Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
74c2fe9e
Commit
74c2fe9e
authored
Aug 17, 2016
by
Alfredo Sumaran
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Be able to select roles and users when creating a protected branch
parent
b61128e5
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
241 additions
and
82 deletions
+241
-82
app/assets/javascripts/allowed_to_merge_dropdown.js.es6
app/assets/javascripts/allowed_to_merge_dropdown.js.es6
+21
-0
app/assets/javascripts/allowed_to_push_dropdown.js.es6
app/assets/javascripts/allowed_to_push_dropdown.js.es6
+21
-0
app/assets/javascripts/gl_dropdown.js
app/assets/javascripts/gl_dropdown.js
+11
-5
app/assets/javascripts/protected_branch_access_dropdown.js.es6
...ssets/javascripts/protected_branch_access_dropdown.js.es6
+107
-4
app/assets/javascripts/protected_branch_create.js.es6
app/assets/javascripts/protected_branch_create.js.es6
+7
-5
app/assets/javascripts/protected_branch_dropdown.js.es6
app/assets/javascripts/protected_branch_dropdown.js.es6
+70
-64
app/views/projects/protected_branches/_create_protected_branch.html.haml
...cts/protected_branches/_create_protected_branch.html.haml
+4
-4
No files found.
app/assets/javascripts/allowed_to_merge_dropdown.js.es6
0 → 100644
View file @
74c2fe9e
/*= require protected_branch_access_dropdown */
(global => {
global.gl = global.gl || {};
class allowedToMergeDropdown extends gl.ProtectedBranchAccessDropdown {
fieldName(selectedItem) {
// Role by default
let fieldName = `protected_branch[merge_access_levels_attributes][${this.inputCount}][access_level]`;
if (selectedItem.type === 'user') {
fieldName = `protected_branch[merge_access_levels_attributes][${this.inputCount}][user_id]`;
}
return fieldName;
}
}
global.gl.allowedToMergeDropdown = allowedToMergeDropdown;
})(window);
app/assets/javascripts/allowed_to_push_dropdown.js.es6
0 → 100644
View file @
74c2fe9e
/*= require protected_branch_access_dropdown */
(global => {
global.gl = global.gl || {};
class allowedToPushDropdown extends gl.ProtectedBranchAccessDropdown {
fieldName(selectedItem) {
// Role by default
let fieldName = `protected_branch[push_access_levels_attributes][${this.inputCount}][access_level]`;
if (selectedItem.type === 'user') {
fieldName = `protected_branch[push_access_levels_attributes][${this.inputCount}][user_id]`;
}
return fieldName;
}
}
global.gl.allowedToPushDropdown = allowedToPushDropdown;
})(window);
app/assets/javascripts/gl_dropdown.js
View file @
74c2fe9e
...
...
@@ -470,7 +470,9 @@
}
else
{
if
(
!
selected
)
{
value
=
this
.
options
.
id
?
this
.
options
.
id
(
data
)
:
data
.
id
;
fieldName
=
this
.
options
.
fieldName
;
// fieldName = this.options.fieldName;
fieldName
=
_
.
isFunction
(
this
.
options
.
fieldName
)
?
this
.
options
.
fieldName
()
:
this
.
options
.
fieldName
;
field
=
this
.
dropdown
.
parent
().
find
(
"
input[name='
"
+
fieldName
+
"
'][value='
"
+
value
+
"
']
"
);
if
(
field
.
length
)
{
selected
=
true
;
...
...
@@ -533,7 +535,7 @@
GitLabDropdown
.
prototype
.
rowClicked
=
function
(
el
)
{
var
field
,
fieldName
,
groupName
,
isInput
,
selectedIndex
,
selectedObject
,
value
;
fieldName
=
this
.
options
.
fieldName
;
//
fieldName = this.options.fieldName;
isInput
=
$
(
this
.
el
).
is
(
'
input
'
);
if
(
this
.
renderedData
)
{
groupName
=
el
.
data
(
'
group
'
);
...
...
@@ -545,6 +547,7 @@
selectedObject
=
this
.
renderedData
[
selectedIndex
];
}
}
fieldName
=
_
.
isFunction
(
this
.
options
.
fieldName
)
?
this
.
options
.
fieldName
(
selectedObject
)
:
this
.
options
.
fieldName
;
value
=
this
.
options
.
id
?
this
.
options
.
id
(
selectedObject
,
el
)
:
selectedObject
.
id
;
if
(
isInput
)
{
field
=
$
(
this
.
el
);
...
...
@@ -570,7 +573,7 @@
field
.
remove
();
}
if
(
!
field
.
length
&&
fieldName
)
{
this
.
addInput
(
fieldName
,
value
);
this
.
addInput
(
fieldName
,
value
,
selectedObject
);
}
return
selectedObject
;
}
else
{
...
...
@@ -589,7 +592,7 @@
}
if
(
value
!=
null
)
{
if
(
!
field
.
length
&&
fieldName
)
{
this
.
addInput
(
fieldName
,
value
);
this
.
addInput
(
fieldName
,
value
,
selectedObject
);
}
else
{
field
.
val
(
value
).
trigger
(
'
change
'
);
}
...
...
@@ -598,12 +601,15 @@
}
};
GitLabDropdown
.
prototype
.
addInput
=
function
(
fieldName
,
value
)
{
GitLabDropdown
.
prototype
.
addInput
=
function
(
fieldName
,
value
,
selectedObject
)
{
var
$input
;
$input
=
$
(
'
<input>
'
).
attr
(
'
type
'
,
'
hidden
'
).
attr
(
'
name
'
,
fieldName
).
val
(
value
);
if
(
this
.
options
.
inputId
!=
null
)
{
$input
.
attr
(
'
id
'
,
this
.
options
.
inputId
);
}
if
(
selectedObject
.
type
)
{
$input
.
attr
(
'
data-type
'
,
selectedObject
.
type
);
}
return
this
.
dropdown
.
before
(
$input
);
};
...
...
app/assets/javascripts/protected_branch_access_dropdown.js.es6
View file @
74c2fe9e
...
...
@@ -4,21 +4,124 @@
gl.ProtectedBranchAccessDropdown = class {
constructor(options) {
const { $dropdown, data, onSelect } = options;
const self = this;
this.$dropdown = $dropdown;
this.usersPath = '/autocomplete/users.json';
this.inputCount = 0;
$dropdown.glDropdown({
data: data,
selectable: true,
filterable: true,
filterRemote: true,
inputId: $dropdown.data('input-id'),
fieldName: $dropdown.data('field-name'),
toggleLabel(item) {
return item.text;
data: this.getData.bind(this),
multiSelect: $dropdown.hasClass('js-multiselect'),
renderRow: this.renderRow.bind(this),
toggleLabel: this.toggleLabel.bind(this),
fieldName: this.fieldName.bind(this),
setActiveIds() {
this.activeIds = self.getActiveIds();
},
clicked(item, $el, e) {
e.preventDefault();
self.inputCount++;
onSelect();
return;
}
});
}
fieldName() {
throw new Error('No fieldName method defined');
}
toggleLabel(selectedItem, el) {
let currentItems = this.$dropdown.siblings('.dropdown-menu').find('.is-active');
let types = _.groupBy(currentItems, (item) => { return item.dataset.type; });
let label = [];
_.allKeys(types).map((type) => {
label.push(`${types[type].length} ${type}`);
});
return label.join(' and ');
}
getData(query, callback) {
this.getUsers(query).done((response) => {
let data = this.consolidateData(response);
callback(data);
});
}
consolidateData(response, callback) {
let consolidatedData;
// This probably should come from the backend already formatted
let users = response.map((user) => {
user.type = 'user';
return user;
});
let mergeAccessLevels = gon.merge_access_levels.map((level) => {
level.type = 'role';
return level;
});
consolidatedData = mergeAccessLevels;
if (users.length) {
consolidatedData = mergeAccessLevels.concat(['divider'], users);
}
return consolidatedData;
}
getUsers(query) {
return $.ajax({
dataType: 'json',
url: this.buildUrl(this.usersPath),
data: {
search: query,
per_page: 20,
active: true,
project_id: gon.current_project_id,
push_code: true,
}
});
}
buildUrl(url) {
if (gon.relative_url_root != null) {
url = gon.relative_url_root.replace(/\/$/, '') + url;
}
return url;
}
renderRow(item, instance) {
if (item.type === 'user') {
return this.userRowHtml(item);
} else if (item.type === 'role') {
return this.roleRowHtml(item);
}
}
userRowHtml(user) {
const avatarHtml = `<img src='${user.avatar_url}' class='avatar avatar-inline' width='30'>`;
const nameHtml = `<strong class='dropdown-menu-user-full-name'>${user.name}</strong>`;
const usernameHtml = `<span class='dropdown-menu-user-username'>${user.username}</span>`;
return `<li><a href='#' data-type='${user.type}'>${avatarHtml} ${nameHtml} ${usernameHtml}</a></li>`;
}
roleRowHtml(role) {
return `<li><a href='#' data-type='${role.type}'>${role.text}</a></li>`;
}
getActiveIds() {
console.log('getActiveIds');
}
}
})(window);
app/assets/javascripts/protected_branch_create.js.es6
View file @
74c2fe9e
...
...
@@ -15,14 +15,14 @@
this.onSelectCallback = this.onSelect.bind(this);
// Allowed to Merge dropdown
new gl.
ProtectedBranchAccess
Dropdown({
new gl.
allowedToMerge
Dropdown({
$dropdown: $allowedToMergeDropdown,
data: gon.merge_access_levels,
onSelect: this.onSelectCallback
});
// Allowed to Push dropdown
new gl.
ProtectedBranchAccess
Dropdown({
new gl.
allowedToPush
Dropdown({
$dropdown: $allowedToPushDropdown,
data: gon.push_access_levels,
onSelect: this.onSelectCallback
...
...
@@ -33,7 +33,7 @@
$allowedToMergeDropdown.data('glDropdown').selectRowAtIndex(0);
// Protected branch dropdown
new ProtectedBranchDropdown({
new
gl.
ProtectedBranchDropdown({
$dropdown: this.$wrap.find('.js-protected-branch-select'),
onSelect: this.onSelectCallback
});
...
...
@@ -44,10 +44,12 @@
// Enable submit button
const $branchInput = this.$wrap.find('input[name="protected_branch[name]"]');
const $allowedToMergeInput = this.$wrap.find('input[name="protected_branch[merge_access_levels_attributes][
0
][access_level]"]');
const $allowedToPushInput = this.$wrap.find('input[name="protected_branch[push_access_levels_attributes][
0
][access_level]"]');
const $allowedToMergeInput = this.$wrap.find('input[name="protected_branch[merge_access_levels_attributes][][access_level]"]');
const $allowedToPushInput = this.$wrap.find('input[name="protected_branch[push_access_levels_attributes][][access_level]"]');
console.log('onSelect');
if ($branchInput.val() && $allowedToMergeInput.val() && $allowedToPushInput.val()){
console.log('onSelect');
this.$form.find('input[type="submit"]').removeAttr('disabled');
}
}
...
...
app/assets/javascripts/protected_branch_dropdown.js.es6
View file @
74c2fe9e
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');
(global => {
global.gl = global.gl || {};
this.buildDropdown();
this.bindEvents();
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');
// 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();
}
});
}
this.buildDropdown();
this.bindEvents();
bindEvents() {
this.$protectedBranch.on('click', this.onClickCreateWildcard.bind(this)
);
}
// Hide footer
this.$dropdownFooter.addClass('hidden'
);
}
onClickCreateWildcard() {
this.$dropdown.data('glDropdown').remote.execute();
this.$dropdown.data('glDropdown').selectRowAtIndex(0);
}
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();
}
});
}
getProtectedBranches(term, callback) {
if (this.selectedBranch) {
callback(gon.open_branches.concat(this.selectedBranch));
} else {
callback(gon.open_branches);
bindEvents() {
this.$protectedBranch.on('click', this.onClickCreateWildcard.bind(this));
}
}
toggleCreateNewButton(branchName) {
this.selectedBranch = {
title: branchName,
id: branchName,
text: branchName
};
onClickCreateWildcard() {
this.$dropdown.data('glDropdown').remote.execute();
this.$dropdown.data('glDropdown').selectRowAtIndex(0);
}
if (branchName) {
this.$dropdownContainer
.find('.create-new-protected-branch code')
.text(branchName);
getProtectedBranches(term, callback) {
if (this.selectedBranch) {
callback(gon.open_branches.concat(this.selectedBranch));
} else {
callback(gon.open_branches);
}
}
this.$dropdownFooter.toggleClass('hidden', !branchName);
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);
}
}
}
global.gl.ProtectedBranchDropdown = ProtectedBranchDropdown;
})(window);
app/views/projects/protected_branches/_create_protected_branch.html.haml
View file @
74c2fe9e
...
...
@@ -23,15 +23,15 @@
Allowed to merge:
.col-md-10
=
dropdown_tag
(
'Select'
,
options:
{
toggle_class:
'js-allowed-to-merge wide
'
,
data:
{
field_name:
'protected_branch[merge_access_levels_attributes][0][access_level]'
,
input_id:
'merge_access_levels_attributes'
}})
options:
{
toggle_class:
'js-allowed-to-merge wide
js-multiselect js-multiselect'
,
dropdown_class:
'dropdown-menu-user dropdown-menu-selectable'
,
filter:
true
,
data:
{
input_id:
'merge_access_levels_attributes'
}})
.form-group
%label
.col-md-2.text-right
{
for:
'push_access_levels_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_levels_attributes][0][access_level]'
,
input_id:
'push_access_levels_attributes'
}})
options:
{
toggle_class:
'js-allowed-to-push wide
js-multiselect js-multiselect'
,
dropdown_class:
'dropdown-menu-user dropdown-menu-selectable'
,
filter:
true
,
data:
{
input_id:
'push_access_levels_attributes'
}})
.panel-footer
=
f
.
submit
'Protect'
,
class:
'btn-create btn'
,
disabled:
true
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment