diff options
author | Jacob Schatz <jschatz@gitlab.com> | 2016-08-08 13:38:04 +0000 |
---|---|---|
committer | Jacob Schatz <jschatz@gitlab.com> | 2016-08-08 13:38:04 +0000 |
commit | b767d8688511d7fdb9487e96c18eb62788fd629b (patch) | |
tree | f383c78130419f2609383a3c3407890952b585ed | |
parent | f2efd892044e8f2d81c9cbf9b6efe2b836b2c95d (diff) | |
parent | 26c1b72d8f63d1ef24738d5df43d2dfe9cb2cf68 (diff) | |
download | gitlab-ce-b767d8688511d7fdb9487e96c18eb62788fd629b.tar.gz |
Merge branch 'branch-permissions' into 'master'
Branch permissions layout
CE part of https://gitlab.com/gitlab-org/gitlab-ee/issues/179
Related javascript code has been refactored and also layout has been updated.
![Screen_Shot_2016-08-04_at_3.23.19_PM](/uploads/a0f6165e255b3f93dcb80eaa3f3318e4/Screen_Shot_2016-08-04_at_3.23.19_PM.png)
See merge request !5652
18 files changed, 350 insertions, 229 deletions
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 cc7e422fd89..d3394fae3f9 100644 --- a/app/assets/javascripts/gl_dropdown.js +++ b/app/assets/javascripts/gl_dropdown.js @@ -607,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) { @@ -615,8 +615,6 @@ } $el = $(selector, this.dropdown); if ($el.length) { - e.preventDefault(); - e.stopImmediatePropagation(); return $el.first().trigger('click'); } }; @@ -653,7 +651,7 @@ return false; } if (currentKeyCode === 13 && currentIndex !== -1) { - return _this.selectRowAtIndex(e, $('.is-focused', _this.dropdown).closest('li').index() - 1); + return _this.selectRowAtIndex($('.is-focused', _this.dropdown).closest('li').index() - 1); } }; })(this)); 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/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/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/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss index d91c8e61165..cf9aa02600d 100644 --- a/app/assets/stylesheets/pages/projects.scss +++ b/app/assets/stylesheets/pages/projects.scss @@ -656,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; } } @@ -678,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/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/spec/features/protected_branches_spec.rb b/spec/features/protected_branches_spec.rb index 57734b33a44..3499460c84d 100644 --- a/spec/features/protected_branches_spec.rb +++ b/spec/features/protected_branches_spec.rb @@ -11,7 +11,7 @@ feature 'Projected Branches', feature: true, js: true do def set_protected_branch_name(branch_name) find(".js-protected-branch-select").click find(".dropdown-input-field").set(branch_name) - click_on "Create Protected Branch: #{branch_name}" + click_on("Create wildcard #{branch_name}") end describe "explicit protected branches" do @@ -90,7 +90,7 @@ feature 'Projected Branches', feature: true, js: true do visit namespace_project_protected_branches_path(project.namespace, project) set_protected_branch_name('master') within('.new_protected_branch') do - find(".allowed-to-push").click + find(".js-allowed-to-push").click within(".dropdown.open .dropdown-menu") { click_on access_type_name } end click_on "Protect" @@ -107,8 +107,8 @@ feature 'Projected Branches', feature: true, js: true do expect(ProtectedBranch.count).to eq(1) within(".protected-branches-list") do - find(".allowed-to-push").click - within('.dropdown-menu.push') { click_on access_type_name } + find(".js-allowed-to-push").click + within('.js-allowed-to-push-container') { click_on access_type_name } end wait_for_ajax @@ -121,7 +121,7 @@ feature 'Projected Branches', feature: true, js: true do visit namespace_project_protected_branches_path(project.namespace, project) set_protected_branch_name('master') within('.new_protected_branch') do - find(".allowed-to-merge").click + find(".js-allowed-to-merge").click within(".dropdown.open .dropdown-menu") { click_on access_type_name } end click_on "Protect" @@ -138,8 +138,8 @@ feature 'Projected Branches', feature: true, js: true do expect(ProtectedBranch.count).to eq(1) within(".protected-branches-list") do - find(".allowed-to-merge").click - within('.dropdown-menu.merge') { click_on access_type_name } + find(".js-allowed-to-merge").click + within('.js-allowed-to-merge-container') { click_on access_type_name } end wait_for_ajax |