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
This commit is contained in:
commit
b767d86885
18 changed files with 350 additions and 229 deletions
|
@ -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()) {
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
56
app/assets/javascripts/protected_branch_create.js.es6
Normal file
56
app/assets/javascripts/protected_branch_create.js.es6
Normal file
|
@ -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);
|
75
app/assets/javascripts/protected_branch_dropdown.js.es6
Normal file
75
app/assets/javascripts/protected_branch_dropdown.js.es6
Normal file
|
@ -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);
|
||||
}
|
||||
}
|
61
app/assets/javascripts/protected_branch_edit.js.es6
Normal file
61
app/assets/javascripts/protected_branch_edit.js.es6
Normal file
|
@ -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);
|
17
app/assets/javascripts/protected_branch_edit_list.js.es6
Normal file
17
app/assets/javascripts/protected_branch_edit_list.js.es6
Normal file
|
@ -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);
|
|
@ -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);
|
|
@ -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");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -72,6 +72,14 @@
|
|||
&.large {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
&.wide {
|
||||
width: 100%;
|
||||
|
||||
+ .dropdown-select {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-menu,
|
||||
|
|
|
@ -23,4 +23,9 @@
|
|||
margin-top: $gl-padding;
|
||||
}
|
||||
}
|
||||
|
||||
.panel-title {
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue