Skip to content
Snippets Groups Projects

Resolve "Customize branch name when using create branch in an issue"

All threads resolved!
Compare and Show latest version
3 files
+ 98
85
Compare changes
  • Side-by-side
  • Inline
Files
3
@@ -13,11 +13,12 @@ export default class CreateMergeRequestDropdown {
constructor(wrapperEl) {
this.wrapperEl = wrapperEl;
this.availableButton = this.wrapperEl.querySelector('.available');
this.branchInput = this.wrapperEl.querySelector('.js-branch-name');
this.branchMessage = this.wrapperEl.querySelector('.js-branch-message');
this.createMergeRequestButton = this.wrapperEl.querySelector('.js-create-merge-request');
this.createTargetButton = this.wrapperEl.querySelector('.js-create-target');
this.dropdownList = this.wrapperEl.querySelector('.dropdown-menu');
this.dropdownToggle = this.wrapperEl.querySelector('.js-dropdown-toggle');
this.newBranchMessage = this.wrapperEl.querySelector('#new-branch-message');
this.branchInput = this.wrapperEl.querySelector('#new-branch-name');
this.refInput = this.wrapperEl.querySelector('#ref');
this.refMessage = this.wrapperEl.querySelector('#ref-message');
this.unavailableButton = this.wrapperEl.querySelector('.unavailable');
@@ -60,13 +61,15 @@ export default class CreateMergeRequestDropdown {
this.createMergeRequestButton.classList.remove('disabled');
this.createMergeRequestButton.removeAttribute('disabled');
this.createTargetButton.classList.remove('disabled');
this.createTargetButton.removeAttribute('disabled', 'disabled');
this.dropdownToggle.classList.remove('disabled');
this.dropdownToggle.removeAttribute('disabled');
}
disable() {
this.createMergeRequestButton.classList.add('disabled');
this.createMergeRequestButton.setAttribute('disabled', 'disabled');
this.disableCreateAction();
this.dropdownToggle.classList.add('disabled');
this.dropdownToggle.setAttribute('disabled', 'disabled');
@@ -75,6 +78,9 @@ export default class CreateMergeRequestDropdown {
disableCreateAction() {
this.createMergeRequestButton.classList.add('disabled');
this.createMergeRequestButton.setAttribute('disabled', 'disabled');
this.createTargetButton.classList.add('disabled');
this.createTargetButton.setAttribute('disabled', 'disabled');
}
hide() {
@@ -137,7 +143,7 @@ export default class CreateMergeRequestDropdown {
.done((data) => {
this.refs = data;
})
.fail((xhr) => {
.fail(() => {
this.unavailable();
this.disable();
new Flash('Failed to get refs.');
@@ -147,13 +153,12 @@ export default class CreateMergeRequestDropdown {
getRef(ref, type = 'all') {
if (!this.refs) return false;
const target = new RegExp('^' + $.trim(ref).replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'));
const target = new RegExp(`^${$.trim(ref).replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')}`);
if (type === 'branch') {
return this.refs.Branches.find(value => target.test(value));
} else {
return this.refs.Branches.find(value => target.test(value)) || this.refs.Tags.find(value => target.test(value));
}
if (type === 'branch') return this.refs.Branches.find(value => target.test(value));
return this.refs.Branches.find(value => target.test(value)) ||
this.refs.Tags.find(value => target.test(value));
}
initDroplab() {
@@ -165,19 +170,32 @@ export default class CreateMergeRequestDropdown {
getDroplabConfig() {
return {
InputSetter: [{
input: this.createMergeRequestButton,
valueAttribute: 'data-value',
inputAttribute: 'data-action',
}, {
input: this.createMergeRequestButton,
valueAttribute: 'data-text',
}],
InputSetter: [
{
input: this.createMergeRequestButton,
valueAttribute: 'data-value',
inputAttribute: 'data-action',
},
{
input: this.createMergeRequestButton,
valueAttribute: 'data-text',
},
{
input: this.createTargetButton,
valueAttribute: 'data-value',
inputAttribute: 'data-action',
},
{
input: this.createTargetButton,
valueAttribute: 'data-text',
},
],
};
}
bindEvents() {
this.createMergeRequestButton.addEventListener('click', this.onClickCreateMergeRequestButton.bind(this));
this.createTargetButton.addEventListener('click', this.onClickCreateMergeRequestButton.bind(this));
this.dropdownToggle.addEventListener('click', this.onClickSetFocusOnBranchNameInput.bind(this));
this.dropdownToggle.addEventListener('click', this.onClickGetRefs.bind(this));
this.branchInput.addEventListener('keyup', this.onChangeBranchInput.bind(this));
@@ -193,69 +211,61 @@ export default class CreateMergeRequestDropdown {
this.isGettingRefs;
}
showCheckBranchExistsMessage() {
this.removeGlFieldErrorClasses('branch');
this.newBranchMessage.classList.add('gl-field-hint');
this.newBranchMessage.textContent = 'Checking branch name availability...';
this.newBranchMessage.classList.remove('hide');
}
showNewBranchTakenMessage() {
this.removeGlFieldErrorClasses('branch');
this.branchInput.classList.add('gl-field-error-outline');
this.newBranchMessage.classList.add('gl-field-error-message');
this.newBranchMessage.textContent = 'Branch name is already taken';
this.newBranchMessage.classList.remove('hide');
}
showNewBranchAvailableMessage() {
this.removeGlFieldErrorClasses('branch');
this.branchInput.classList.add('gl-field-success-outline');
this.newBranchMessage.classList.add('gl-field-success-message');
this.newBranchMessage.textContent = 'Branch name is available';
this.newBranchMessage.classList.remove('hide');
}
showCheckRefExistsMessage() {
this.removeGlFieldErrorClasses('ref');
this.refMessage.classList.add('gl-field-hint');
this.refMessage.textContent = 'Checking source availability...';
this.refMessage.classList.remove('hide');
}
showRefAvailableMessage() {
this.removeGlFieldErrorClasses('ref');
this.refInput.classList.add('gl-field-success-outline');
this.refMessage.classList.add('gl-field-success-message');
this.refMessage.textContent = 'Source is available';
this.refMessage.classList.remove('hide');
}
showRefNotAvailableMessage() {
this.removeGlFieldErrorClasses('ref');
this.refInput.classList.add('gl-field-error-outline');
this.refMessage.classList.add('gl-field-error-message');
this.refMessage.textContent = 'Source is not available';
this.refMessage.classList.remove('hide');
}
removeGlFieldErrorClasses(target) {
let input = null;
let message = null;
// target: 'branch', 'ref'
// type: 'checking', 'available', 'not_available'
showMessage(target, type) {
let input;
let message;
let text;
if (target === 'branch') {
input = this.branchInput;
message = this.newBranchMessage;
message = this.branchMessage;
text = 'branch name';
} else {
input = this.refInput;
message = this.refMessage;
text = 'source';
}
// Remove gl-field error classes
input.classList.remove('gl-field-error-outline');
input.classList.remove('gl-field-success-outline');
message.classList.remove('gl-field-hint');
message.classList.remove('gl-field-error-message');
message.classList.remove('gl-field-success-message');
if (type === 'checking') {
message.classList.add('gl-field-hint');
message.textContent = `Checking ${text} availability...`;
message.classList.remove('hide');
return;
}
if (type === 'not_available') {
if (target === 'branch') {
text = 'Branch is already taken';
} else {
text = 'Source is not available';
}
input.classList.add('gl-field-error-outline');
message.classList.add('gl-field-error-message');
message.textContent = text;
message.classList.remove('hide');
return;
}
if (type === 'available') {
text = text.charAt(0).toUpperCase() + text.slice(1);
input.classList.add('gl-field-success-outline');
message.classList.add('gl-field-success-message');
message.textContent = `${text} is available`;
message.classList.remove('hide');
}
}
onClickSetFocusOnBranchNameInput() {
@@ -289,28 +299,27 @@ export default class CreateMergeRequestDropdown {
this.createMrPath = this.wrapperEl.dataset.createMrPath;
this.inputsAreValid = true;
this.enable();
this.showNewBranchAvailableMessage();
this.showMessage('branch', 'available');
return;
}
if (this.getRef(branch, 'branch') === branch) {
this.inputsAreValid = false;
this.disableCreateAction();
this.showNewBranchTakenMessage();
this.showMessage('branch', 'not_available');
} else {
this.inputsAreValid = true;
this.enable();
this.showNewBranchAvailableMessage();
this.showMessage('branch', 'available');
this.createBranchPath = this.createBranchPath.replace(/(branch_name=)(.+?)(?=&issue)/, `$1${branch}`);
this.createMrPath = this.createMrPath.replace(/(branch_name=)(.+?)(?=&ref)/, `$1${branch}`);
}
}
onChangeRefInput(event) {
console.log(this.createMrPath)
// Remove selected text (autocomplete text).
const ref = this.refInput.value.slice(0, this.refInput.selectionStart) + this.refInput.value.slice(this.refInput.selectionEnd);
const ref = this.refInput.value.slice(0, this.refInput.selectionStart) +
this.refInput.value.slice(this.refInput.selectionEnd);
if (this.isGettingRefs) return;
@@ -332,30 +341,30 @@ export default class CreateMergeRequestDropdown {
this.createMrPath = this.wrapperEl.dataset.createMrPath;
this.inputsAreValid = true;
this.enable();
this.showRefAvailableMessage();
this.showMessage('ref', 'available');
return;
}
this.createBranchPath = this.createBranchPath.replace(/(ref=)(.+?)$/, `$1${ref}`);
this.createMrPath = this.createMrPath.replace(/(ref=)(.+?)$/, `$1${ref}`);
const foundRef = this.getRef(ref, 'all')
const foundRef = this.getRef(ref, 'all');
if (ref === foundRef) {
this.inputsAreValid = true;
this.enable();
this.showRefAvailableMessage();
this.showMessage('ref', 'available');
} else {
this.inputsAreValid = false;
this.disableCreateAction();
this.showRefNotAvailableMessage();
this.showMessage('ref', 'not_available');
// Show the first found ref as a hint.
if (foundRef) {
clearTimeout(this.delay);
this.delay = setTimeout(() => {
this.refInput.value = foundRef;
this.refInput.setSelectionRange(ref.length, foundRef.length)
this.refInput.setSelectionRange(ref.length, foundRef.length);
}, 500);
}
}
Loading