diff options
author | Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> | 2016-08-08 18:15:41 +0300 |
---|---|---|
committer | Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> | 2016-08-08 18:15:41 +0300 |
commit | 2836b47370434bc96cc54766c898577421ba14e2 (patch) | |
tree | 3e84b6934995bea8a031d84be5ffdf95fb33b63e /app | |
parent | 71dec8b1b61e9e194d242d37b39416b72020936b (diff) | |
parent | b767d8688511d7fdb9487e96c18eb62788fd629b (diff) | |
download | gitlab-ce-2836b47370434bc96cc54766c898577421ba14e2.tar.gz |
Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ce
Diffstat (limited to 'app')
42 files changed, 538 insertions, 347 deletions
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 127e568adc9..f1aab067351 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -287,7 +287,7 @@ $('.page-with-sidebar').toggleClass('page-sidebar-collapsed page-sidebar-expanded').removeClass('page-sidebar-pinned'); $('.navbar-fixed-top').removeClass('header-pinned-nav'); } - return $document.off('click', '.js-nav-pin').on('click', '.js-nav-pin', function(e) { + $document.off('click', '.js-nav-pin').on('click', '.js-nav-pin', function(e) { var $page, $pinBtn, $tooltip, $topNav, doPinNav, tooltipText; e.preventDefault(); $pinBtn = $(e.currentTarget); @@ -315,6 +315,8 @@ $tooltip.find('.tooltip-inner').text(tooltipText); return $pinBtn.attr('title', tooltipText).tooltip('fixTitle'); }); - }); + // Custom time ago + gl.utils.shortTimeAgo($('.js-short-timeago')); + }); }).call(this); diff --git a/app/assets/javascripts/diff.js b/app/assets/javascripts/diff.js index 298f3852085..3dd7ceba92f 100644 --- a/app/assets/javascripts/diff.js +++ b/app/assets/javascripts/diff.js @@ -10,7 +10,7 @@ $(document).off('click', '.js-unfold'); $(document).on('click', '.js-unfold', (function(_this) { return function(event) { - var line_number, link, offset, old_line, params, prev_new_line, prev_old_line, ref, ref1, since, target, to, unfold, unfoldBottom; + var line_number, link, file, offset, old_line, params, prev_new_line, prev_old_line, ref, ref1, since, target, to, unfold, unfoldBottom; target = $(event.target); unfoldBottom = target.hasClass('js-unfold-bottom'); unfold = true; @@ -31,14 +31,16 @@ unfold = false; } } - link = target.parents('.diff-file').attr('data-blob-diff-path'); + file = target.parents('.diff-file'); + link = file.data('blob-diff-path'); params = { since: since, to: to, bottom: unfoldBottom, offset: offset, unfold: unfold, - indent: 1 + indent: 1, + view: file.data('view') }; return $.get(link, params, function(response) { return target.parent().replaceWith(response); @@ -48,26 +50,13 @@ } Diff.prototype.lineNumbers = function(line) { - var i, l, len, line_number, line_numbers, lines, results; if (!line.children().length) { return [0, 0]; } - lines = line.children().slice(0, 2); - line_numbers = (function() { - var i, len, results; - results = []; - for (i = 0, len = lines.length; i < len; i++) { - l = lines[i]; - results.push($(l).attr('data-linenumber')); - } - return results; - })(); - results = []; - for (i = 0, len = line_numbers.length; i < len; i++) { - line_number = line_numbers[i]; - results.push(parseInt(line_number)); - } - return results; + + return line.find('.diff-line-num').map(function() { + return parseInt($(this).data('linenumber')); + }); }; return Diff; diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js index 9e6901962c6..20f2b1d69b5 100644 --- a/app/assets/javascripts/dispatcher.js +++ b/app/assets/javascripts/dispatcher.js @@ -173,8 +173,8 @@ new Search(); break; case 'projects:protected_branches:index': - new ProtectedBranchesAccessSelect($(".new_protected_branch"), false, true); - new ProtectedBranchesAccessSelect($(".protected-branches-list"), true, false); + new gl.ProtectedBranchCreate(); + new gl.ProtectedBranchEditList(); break; } switch (path.first()) { diff --git a/app/assets/javascripts/gl_dropdown.js b/app/assets/javascripts/gl_dropdown.js index c5d92831fbe..d3394fae3f9 100644 --- a/app/assets/javascripts/gl_dropdown.js +++ b/app/assets/javascripts/gl_dropdown.js @@ -28,38 +28,43 @@ }; })(this)); timeout = ""; - this.input.on("keyup", (function(_this) { - return function(e) { + this.input + .on('keydown', function (e) { + var keyCode = e.which; + + if (keyCode === 13) { + e.preventDefault() + } + }) + .on('keyup', function(e) { var keyCode; keyCode = e.which; if (ARROW_KEY_CODES.indexOf(keyCode) >= 0) { return; } - if (_this.input.val() !== "" && !$inputContainer.hasClass(HAS_VALUE_CLASS)) { + if (this.input.val() !== "" && !$inputContainer.hasClass(HAS_VALUE_CLASS)) { $inputContainer.addClass(HAS_VALUE_CLASS); - } else if (_this.input.val() === "" && $inputContainer.hasClass(HAS_VALUE_CLASS)) { + } else if (this.input.val() === "" && $inputContainer.hasClass(HAS_VALUE_CLASS)) { $inputContainer.removeClass(HAS_VALUE_CLASS); } if (keyCode === 13) { return false; } - if (_this.options.remote) { + if (this.options.remote) { clearTimeout(timeout); return timeout = setTimeout(function() { - var blur_field; - blur_field = _this.shouldBlur(keyCode); - if (blur_field && _this.filterInputBlur) { - _this.input.blur(); + var blurField = this.shouldBlur(keyCode); + if (blurField && this.filterInputBlur) { + this.input.blur(); } - return _this.options.query(_this.input.val(), function(data) { - return _this.options.callback(data); - }); - }, 250); + return this.options.query(this.input.val(), function(data) { + return this.options.callback(data); + }.bind(this)); + }.bind(this), 250); } else { - return _this.filter(_this.input.val()); + return this.filter(this.input.val()); } - }; - })(this)); + }.bind(this)); } GitLabDropdownFilter.prototype.shouldBlur = function(keyCode) { @@ -382,6 +387,7 @@ GitLabDropdown.prototype.opened = function() { var contentHtml; + currentIndex = -1; this.addArrowKeyEvent(); if (this.options.setIndeterminateIds) { this.options.setIndeterminateIds.call(this); @@ -601,7 +607,7 @@ return this.dropdown.before($input); }; - GitLabDropdown.prototype.selectRowAtIndex = function(e, index) { + GitLabDropdown.prototype.selectRowAtIndex = function(index) { var $el, selector; selector = ".dropdown-content li:not(.divider,.dropdown-header,.separator):eq(" + index + ") a"; if (this.dropdown.find(".dropdown-toggle-page").length) { @@ -609,8 +615,6 @@ } $el = $(selector, this.dropdown); if ($el.length) { - e.preventDefault(); - e.stopImmediatePropagation(); return $el.first().trigger('click'); } }; @@ -619,7 +623,7 @@ var $input, ARROW_KEY_CODES, selector; ARROW_KEY_CODES = [38, 40]; $input = this.dropdown.find(".dropdown-input-field"); - selector = '.dropdown-content li:not(.divider,.dropdown-header,.separator)'; + selector = '.dropdown-content li:not(.divider,.dropdown-header,.separator):visible'; if (this.dropdown.find(".dropdown-toggle-page").length) { selector = ".dropdown-page-one " + selector; } @@ -647,7 +651,7 @@ return false; } if (currentKeyCode === 13 && currentIndex !== -1) { - return _this.selectRowAtIndex(e, currentIndex); + return _this.selectRowAtIndex($('.is-focused', _this.dropdown).closest('li').index() - 1); } }; })(this)); diff --git a/app/assets/javascripts/lib/utils/datetime_utility.js b/app/assets/javascripts/lib/utils/datetime_utility.js index e817261f210..10afa7e4329 100644 --- a/app/assets/javascripts/lib/utils/datetime_utility.js +++ b/app/assets/javascripts/lib/utils/datetime_utility.js @@ -8,13 +8,16 @@ base.utils = {}; } w.gl.utils.days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; + w.gl.utils.formatDate = function(datetime) { return dateFormat(datetime, 'mmm d, yyyy h:MMtt Z'); }; + w.gl.utils.getDayName = function(date) { return this.days[date.getDay()]; }; - return w.gl.utils.localTimeAgo = function($timeagoEls, setTimeago) { + + w.gl.utils.localTimeAgo = function($timeagoEls, setTimeago) { if (setTimeago == null) { setTimeago = true; } @@ -31,6 +34,39 @@ }); } }; + + w.gl.utils.shortTimeAgo = function($el) { + var shortLocale, tmpLocale; + shortLocale = { + prefixAgo: null, + prefixFromNow: null, + suffixAgo: 'ago', + suffixFromNow: 'from now', + seconds: '1 min', + minute: '1 min', + minutes: '%d mins', + hour: '1 hr', + hours: '%d hrs', + day: '1 day', + days: '%d days', + month: '1 month', + months: '%d months', + year: '1 year', + years: '%d years', + wordSeparator: ' ', + numbers: [] + }; + tmpLocale = $.timeago.settings.strings; + $el.each(function(el) { + var $el1; + $el1 = $(this); + return $el1.attr('title', gl.utils.formatDate($el.attr('datetime'))); + }); + $.timeago.settings.strings = shortLocale; + $el.timeago(); + $.timeago.settings.strings = tmpLocale; + }; + })(window); }).call(this); diff --git a/app/assets/javascripts/project.js b/app/assets/javascripts/project.js index e6663177161..b97f6d22715 100644 --- a/app/assets/javascripts/project.js +++ b/app/assets/javascripts/project.js @@ -89,8 +89,14 @@ toggleLabel: function(obj, $el) { return $el.text().trim(); }, - clicked: function(e) { - return $dropdown.closest('form').submit(); + clicked: function(selected, $el, e) { + e.preventDefault() + if ($('input[name="ref"]').length) { + var $form = $dropdown.closest('form'), + action = $form.attr('action'), + divider = action.indexOf('?') < 0 ? '?' : '&'; + Turbolinks.visit(action + '' + divider + '' + $form.serialize()); + } } }); }); diff --git a/app/assets/javascripts/protected_branch_access_dropdown.js.es6 b/app/assets/javascripts/protected_branch_access_dropdown.js.es6 new file mode 100644 index 00000000000..2fbb088fa04 --- /dev/null +++ b/app/assets/javascripts/protected_branch_access_dropdown.js.es6 @@ -0,0 +1,24 @@ +(global => { + global.gl = global.gl ||Â {}; + + gl.ProtectedBranchAccessDropdown = class { + constructor(options) { + const { $dropdown, data, onSelect } = options; + + $dropdown.glDropdown({ + data: data, + selectable: true, + inputId: $dropdown.data('input-id'), + fieldName: $dropdown.data('field-name'), + toggleLabel(item) { + return item.text; + }, + clicked(item, $el, e) { + e.preventDefault(); + onSelect(); + } + }); + } + } + +})(window); diff --git a/app/assets/javascripts/protected_branch_create.js.es6 b/app/assets/javascripts/protected_branch_create.js.es6 new file mode 100644 index 00000000000..00e20a03b04 --- /dev/null +++ b/app/assets/javascripts/protected_branch_create.js.es6 @@ -0,0 +1,56 @@ +(global => { + global.gl = global.gl ||Â {}; + + gl.ProtectedBranchCreate = class { + constructor() { + this.$wrap = this.$form = $('#new_protected_branch'); + this.buildDropdowns(); + } + + buildDropdowns() { + const $allowedToMergeDropdown = this.$wrap.find('.js-allowed-to-merge'); + const $allowedToPushDropdown = this.$wrap.find('.js-allowed-to-push'); + + // Cache callback + this.onSelectCallback = this.onSelect.bind(this); + + // Allowed to Merge dropdown + new gl.ProtectedBranchAccessDropdown({ + $dropdown: $allowedToMergeDropdown, + data: gon.merge_access_levels, + onSelect: this.onSelectCallback + }); + + // Allowed to Push dropdown + new gl.ProtectedBranchAccessDropdown({ + $dropdown: $allowedToPushDropdown, + data: gon.push_access_levels, + onSelect: this.onSelectCallback + }); + + // Select default + $allowedToPushDropdown.data('glDropdown').selectRowAtIndex(0); + $allowedToMergeDropdown.data('glDropdown').selectRowAtIndex(0); + + // Protected branch dropdown + new ProtectedBranchDropdown({ + $dropdown: this.$wrap.find('.js-protected-branch-select'), + onSelect: this.onSelectCallback + }); + } + + // This will run after clicked callback + onSelect() { + + // Enable submit button + const $branchInput = this.$wrap.find('input[name="protected_branch[name]"]'); + const $allowedToMergeInput = this.$wrap.find('input[name="protected_branch[merge_access_level_attributes][access_level]"]'); + const $allowedToPushInput = this.$wrap.find('input[name="protected_branch[push_access_level_attributes][access_level]"]'); + + if ($branchInput.val() && $allowedToMergeInput.val() && $allowedToPushInput.val()){ + this.$form.find('input[type="submit"]').removeAttr('disabled'); + } + } + } + +})(window); diff --git a/app/assets/javascripts/protected_branch_dropdown.js.es6 b/app/assets/javascripts/protected_branch_dropdown.js.es6 new file mode 100644 index 00000000000..6738dc8862d --- /dev/null +++ b/app/assets/javascripts/protected_branch_dropdown.js.es6 @@ -0,0 +1,75 @@ +class ProtectedBranchDropdown { + constructor(options) { + this.onSelect = options.onSelect; + this.$dropdown = options.$dropdown; + this.$dropdownContainer = this.$dropdown.parent(); + this.$dropdownFooter = this.$dropdownContainer.find('.dropdown-footer'); + this.$protectedBranch = this.$dropdownContainer.find('.create-new-protected-branch'); + + this.buildDropdown(); + this.bindEvents(); + + // Hide footer + this.$dropdownFooter.addClass('hidden'); + } + + buildDropdown() { + this.$dropdown.glDropdown({ + data: this.getProtectedBranches.bind(this), + filterable: true, + remote: false, + search: { + fields: ['title'] + }, + selectable: true, + toggleLabel(selected) { + return (selected && 'id' in selected) ? selected.title : 'Protected Branch'; + }, + fieldName: 'protected_branch[name]', + text(protectedBranch) { + return _.escape(protectedBranch.title); + }, + id(protectedBranch) { + return _.escape(protectedBranch.id); + }, + onFilter: this.toggleCreateNewButton.bind(this), + clicked: (item, $el, e) => { + e.preventDefault(); + this.onSelect(); + } + }); + } + + bindEvents() { + this.$protectedBranch.on('click', this.onClickCreateWildcard.bind(this)); + } + + onClickCreateWildcard() { + this.$dropdown.data('glDropdown').remote.execute(); + this.$dropdown.data('glDropdown').selectRowAtIndex(0); + } + + getProtectedBranches(term, callback) { + if (this.selectedBranch) { + callback(gon.open_branches.concat(this.selectedBranch)); + } else { + callback(gon.open_branches); + } + } + + toggleCreateNewButton(branchName) { + this.selectedBranch = { + title: branchName, + id: branchName, + text: branchName + }; + + if (branchName) { + this.$dropdownContainer + .find('.create-new-protected-branch code') + .text(branchName); + } + + this.$dropdownFooter.toggleClass('hidden', !branchName); + } +} diff --git a/app/assets/javascripts/protected_branch_edit.js.es6 b/app/assets/javascripts/protected_branch_edit.js.es6 new file mode 100644 index 00000000000..8d42e268ebc --- /dev/null +++ b/app/assets/javascripts/protected_branch_edit.js.es6 @@ -0,0 +1,61 @@ +(global => { + global.gl = global.gl ||Â {}; + + gl.ProtectedBranchEdit = class { + constructor(options) { + this.$wrap = options.$wrap; + this.$allowedToMergeDropdown = this.$wrap.find('.js-allowed-to-merge'); + this.$allowedToPushDropdown = this.$wrap.find('.js-allowed-to-push'); + + this.buildDropdowns(); + } + + buildDropdowns() { + + // Allowed to merge dropdown + new gl.ProtectedBranchAccessDropdown({ + $dropdown: this.$allowedToMergeDropdown, + data: gon.merge_access_levels, + onSelect: this.onSelect.bind(this) + }); + + // Allowed to push dropdown + new gl.ProtectedBranchAccessDropdown({ + $dropdown: this.$allowedToPushDropdown, + data: gon.push_access_levels, + onSelect: this.onSelect.bind(this) + }); + } + + onSelect() { + const $allowedToMergeInput = this.$wrap.find(`input[name="${this.$allowedToMergeDropdown.data('fieldName')}"]`); + const $allowedToPushInput = this.$wrap.find(`input[name="${this.$allowedToPushDropdown.data('fieldName')}"]`); + + $.ajax({ + type: 'POST', + url: this.$wrap.data('url'), + dataType: 'json', + data: { + _method: 'PATCH', + id: this.$wrap.data('banchId'), + protected_branch: { + merge_access_level_attributes: { + access_level: $allowedToMergeInput.val() + }, + push_access_level_attributes: { + access_level: $allowedToPushInput.val() + } + } + }, + success: () => { + this.$wrap.effect('highlight'); + }, + error() { + $.scrollTo(0); + new Flash('Failed to update branch!'); + } + }); + } + } + +})(window); diff --git a/app/assets/javascripts/protected_branch_edit_list.js.es6 b/app/assets/javascripts/protected_branch_edit_list.js.es6 new file mode 100644 index 00000000000..9ff0fd12c76 --- /dev/null +++ b/app/assets/javascripts/protected_branch_edit_list.js.es6 @@ -0,0 +1,17 @@ +(global => { + global.gl = global.gl ||Â {}; + + gl.ProtectedBranchEditList = class { + constructor()Â { + this.$wrap = $('.protected-branches-list'); + + // Build edit forms + this.$wrap.find('.js-protected-branch-edit-form').each((i, el) => { + new gl.ProtectedBranchEdit({ + $wrap: $(el) + }); + }); + } + } + +})(window); diff --git a/app/assets/javascripts/protected_branch_select.js b/app/assets/javascripts/protected_branch_select.js deleted file mode 100644 index 3a47fc972dc..00000000000 --- a/app/assets/javascripts/protected_branch_select.js +++ /dev/null @@ -1,72 +0,0 @@ -(function() { - var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; - - this.ProtectedBranchSelect = (function() { - function ProtectedBranchSelect(currentProject) { - this.toggleCreateNewButton = bind(this.toggleCreateNewButton, this); - this.getProtectedBranches = bind(this.getProtectedBranches, this); - $('.dropdown-footer').hide(); - this.dropdown = $('.js-protected-branch-select').glDropdown({ - data: this.getProtectedBranches, - filterable: true, - remote: false, - search: { - fields: ['title'] - }, - selectable: true, - toggleLabel: function(selected) { - if (selected && 'id' in selected) { - return selected.title; - } else { - return 'Protected Branch'; - } - }, - fieldName: 'protected_branch[name]', - text: function(protected_branch) { - return _.escape(protected_branch.title); - }, - id: function(protected_branch) { - return _.escape(protected_branch.id); - }, - onFilter: this.toggleCreateNewButton, - clicked: function() { - return $('.protect-branch-btn').attr('disabled', false); - } - }); - $('.create-new-protected-branch').on('click', (function(_this) { - return function(event) { - _this.dropdown.data('glDropdown').remote.execute(); - return _this.dropdown.data('glDropdown').selectRowAtIndex(event, 0); - }; - })(this)); - } - - ProtectedBranchSelect.prototype.getProtectedBranches = function(term, callback) { - if (this.selectedBranch) { - return callback(gon.open_branches.concat(this.selectedBranch)); - } else { - return callback(gon.open_branches); - } - }; - - ProtectedBranchSelect.prototype.toggleCreateNewButton = function(branchName) { - this.selectedBranch = { - title: branchName, - id: branchName, - text: branchName - }; - if (branchName === '') { - $('.protected-branch-select-footer-list').addClass('hidden'); - return $('.dropdown-footer').hide(); - } else { - $('.create-new-protected-branch').text("Create Protected Branch: " + branchName); - $('.protected-branch-select-footer-list').removeClass('hidden'); - return $('.dropdown-footer').show(); - } - }; - - return ProtectedBranchSelect; - - })(); - -}).call(this); diff --git a/app/assets/javascripts/protected_branches_access_select.js.es6 b/app/assets/javascripts/protected_branches_access_select.js.es6 deleted file mode 100644 index e98312bbf37..00000000000 --- a/app/assets/javascripts/protected_branches_access_select.js.es6 +++ /dev/null @@ -1,63 +0,0 @@ -class ProtectedBranchesAccessSelect { - constructor(container, saveOnSelect, selectDefault) { - this.container = container; - this.saveOnSelect = saveOnSelect; - - this.container.find(".allowed-to-merge").each((i, element) => { - var fieldName = $(element).data('field-name'); - var dropdown = $(element).glDropdown({ - data: gon.merge_access_levels, - selectable: true, - fieldName: fieldName, - clicked: _.chain(this.onSelect).partial(element).bind(this).value() - }); - - if (selectDefault) { - dropdown.data('glDropdown').selectRowAtIndex(document.createEvent("Event"), 0); - } - }); - - - this.container.find(".allowed-to-push").each((i, element) => { - var fieldName = $(element).data('field-name'); - var dropdown = $(element).glDropdown({ - data: gon.push_access_levels, - selectable: true, - fieldName: fieldName, - clicked: _.chain(this.onSelect).partial(element).bind(this).value() - }); - - if (selectDefault) { - dropdown.data('glDropdown').selectRowAtIndex(document.createEvent("Event"), 0); - } - }); - } - - onSelect(dropdown, selected, element, e) { - $(dropdown).find('.dropdown-toggle-text').text(selected.text); - if (this.saveOnSelect) { - return $.ajax({ - type: "POST", - url: $(dropdown).data('url'), - dataType: "json", - data: { - _method: 'PATCH', - id: $(dropdown).data('id'), - protected_branch: { - ["" + ($(dropdown).data('type')) + "_attributes"]: { - "access_level": selected.id - } - } - }, - success: function() { - var row; - row = $(e.target); - return row.closest('tr').effect('highlight'); - }, - error: function() { - return new Flash("Failed to update branch!", "alert"); - } - }); - } - } -} diff --git a/app/assets/javascripts/users_select.js b/app/assets/javascripts/users_select.js index 4af2a214e12..65d362e072c 100644 --- a/app/assets/javascripts/users_select.js +++ b/app/assets/javascripts/users_select.js @@ -13,14 +13,15 @@ } $('.js-user-search').each((function(_this) { return function(i, dropdown) { + var options = {}; var $block, $collapsedSidebar, $dropdown, $loading, $selectbox, $value, abilityName, assignTo, assigneeTemplate, collapsedAssigneeTemplate, defaultLabel, firstUser, issueURL, selectedId, showAnyUser, showNullUser; $dropdown = $(dropdown); - _this.projectId = $dropdown.data('project-id'); - _this.showCurrentUser = $dropdown.data('current-user'); + options.projectId = $dropdown.data('project-id'); + options.showCurrentUser = $dropdown.data('current-user'); showNullUser = $dropdown.data('null-user'); showAnyUser = $dropdown.data('any-user'); firstUser = $dropdown.data('first-user'); - _this.authorId = $dropdown.data('author-id'); + options.authorId = $dropdown.data('author-id'); selectedId = $dropdown.data('selected'); defaultLabel = $dropdown.data('default-label'); issueURL = $dropdown.data('issueUpdate'); @@ -75,7 +76,7 @@ data: function(term, callback) { var isAuthorFilter; isAuthorFilter = $('.js-author-search'); - return _this.users(term, function(users) { + return _this.users(term, options, function(users) { var anyUser, index, j, len, name, obj, showDivider; if (term.length === 0) { showDivider = 0; @@ -185,11 +186,14 @@ $('.ajax-users-select').each((function(_this) { return function(i, select) { var firstUser, showAnyUser, showEmailUser, showNullUser; - _this.projectId = $(select).data('project-id'); - _this.groupId = $(select).data('group-id'); - _this.showCurrentUser = $(select).data('current-user'); - _this.authorId = $(select).data('author-id'); - _this.skipUsers = $(select).data('skip-users'); + var options = {}; + options.skipLdap = $(select).hasClass('skip_ldap'); + options.projectId = $(select).data('project-id'); + options.groupId = $(select).data('group-id'); + options.showCurrentUser = $(select).data('current-user'); + options.pushCodeToProtectedBranches = $(select).data('push-code-to-protected-branches'); + options.authorId = $(select).data('author-id'); + options.skipUsers = $(select).data('skip-users'); showNullUser = $(select).data('null-user'); showAnyUser = $(select).data('any-user'); showEmailUser = $(select).data('email-user'); @@ -199,7 +203,7 @@ multiple: $(select).hasClass('multiselect'), minimumInputLength: 0, query: function(query) { - return _this.users(query.term, function(users) { + return _this.users(query.term, options, function(users) { var anyUser, data, emailUser, index, j, len, name, nullUser, obj, ref; data = { results: users @@ -309,7 +313,7 @@ }); }; - UsersSelect.prototype.users = function(query, callback) { + UsersSelect.prototype.users = function(query, options, callback) { var url; url = this.buildUrl(this.usersPath); return $.ajax({ @@ -318,11 +322,13 @@ search: query, per_page: 20, active: true, - project_id: this.projectId, - group_id: this.groupId, - current_user: this.showCurrentUser, - author_id: this.authorId, - skip_users: this.skipUsers + project_id: options.projectId || null, + group_id: options.groupId || null, + skip_ldap: options.skipLdap || null, + current_user: options.showCurrentUser || null, + push_code_to_protected_branches: options.pushCodeToProtectedBranches || null, + author_id: options.authorId || null, + skip_users: options.skipUsers || null }, dataType: "json" }).done(function(users) { diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss index c54eb0d6479..e8eafa15899 100644 --- a/app/assets/stylesheets/framework/dropdowns.scss +++ b/app/assets/stylesheets/framework/dropdowns.scss @@ -72,6 +72,14 @@ &.large { width: 200px; } + + &.wide { + width: 100%; + + + .dropdown-select { + width: 100%; + } + } } .dropdown-menu, diff --git a/app/assets/stylesheets/framework/lists.scss b/app/assets/stylesheets/framework/lists.scss index 2c40ec430ca..965fcc06518 100644 --- a/app/assets/stylesheets/framework/lists.scss +++ b/app/assets/stylesheets/framework/lists.scss @@ -114,6 +114,12 @@ ul.content-list { font-size: $list-font-size; color: $list-text-color; + &.no-description { + .title { + line-height: $list-text-height; + } + } + .title { font-weight: 600; } @@ -134,12 +140,11 @@ ul.content-list { } .controls { - padding-top: 1px; float: right; > .control-text { margin-right: $gl-padding-top; - line-height: 40px; + line-height: $list-text-height; &:last-child { margin-right: 0; @@ -150,7 +155,7 @@ ul.content-list { > .btn-group { margin-right: $gl-padding-top; display: inline-block; - margin-top: 4px; + margin-top: 3px; margin-bottom: 4px; &:last-child { diff --git a/app/assets/stylesheets/framework/panels.scss b/app/assets/stylesheets/framework/panels.scss index 874416e1007..c6f30e144fd 100644 --- a/app/assets/stylesheets/framework/panels.scss +++ b/app/assets/stylesheets/framework/panels.scss @@ -23,4 +23,9 @@ margin-top: $gl-padding; } } + + .panel-title { + font-size: inherit; + line-height: inherit; + } } diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss index 1882d4e888d..ca720022539 100644 --- a/app/assets/stylesheets/framework/variables.scss +++ b/app/assets/stylesheets/framework/variables.scss @@ -43,6 +43,7 @@ $gl-header-color: $gl-title-color; $list-font-size: $gl-font-size; $list-title-color: $gl-title-color; $list-text-color: $gl-text-color; +$list-text-height: 42px; /* * Markdown diff --git a/app/assets/stylesheets/pages/groups.scss b/app/assets/stylesheets/pages/groups.scss index 2a3acc3eb4c..b657ca47d38 100644 --- a/app/assets/stylesheets/pages/groups.scss +++ b/app/assets/stylesheets/pages/groups.scss @@ -23,15 +23,9 @@ } .group-row { - &.no-description { - .group-name { - line-height: 44px; - } - } - .stats { float: right; - line-height: 44px; + line-height: $list-text-height; color: $gl-gray; span { diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss index 4409477916f..cf9aa02600d 100644 --- a/app/assets/stylesheets/pages/projects.scss +++ b/app/assets/stylesheets/pages/projects.scss @@ -512,18 +512,12 @@ pre.light-well { .project-row { border-color: $table-border-color; - &.no-description { - .project { - line-height: 40px; - } - } - .project-full-name { @include str-truncated; } .controls { - line-height: 40px; + line-height: $list-text-height; a:hover { text-decoration: none; @@ -662,13 +656,9 @@ pre.light-well { } .new_protected_branch { - .dropdown { - display: inline; - margin-left: 15px; - } - label { - min-width: 120px; + margin-top: 6px; + font-weight: normal; } } @@ -684,6 +674,21 @@ pre.light-well { font-weight: 600; } } + + .settings-message { + margin: 0; + border-radius: 0 0 1px 1px; + padding: 20px 0; + border: none; + } + + .table-bordered { + border-radius: 1px; + + th:not(:last-child), td:not(:last-child) { + border-right: solid 1px transparent; + } + } } .custom-notifications-form { diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb index eda3727a28d..19d051720e9 100644 --- a/app/controllers/projects/blob_controller.rb +++ b/app/controllers/projects/blob_controller.rb @@ -76,6 +76,8 @@ class Projects::BlobController < Projects::ApplicationController end def diff + apply_diff_view_cookie! + @form = UnfoldForm.new(params) @lines = Gitlab::Highlight.highlight_lines(repository, @ref, @path) @lines = @lines[@form.since - 1..@form.to - 1] diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 50de93d4bdf..c3613bc67dd 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -163,9 +163,13 @@ module ApplicationHelper # `html_class` argument is provided. # # Returns an HTML-safe String - def time_ago_with_tooltip(time, placement: 'top', html_class: 'time_ago', skip_js: false) + def time_ago_with_tooltip(time, placement: 'top', html_class: '', skip_js: false, short_format: false) + css_classes = short_format ? 'js-short-timeago' : 'js-timeago' + css_classes << " #{html_class}" unless html_class.blank? + css_classes << ' js-timeago-pending' unless skip_js + element = content_tag :time, time.to_s, - class: "#{html_class} js-timeago #{"js-timeago-pending" unless skip_js}", + class: css_classes, datetime: time.to_time.getutc.iso8601, title: time.to_time.in_time_zone.to_s(:medium), data: { toggle: 'tooltip', placement: placement, container: 'body' } diff --git a/app/helpers/diff_helper.rb b/app/helpers/diff_helper.rb index cc7121b1163..f3c9ea074b4 100644 --- a/app/helpers/diff_helper.rb +++ b/app/helpers/diff_helper.rb @@ -13,12 +13,11 @@ module DiffHelper end def diff_view - diff_views = %w(inline parallel) - - if diff_views.include?(cookies[:diff_view]) - cookies[:diff_view] - else - diff_views.first + @diff_view ||= begin + diff_views = %w(inline parallel) + diff_view = cookies[:diff_view] + diff_view = diff_views.first unless diff_views.include?(diff_view) + diff_view.to_sym end end @@ -33,12 +32,23 @@ module DiffHelper options end - def unfold_bottom_class(bottom) - bottom ? 'js-unfold js-unfold-bottom' : '' - end + def diff_match_line(old_pos, new_pos, text: '', view: :inline, bottom: false) + content = content_tag :td, text, class: "line_content match #{view == :inline ? '' : view}" + cls = ['diff-line-num', 'unfold', 'js-unfold'] + cls << 'js-unfold-bottom' if bottom + + html = '' + if old_pos + html << content_tag(:td, '...', class: cls + ['old_line'], data: { linenumber: old_pos }) + html << content unless view == :inline + end + + if new_pos + html << content_tag(:td, '...', class: cls + ['new_line'], data: { linenumber: new_pos }) + html << content + end - def unfold_class(unfold) - unfold ? 'unfold js-unfold' : '' + html.html_safe end def diff_line_content(line, line_type = nil) @@ -67,11 +77,11 @@ module DiffHelper end def inline_diff_btn - diff_btn('Inline', 'inline', diff_view == 'inline') + diff_btn('Inline', 'inline', diff_view == :inline) end def parallel_diff_btn - diff_btn('Side-by-side', 'parallel', diff_view == 'parallel') + diff_btn('Side-by-side', 'parallel', diff_view == :parallel) end def submodule_link(blob, ref, repository = @repository) @@ -103,7 +113,8 @@ module DiffHelper commit = commit_for_diff(diff_file) { blob_diff_path: namespace_project_blob_diff_path(project.namespace, project, - tree_join(commit.id, diff_file.file_path)) + tree_join(commit.id, diff_file.file_path)), + view: diff_view } end diff --git a/app/models/ability.rb b/app/models/ability.rb index d95a2507199..d9113ffd99a 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -6,6 +6,10 @@ class Ability return [] unless user.is_a?(User) return [] if user.blocked? + abilities_by_subject_class(user: user, subject: subject) + end + + def abilities_by_subject_class(user:, subject:) case subject when CommitStatus then commit_status_abilities(user, subject) when Project then project_abilities(user, subject) diff --git a/app/views/admin/application_settings/_form.html.haml b/app/views/admin/application_settings/_form.html.haml index 23b52d08df7..23f864df147 100644 --- a/app/views/admin/application_settings/_form.html.haml +++ b/app/views/admin/application_settings/_form.html.haml @@ -228,6 +228,9 @@ = f.label :max_artifacts_size, 'Maximum artifacts size (MB)', class: 'control-label col-sm-2' .col-sm-10 = f.number_field :max_artifacts_size, class: 'form-control' + .help-block + Set the maximum file size each build's artifacts can have + = link_to "(?)", help_page_path("user/admin_area/settings/continuous_integration", anchor: "maximum-artifacts-size") - if Gitlab.config.registry.enabled %fieldset @@ -385,4 +388,4 @@ .form-actions - = f.submit 'Save', class: 'btn btn-save'
\ No newline at end of file + = f.submit 'Save', class: 'btn btn-save' diff --git a/app/views/notify/new_issue_email.text.erb b/app/views/notify/new_issue_email.text.erb index fc64c98038b..ca5c2f2688c 100644 --- a/app/views/notify/new_issue_email.text.erb +++ b/app/views/notify/new_issue_email.text.erb @@ -3,3 +3,5 @@ New Issue was created. Issue <%= @issue.iid %>: <%= url_for(namespace_project_issue_url(@issue.project.namespace, @issue.project, @issue)) %> Author: <%= @issue.author_name %> Assignee: <%= @issue.assignee_name %> + +<%= @issue.description %> diff --git a/app/views/notify/new_merge_request_email.text.erb b/app/views/notify/new_merge_request_email.text.erb index d4aad8d1862..3c8f178ac77 100644 --- a/app/views/notify/new_merge_request_email.text.erb +++ b/app/views/notify/new_merge_request_email.text.erb @@ -6,3 +6,5 @@ New Merge Request <%= @merge_request.to_reference %> Author: <%= @merge_request.author_name %> Assignee: <%= @merge_request.assignee_name %> +<%= @merge_request.description %> + diff --git a/app/views/projects/blob/diff.html.haml b/app/views/projects/blob/diff.html.haml index 5926d181ba3..a79ae53c780 100644 --- a/app/views/projects/blob/diff.html.haml +++ b/app/views/projects/blob/diff.html.haml @@ -1,20 +1,30 @@ - if @lines.present? + - line_class = diff_view == :inline ? '' : diff_view - if @form.unfold? && @form.since != 1 && !@form.bottom? - %tr.line_holder - = render "projects/diffs/match_line", { line: @match_line, - line_old: @form.since, line_new: @form.since, bottom: false, new_file: false } + %tr.line_holder{ class: line_class } + = diff_match_line @form.since, @form.since, text: @match_line, view: diff_view - @lines.each_with_index do |line, index| - line_new = index + @form.since - line_old = line_new - @form.offset - %tr.line_holder{ id: line_old } - %td.old_line.diff-line-num{ data: { linenumber: line_old } } - = link_to raw(line_old), "##{line_old}" - %td.new_line.diff-line-num{ data: { linenumber: line_old } } - = link_to raw(line_new) , "##{line_old}" - %td.line_content.noteable_line==#{' ' * @form.indent}#{line} + - line_content = capture do + %td.line_content.noteable_line{ class: line_class }==#{' ' * @form.indent}#{line} + %tr.line_holder{ id: line_old, class: line_class } + - case diff_view + - when :inline + %td.old_line.diff-line-num{ data: { linenumber: line_old } } + %a{href: "##{line_old}", data: { linenumber: line_old }} + %td.new_line.diff-line-num{ data: { linenumber: line_new } } + %a{href: "##{line_new}", data: { linenumber: line_new }} + = line_content + - when :parallel + %td.old_line.diff-line-num{data: { linenumber: line_old }} + = link_to raw(line_old), "##{line_old}" + = line_content + %td.new_line.diff-line-num{data: { linenumber: line_new }} + = link_to raw(line_new), "##{line_new}" + = line_content - if @form.unfold? && @form.bottom? && @form.to < @blob.loc - %tr.line_holder{ id: @form.to } - = render "projects/diffs/match_line", { line: @match_line, - line_old: @form.to, line_new: @form.to, bottom: true, new_file: false } + %tr.line_holder{ id: @form.to, class: line_class } + = diff_match_line @form.to, @form.to, text: @match_line, view: diff_view, bottom: true diff --git a/app/views/projects/ci/pipelines/_pipeline.html.haml b/app/views/projects/ci/pipelines/_pipeline.html.haml index 558c35553da..9a594877803 100644 --- a/app/views/projects/ci/pipelines/_pipeline.html.haml +++ b/app/views/projects/ci/pipelines/_pipeline.html.haml @@ -53,7 +53,7 @@ - if pipeline.finished_at %p.finished-at = icon("calendar") - #{time_ago_with_tooltip(pipeline.finished_at)} + #{time_ago_with_tooltip(pipeline.finished_at, short_format: true, skip_js: true)} %td.pipeline-actions .controls.hidden-xs.pull-right diff --git a/app/views/projects/diffs/_content.html.haml b/app/views/projects/diffs/_content.html.haml index a1b071f130c..d37961c4e40 100644 --- a/app/views/projects/diffs/_content.html.haml +++ b/app/views/projects/diffs/_content.html.haml @@ -13,7 +13,7 @@ .nothing-here-block.diff-collapsed{data: { diff_for_path: url } } This diff is collapsed. Click to expand it. - elsif diff_file.diff_lines.length > 0 - - if diff_view == 'parallel' + - if diff_view == :parallel = render "projects/diffs/parallel_view", diff_file: diff_file, project: project, blob: blob - else = render "projects/diffs/text_file", diff_file: diff_file diff --git a/app/views/projects/diffs/_diffs.html.haml b/app/views/projects/diffs/_diffs.html.haml index ebaf939f930..62aff36aadd 100644 --- a/app/views/projects/diffs/_diffs.html.haml +++ b/app/views/projects/diffs/_diffs.html.haml @@ -1,6 +1,6 @@ - show_whitespace_toggle = local_assigns.fetch(:show_whitespace_toggle, true) - diff_files = diffs.diff_files -- if diff_view == 'parallel' +- if diff_view == :parallel - fluid_layout true .content-block.oneline-block.files-changed diff --git a/app/views/projects/diffs/_line.html.haml b/app/views/projects/diffs/_line.html.haml index 4d3af905b58..2d6a370b848 100644 --- a/app/views/projects/diffs/_line.html.haml +++ b/app/views/projects/diffs/_line.html.haml @@ -4,8 +4,7 @@ %tr.line_holder{ plain ? { class: type} : { class: type, id: line_code } } - case type - when 'match' - = render "projects/diffs/match_line", { line: line.text, - line_old: line.old_pos, line_new: line.new_pos, bottom: false, new_file: diff_file.new_file } + = diff_match_line line.old_pos, line.new_pos, text: line.text - when 'nonewline' %td.old_line.diff-line-num %td.new_line.diff-line-num diff --git a/app/views/projects/diffs/_match_line.html.haml b/app/views/projects/diffs/_match_line.html.haml deleted file mode 100644 index d6dddd97879..00000000000 --- a/app/views/projects/diffs/_match_line.html.haml +++ /dev/null @@ -1,7 +0,0 @@ -%td.old_line.diff-line-num{data: {linenumber: line_old}, - class: [unfold_bottom_class(bottom), unfold_class(!new_file)]} - \... -%td.new_line.diff-line-num{data: {linenumber: line_new}, - class: [unfold_bottom_class(bottom), unfold_class(!new_file)]} - \... -%td.line_content.match= line diff --git a/app/views/projects/diffs/_parallel_view.html.haml b/app/views/projects/diffs/_parallel_view.html.haml index 7f30faa20d8..28aad3f4725 100644 --- a/app/views/projects/diffs/_parallel_view.html.haml +++ b/app/views/projects/diffs/_parallel_view.html.haml @@ -1,14 +1,15 @@ / Side-by-side diff view %div.text-file.diff-wrap-lines.code.file-content.js-syntax-highlight{ data: diff_view_data } %table + - last_line = 0 - diff_file.parallel_diff_lines.each do |line| - left = line[:left] - right = line[:right] + - last_line = right.new_pos if right %tr.line_holder.parallel - if left - if left.meta? - %td.old_line.diff-line-num.empty-cell - %td.line_content.parallel.match= left.text + = diff_match_line left.old_pos, nil, text: left.text, view: :parallel - else - left_line_code = diff_file.line_code(left) - left_position = diff_file.position(left) @@ -21,8 +22,7 @@ - if right - if right.meta? - %td.old_line.diff-line-num.empty-cell - %td.line_content.parallel.match= left.text + = diff_match_line nil, right.new_pos, text: left.text, view: :parallel - else - right_line_code = diff_file.line_code(right) - right_position = diff_file.position(right) @@ -37,3 +37,5 @@ - discussion_left, discussion_right = parallel_diff_discussions(left, right, diff_file) - if discussion_left || discussion_right = render "discussions/parallel_diff_discussion", discussion_left: discussion_left, discussion_right: discussion_right + - if !diff_file.new_file && last_line > 0 + = diff_match_line last_line, last_line, bottom: true, view: :parallel diff --git a/app/views/projects/diffs/_text_file.html.haml b/app/views/projects/diffs/_text_file.html.haml index 5970b9abf2b..ab5463ba89d 100644 --- a/app/views/projects/diffs/_text_file.html.haml +++ b/app/views/projects/diffs/_text_file.html.haml @@ -15,6 +15,5 @@ - if discussion = render "discussions/diff_discussion", discussion: discussion - - if last_line > 0 - = render "projects/diffs/match_line", { line: "", - line_old: last_line, line_new: last_line, bottom: true, new_file: diff_file.new_file } + - if !diff_file.new_file && last_line > 0 + = diff_match_line last_line, last_line, bottom: true diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml index 873ed9b59ee..269198adf91 100644 --- a/app/views/projects/merge_requests/_show.html.haml +++ b/app/views/projects/merge_requests/_show.html.haml @@ -2,7 +2,7 @@ - page_description @merge_request.description - page_card_attributes @merge_request.card_attributes -- if diff_view == 'parallel' +- if diff_view == :parallel - fluid_layout true .merge-request{'data-url' => merge_request_path(@merge_request)} diff --git a/app/views/projects/protected_branches/_branches_list.html.haml b/app/views/projects/protected_branches/_branches_list.html.haml index 0603a014008..04b19a8c5a7 100644 --- a/app/views/projects/protected_branches/_branches_list.html.haml +++ b/app/views/projects/protected_branches/_branches_list.html.haml @@ -1,26 +1,28 @@ -%h5.prepend-top-0 - Already Protected (#{@protected_branches.size}) -- if @protected_branches.empty? - %p.settings-message.text-center - No branches are protected, protect a branch with the form above. -- else - - can_admin_project = can?(current_user, :admin_project, @project) +.panel.panel-default.protected-branches-list + - if @protected_branches.empty? + .panel-heading + %h3.panel-title + Protected branch (#{@protected_branches.size}) + %p.settings-message.text-center + There are currently no protected branches, protect a branch with the form above. + - else + - can_admin_project = can?(current_user, :admin_project, @project) - %table.table.protected-branches-list - %colgroup - %col{ width: "20%" } - %col{ width: "30%" } - %col{ width: "25%" } - %col{ width: "25%" } - %thead - %tr - %th Branch - %th Last commit - %th Allowed to merge - %th Allowed to push - - if can_admin_project - %th - %tbody - = render partial: @protected_branches, locals: { can_admin_project: can_admin_project } + %table.table.table-bordered + %colgroup + %col{ width: "25%" } + %col{ width: "30%" } + %col{ width: "25%" } + %col{ width: "20%" } + %thead + %tr + %th Protected branch (#{@protected_branches.size}) + %th Last commit + %th Allowed to merge + %th Allowed to push + - if can_admin_project + %th + %tbody + = render partial: @protected_branches, locals: { can_admin_project: can_admin_project } - = paginate @protected_branches, theme: 'gitlab' + = paginate @protected_branches, theme: 'gitlab' diff --git a/app/views/projects/protected_branches/_create_protected_branch.html.haml b/app/views/projects/protected_branches/_create_protected_branch.html.haml new file mode 100644 index 00000000000..85d0c494ba8 --- /dev/null +++ b/app/views/projects/protected_branches/_create_protected_branch.html.haml @@ -0,0 +1,36 @@ += form_for [@project.namespace.becomes(Namespace), @project, @protected_branch] do |f| + .panel.panel-default + .panel-heading + %h3.panel-title + Protect a branch + .panel-body + .form-horizontal + .form-group + = f.label :name, class: 'col-md-2 text-right' do + Branch: + .col-md-10 + = render partial: "dropdown", locals: { f: f } + .help-block + = link_to 'Wildcards', help_page_path('user/project/protected_branches', anchor: 'wildcard-protected-branches') + such as + %code *-stable + or + %code production/* + are supported + .form-group + %label.col-md-2.text-right{ for: 'merge_access_level_attributes' } + Allowed to merge: + .col-md-10 + = dropdown_tag('Select', + options: { toggle_class: 'js-allowed-to-merge wide', + data: { field_name: 'protected_branch[merge_access_level_attributes][access_level]', input_id: 'merge_access_level_attributes' }}) + .form-group + %label.col-md-2.text-right{ for: 'push_access_level_attributes' } + Allowed to push: + .col-md-10 + = dropdown_tag('Select', + options: { toggle_class: 'js-allowed-to-push wide', + data: { field_name: 'protected_branch[push_access_level_attributes][access_level]', input_id: 'push_access_level_attributes' }}) + + .panel-footer + = f.submit 'Protect', class: 'btn-create btn', disabled: true diff --git a/app/views/projects/protected_branches/_dropdown.html.haml b/app/views/projects/protected_branches/_dropdown.html.haml index b803d932e67..a9e27df5a87 100644 --- a/app/views/projects/protected_branches/_dropdown.html.haml +++ b/app/views/projects/protected_branches/_dropdown.html.haml @@ -1,17 +1,15 @@ = f.hidden_field(:name) -= dropdown_tag("Protected Branch", - options: { title: "Pick protected branch", toggle_class: 'js-protected-branch-select js-filter-submit', += dropdown_tag('Select branch or create wildcard', + options: { toggle_class: 'js-protected-branch-select js-filter-submit wide', filter: true, dropdown_class: "dropdown-menu-selectable", placeholder: "Search protected branches", footer_content: true, data: { show_no: true, show_any: true, show_upcoming: true, selected: params[:protected_branch_name], project_id: @project.try(:id) } }) do - %ul.dropdown-footer-list.hidden.protected-branch-select-footer-list + %ul.dropdown-footer-list %li = link_to '#', title: "New Protected Branch", class: "create-new-protected-branch" do - Create new - -:javascript - new ProtectedBranchSelect(); + Create wildcard + %code diff --git a/app/views/projects/protected_branches/_protected_branch.html.haml b/app/views/projects/protected_branches/_protected_branch.html.haml index 498e412235e..e2e01ee78f8 100644 --- a/app/views/projects/protected_branches/_protected_branch.html.haml +++ b/app/views/projects/protected_branches/_protected_branch.html.haml @@ -1,5 +1,4 @@ -- url = namespace_project_protected_branch_path(@project.namespace, @project, protected_branch) -%tr +%tr.js-protected-branch-edit-form{ data: { url: namespace_project_protected_branch_path(@project.namespace, @project, protected_branch), branch_id: protected_branch.id } } %td = protected_branch.name - if @project.root_ref?(protected_branch.name) @@ -16,14 +15,14 @@ (branch was removed from repository) %td = hidden_field_tag "allowed_to_merge_#{protected_branch.id}", protected_branch.merge_access_level.access_level - = dropdown_tag(protected_branch.merge_access_level.humanize, - options: { title: "Allowed to merge", toggle_class: 'allowed-to-merge', dropdown_class: 'dropdown-menu-selectable merge', - data: { field_name: "allowed_to_merge_#{protected_branch.id}", url: url, id: protected_branch.id, type: "merge_access_level" }}) + = dropdown_tag( (protected_branch.merge_access_level.humanize || 'Select') , + options: { toggle_class: 'js-allowed-to-merge', dropdown_class: 'dropdown-menu-selectable js-allowed-to-merge-container', + data: { field_name: "allowed_to_merge_#{protected_branch.id}" }}) %td = hidden_field_tag "allowed_to_push_#{protected_branch.id}", protected_branch.push_access_level.access_level - = dropdown_tag(protected_branch.push_access_level.humanize, - options: { title: "Allowed to push", toggle_class: 'allowed-to-push', dropdown_class: 'dropdown-menu-selectable push', - data: { field_name: "allowed_to_push_#{protected_branch.id}", url: url, id: protected_branch.id, type: "push_access_level" }}) + = dropdown_tag( (protected_branch.push_access_level.humanize || 'Select') , + options: { toggle_class: 'js-allowed-to-push', dropdown_class: 'dropdown-menu-selectable js-allowed-to-push-container', + data: { field_name: "allowed_to_push_#{protected_branch.id}" }}) - if can_admin_project %td - = link_to 'Unprotect', [@project.namespace.becomes(Namespace), @project, protected_branch], data: { confirm: 'Branch will be writable for developers. Are you sure?' }, method: :delete, class: "btn btn-warning btn-sm pull-right" + = link_to 'Unprotect', [@project.namespace.becomes(Namespace), @project, protected_branch], data: { confirm: 'Branch will be writable for developers. Are you sure?' }, method: :delete, class: 'btn btn-warning' diff --git a/app/views/projects/protected_branches/index.html.haml b/app/views/projects/protected_branches/index.html.haml index 4efe44c7233..49dcc9a6ba4 100644 --- a/app/views/projects/protected_branches/index.html.haml +++ b/app/views/projects/protected_branches/index.html.haml @@ -14,41 +14,7 @@ %li prevent <strong>anyone</strong> from deleting the branch %p.append-bottom-0 Read more about #{link_to "protected branches", help_page_path("user/project/protected_branches"), class: "underlined-link"} and #{link_to "project permissions", help_page_path("user/permissions"), class: "underlined-link"}. .col-lg-9 - %h5.prepend-top-0 - Protect a branch - if can? current_user, :admin_project, @project - = form_for [@project.namespace.becomes(Namespace), @project, @protected_branch] do |f| - = form_errors(@protected_branch) + = render 'create_protected_branch' - .form-group - = f.label :name, "Branch", class: "label-light" - = render partial: "dropdown", locals: { f: f } - %p.help-block - = link_to "Wildcards", help_page_path('user/project/protected_branches', anchor: "wildcard-protected-branches") - such as - %code *-stable - or - %code production/* - are supported. - - .form-group - = hidden_field_tag 'protected_branch[merge_access_level_attributes][access_level]' - = label_tag "Allowed to merge: ", nil, class: "label-light append-bottom-0" - = dropdown_tag("<Make a selection>", - options: { title: "Allowed to merge", toggle_class: 'allowed-to-merge', - dropdown_class: 'dropdown-menu-selectable', - data: { field_name: "protected_branch[merge_access_level_attributes][access_level]" }}) - - .form-group - = hidden_field_tag 'protected_branch[push_access_level_attributes][access_level]' - = label_tag "Allowed to push: ", nil, class: "label-light append-bottom-0" - = dropdown_tag("<Make a selection>", - options: { title: "Allowed to push", toggle_class: 'allowed-to-push', - dropdown_class: 'dropdown-menu-selectable', - data: { field_name: "protected_branch[push_access_level_attributes][access_level]" }}) - - - = f.submit "Protect", class: "btn-create btn protect-branch-btn", disabled: true - - %hr = render "branches_list" diff --git a/app/views/shared/web_hooks/_form.html.haml b/app/views/shared/web_hooks/_form.html.haml index 2585ed9360b..470dac6d75b 100644 --- a/app/views/shared/web_hooks/_form.html.haml +++ b/app/views/shared/web_hooks/_form.html.haml @@ -19,7 +19,7 @@ = f.label :token, "Secret Token", class: 'label-light' = f.text_field :token, class: "form-control", placeholder: '' %p.help-block - Use this token to validate received payloads + Use this token to validate received payloads. It will be sent with the request in the X-Gitlab-Token HTTP header. .form-group = f.label :url, "Trigger", class: 'label-light' %ul.list-unstyled |