Generalize protected branch/tag dropdowns
Remove duplicate ee code This was generalized for usage in the new variable table design, see https://gitlab.com/gitlab-org/gitlab-ce/issues/39118#note_53615249 Conflicts: app/assets/stylesheets/pages/projects.scss ee/app/assets/javascripts/protected_branches/protected_branch_create.js ee/app/assets/javascripts/protected_tags/protected_tag_create.js ee/app/views/projects/protected_branches/ee/_dropdown.html.haml
This commit is contained in:
parent
ab28ea071b
commit
b63686ce6a
8 changed files with 60 additions and 135 deletions
|
@ -1,6 +1,6 @@
|
|||
import _ from 'underscore';
|
||||
|
||||
export default class ProtectedTagDropdown {
|
||||
export default class CreateItemDropdown {
|
||||
/**
|
||||
* @param {Object} options containing
|
||||
* `$dropdown` target element
|
||||
|
@ -8,11 +8,14 @@ export default class ProtectedTagDropdown {
|
|||
* $dropdown must be an element created using `dropdown_tag()` rails helper
|
||||
*/
|
||||
constructor(options) {
|
||||
this.onSelect = options.onSelect;
|
||||
this.defaultToggleLabel = options.defaultToggleLabel;
|
||||
this.fieldName = options.fieldName;
|
||||
this.onSelect = options.onSelect || (() => {});
|
||||
this.getDataOption = options.getData;
|
||||
this.$dropdown = options.$dropdown;
|
||||
this.$dropdownContainer = this.$dropdown.parent();
|
||||
this.$dropdownFooter = this.$dropdownContainer.find('.dropdown-footer');
|
||||
this.$protectedTag = this.$dropdownContainer.find('.js-create-new-protected-tag');
|
||||
this.$createButton = this.$dropdownContainer.find('.js-dropdown-create-new-item');
|
||||
|
||||
this.buildDropdown();
|
||||
this.bindEvents();
|
||||
|
@ -23,7 +26,7 @@ export default class ProtectedTagDropdown {
|
|||
|
||||
buildDropdown() {
|
||||
this.$dropdown.glDropdown({
|
||||
data: this.getProtectedTags.bind(this),
|
||||
data: this.getData.bind(this),
|
||||
filterable: true,
|
||||
remote: false,
|
||||
search: {
|
||||
|
@ -31,14 +34,14 @@ export default class ProtectedTagDropdown {
|
|||
},
|
||||
selectable: true,
|
||||
toggleLabel(selected) {
|
||||
return (selected && 'id' in selected) ? selected.title : 'Protected Tag';
|
||||
return (selected && 'id' in selected) ? selected.title : this.defaultToggleLabel;
|
||||
},
|
||||
fieldName: 'protected_tag[name]',
|
||||
text(protectedTag) {
|
||||
return _.escape(protectedTag.title);
|
||||
fieldName: this.fieldName,
|
||||
text(item) {
|
||||
return _.escape(item.title);
|
||||
},
|
||||
id(protectedTag) {
|
||||
return _.escape(protectedTag.id);
|
||||
id(item) {
|
||||
return _.escape(item.id);
|
||||
},
|
||||
onFilter: this.toggleCreateNewButton.bind(this),
|
||||
clicked: (options) => {
|
||||
|
@ -49,37 +52,37 @@ export default class ProtectedTagDropdown {
|
|||
}
|
||||
|
||||
bindEvents() {
|
||||
this.$protectedTag.on('click', this.onClickCreateWildcard.bind(this));
|
||||
this.$createButton.on('click', this.onClickCreateWildcard.bind(this));
|
||||
}
|
||||
|
||||
onClickCreateWildcard(e) {
|
||||
e.preventDefault();
|
||||
|
||||
// Refresh the dropdown's data, which ends up calling `getData`
|
||||
this.$dropdown.data('glDropdown').remote.execute();
|
||||
this.$dropdown.data('glDropdown').selectRowAtIndex();
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
getProtectedTags(term, callback) {
|
||||
if (this.selectedTag) {
|
||||
callback(gon.open_tags.concat(this.selectedTag));
|
||||
} else {
|
||||
callback(gon.open_tags);
|
||||
}
|
||||
getData(term, callback) {
|
||||
this.getDataOption(term, (data = []) => {
|
||||
callback(data.concat(this.selectedItem || []));
|
||||
});
|
||||
}
|
||||
|
||||
toggleCreateNewButton(tagName) {
|
||||
if (tagName) {
|
||||
this.selectedTag = {
|
||||
title: tagName,
|
||||
id: tagName,
|
||||
text: tagName,
|
||||
toggleCreateNewButton(item) {
|
||||
if (item) {
|
||||
this.selectedItem = {
|
||||
title: item,
|
||||
id: item,
|
||||
text: item,
|
||||
};
|
||||
|
||||
this.$dropdownContainer
|
||||
.find('.js-create-new-protected-tag code')
|
||||
.text(tagName);
|
||||
.find('.js-dropdown-create-new-item code')
|
||||
.text(item);
|
||||
}
|
||||
|
||||
this.toggleFooter(!tagName);
|
||||
this.toggleFooter(!item);
|
||||
}
|
||||
|
||||
toggleFooter(toggleState) {
|
|
@ -1,6 +1,6 @@
|
|||
import _ from 'underscore';
|
||||
import ProtectedBranchAccessDropdown from './protected_branch_access_dropdown';
|
||||
import ProtectedBranchDropdown from './protected_branch_dropdown';
|
||||
import CreateItemDropdown from '../create_item_dropdown';
|
||||
import AccessorUtilities from '../lib/utils/accessor';
|
||||
|
||||
const PB_LOCAL_STORAGE_KEY = 'protected-branches-defaults';
|
||||
|
@ -35,10 +35,12 @@ export default class ProtectedBranchCreate {
|
|||
onSelect: this.onSelectCallback,
|
||||
});
|
||||
|
||||
// Protected branch dropdown
|
||||
this.protectedBranchDropdown = new ProtectedBranchDropdown({
|
||||
this.createItemDropdown = new CreateItemDropdown({
|
||||
$dropdown: $protectedBranchDropdown,
|
||||
defaultToggleLabel: 'Protected Branch',
|
||||
fieldName: 'protected_branch[name]',
|
||||
onSelect: this.onSelectCallback,
|
||||
getData: ProtectedBranchCreate.getProtectedBranches,
|
||||
});
|
||||
|
||||
this.loadPreviousSelection($allowedToMergeDropdown.data('glDropdown'), $allowedToPushDropdown.data('glDropdown'));
|
||||
|
@ -60,6 +62,10 @@ export default class ProtectedBranchCreate {
|
|||
this.$form.find('input[type="submit"]').attr('disabled', completedForm);
|
||||
}
|
||||
|
||||
static getProtectedBranches(term, callback) {
|
||||
callback(gon.open_branches);
|
||||
}
|
||||
|
||||
loadPreviousSelection(mergeDropdown, pushDropdown) {
|
||||
let mergeIndex = 0;
|
||||
let pushIndex = 0;
|
||||
|
|
|
@ -1,90 +0,0 @@
|
|||
import _ from 'underscore';
|
||||
|
||||
export default class ProtectedBranchDropdown {
|
||||
/**
|
||||
* @param {Object} options containing
|
||||
* `$dropdown` target element
|
||||
* `onSelect` event callback
|
||||
* $dropdown must be an element created using `dropdown_branch()` rails helper
|
||||
*/
|
||||
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('.js-create-new-protected-branch');
|
||||
|
||||
this.buildDropdown();
|
||||
this.bindEvents();
|
||||
|
||||
// Hide footer
|
||||
this.toggleFooter(true);
|
||||
}
|
||||
|
||||
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: (options) => {
|
||||
options.e.preventDefault();
|
||||
this.onSelect();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
bindEvents() {
|
||||
this.$protectedBranch.on('click', this.onClickCreateWildcard.bind(this));
|
||||
}
|
||||
|
||||
onClickCreateWildcard(e) {
|
||||
e.preventDefault();
|
||||
|
||||
// Refresh the dropdown's data, which ends up calling `getProtectedBranches`
|
||||
this.$dropdown.data('glDropdown').remote.execute();
|
||||
this.$dropdown.data('glDropdown').selectRowAtIndex();
|
||||
}
|
||||
|
||||
getProtectedBranches(term, callback) {
|
||||
if (this.selectedBranch) {
|
||||
callback(gon.open_branches.concat(this.selectedBranch));
|
||||
} else {
|
||||
callback(gon.open_branches);
|
||||
}
|
||||
}
|
||||
|
||||
toggleCreateNewButton(branchName) {
|
||||
if (branchName) {
|
||||
this.selectedBranch = {
|
||||
title: branchName,
|
||||
id: branchName,
|
||||
text: branchName,
|
||||
};
|
||||
|
||||
this.$dropdownContainer
|
||||
.find('.js-create-new-protected-branch code')
|
||||
.text(branchName);
|
||||
}
|
||||
|
||||
this.toggleFooter(!branchName);
|
||||
}
|
||||
|
||||
toggleFooter(toggleState) {
|
||||
this.$dropdownFooter.toggleClass('hidden', toggleState);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
import ProtectedTagAccessDropdown from './protected_tag_access_dropdown';
|
||||
import ProtectedTagDropdown from './protected_tag_dropdown';
|
||||
import CreateItemDropdown from '../create_item_dropdown';
|
||||
|
||||
export default class ProtectedTagCreate {
|
||||
constructor() {
|
||||
|
@ -24,9 +24,12 @@ export default class ProtectedTagCreate {
|
|||
$allowedToCreateDropdown.data('glDropdown').selectRowAtIndex(0);
|
||||
|
||||
// Protected tag dropdown
|
||||
this.protectedTagDropdown = new ProtectedTagDropdown({
|
||||
this.createItemDropdown = new CreateItemDropdown({
|
||||
$dropdown: this.$form.find('.js-protected-tag-select'),
|
||||
defaultToggleLabel: 'Protected Tag',
|
||||
fieldName: 'protected_tag[name]',
|
||||
onSelect: this.onSelectCallback,
|
||||
getData: ProtectedTagCreate.getProtectedTags,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -38,4 +41,8 @@ export default class ProtectedTagCreate {
|
|||
|
||||
this.$form.find('input[type="submit"]').attr('disabled', !($tagInput.val() && $allowedToCreateInput.length));
|
||||
}
|
||||
|
||||
static getProtectedTags(term, callback) {
|
||||
callback(gon.open_tags);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -666,6 +666,16 @@
|
|||
}
|
||||
}
|
||||
|
||||
.dropdown-create-new-item-button {
|
||||
@include dropdown-link;
|
||||
|
||||
width: 100%;
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
text-align: left;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.dropdown-loading {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
|
|
|
@ -895,17 +895,6 @@ pre.light-well {
|
|||
}
|
||||
}
|
||||
|
||||
.create-new-protected-branch-button,
|
||||
.create-new-protected-tag-button {
|
||||
@include dropdown-link;
|
||||
|
||||
width: 100%;
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
text-align: left;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.protected-branches-list,
|
||||
.protected-tags-list {
|
||||
margin-bottom: 30px;
|
||||
|
|
|
@ -10,6 +10,6 @@
|
|||
|
||||
%ul.dropdown-footer-list
|
||||
%li
|
||||
%button{ class: "create-new-protected-branch-button js-create-new-protected-branch", title: "New Protected Branch" }
|
||||
%button{ class: "dropdown-create-new-item-button js-dropdown-create-new-item", title: "New Protected Branch" }
|
||||
Create wildcard
|
||||
%code
|
||||
|
|
|
@ -10,6 +10,6 @@
|
|||
|
||||
%ul.dropdown-footer-list
|
||||
%li
|
||||
%button{ class: "create-new-protected-tag-button js-create-new-protected-tag", title: "New Protected Tag" }
|
||||
%button{ class: "dropdown-create-new-item-button js-dropdown-create-new-item", title: "New Protected Tag" }
|
||||
Create wildcard
|
||||
%code
|
||||
|
|
Loading…
Reference in a new issue