From 548bfbd5d7e3885e8dd662618f9fc4b585460ce9 Mon Sep 17 00:00:00 2001 From: therealrinku Date: Thu, 11 Dec 2025 15:09:31 +0545 Subject: [PATCH 01/12] Add ref selector dropdown to create mr from issue modal Changelog: changed --- ...item_create_branch_merge_request_modal.vue | 122 +++++++----------- .../javascripts/work_items/constants.js | 3 - locale/gitlab.pot | 15 +-- ..._create_branch_merge_request_modal_spec.js | 19 +++ 4 files changed, 68 insertions(+), 91 deletions(-) diff --git a/app/assets/javascripts/work_items/components/work_item_development/work_item_create_branch_merge_request_modal.vue b/app/assets/javascripts/work_items/components/work_item_development/work_item_create_branch_merge_request_modal.vue index 775a8e51079551..d2d07a238f0b0e 100644 --- a/app/assets/javascripts/work_items/components/work_item_development/work_item_create_branch_merge_request_modal.vue +++ b/app/assets/javascripts/work_items/components/work_item_development/work_item_create_branch_merge_request_modal.vue @@ -3,11 +3,8 @@ import { GlForm, GlFormInput, GlFormInputGroup, GlFormGroup, GlModal } from '@gi import { debounce } from 'lodash'; import axios from '~/lib/utils/axios_utils'; import { createAlert } from '~/alert'; -import { - NAME_TO_TEXT_LOWERCASE_MAP, - WORK_ITEM_CREATE_ENTITY_MODAL_TARGET_SOURCE, - WORK_ITEM_CREATE_ENTITY_MODAL_TARGET_BRANCH, -} from '~/work_items/constants'; +import { REF_TYPE_BRANCHES, ALL_REF_TYPES } from '~/ref/constants'; +import { NAME_TO_TEXT_LOWERCASE_MAP } from '~/work_items/constants'; import { visitUrl } from '~/lib/utils/url_utility'; import { createBranchMRApiPathHelper } from '~/work_items/utils'; import { helpPagePath } from '~/helpers/help_page_helper'; @@ -16,7 +13,7 @@ import { humanizeBranchValidationErrors, } from '~/lib/utils/text_utility'; import SimpleCopyButton from '~/vue_shared/components/simple_copy_button.vue'; - +import RefSelector from '~/ref/components/ref_selector.vue'; import getProjectRootRef from '~/work_items/graphql/get_project_root_ref.query.graphql'; import { s__, __, sprintf } from '~/locale'; import confidentialMergeRequestState from '~/confidential_merge_request/state'; @@ -31,20 +28,19 @@ export default { GlModal, ProjectFormGroup, SimpleCopyButton, + RefSelector, }, i18n: { - sourceLabel: __('Source (branch or tag)'), - branchLabel: __('Branch name'), + sourceBranchOrTagLabel: __('Source (branch or tag)'), + targetBranchLabel: __('Target branch'), + newBranchLabel: __('Branch name'), + sourceBranchLabel: __('Source branch name'), createBranch: __('Create branch'), cancelLabel: __('Cancel'), createMergeRequest: __('Create merge request'), branchNameExists: __('Branch is already taken'), - sourceNotAvailable: __('Source is not available'), branchNameAvailable: __('Branch name is available'), - sourceIsAvailable: __('Source is available'), branchNameIsRequired: __('Branch name is required'), - sourceNameIsRequired: __('Source name is required'), - checkingSourceValidity: __('Checking source validity'), checkingBranchValidity: __('Checking branch validity'), }, createMRModalId: 'create-merge-request-modal', @@ -88,13 +84,10 @@ export default { isLoading: false, canCreateBranch: false, branchName: '', - sourceName: '', - invalidSource: false, + refName: '', invalidBranch: false, - invalidForm: false, sourceDescription: '', branchDescription: '', - checkingSourceValidity: false, checkingBranchValidity: false, creatingBranch: false, defaultBranch: '', @@ -121,16 +114,27 @@ export default { }, }, computed: { + enabledRefTypes() { + return this.showBranchFlow ? ALL_REF_TYPES : [REF_TYPE_BRANCHES]; + }, + numericProjectId() { + return this.projectId.split('/').at(-1); + }, + refSelectorFieldLabel() { + return this.showBranchFlow + ? this.$options.i18n.sourceBranchOrTagLabel + : this.$options.i18n.targetBranchLabel; + }, + branchNameFieldLabel() { + return this.showBranchFlow + ? this.$options.i18n.newBranchLabel + : this.$options.i18n.sourceBranchLabel; + }, createButtonText() { return this.showBranchFlow ? this.$options.i18n.createBranch : this.$options.i18n.createMergeRequest; }, - sourceFeedback() { - return this.sourceName?.length - ? this.$options.i18n.sourceNotAvailable - : this.$options.i18n.sourceNameIsRequired; - }, branchFeedback() { const branchErrors = findInvalidBranchNameCharacters(this.branchName); if (!this.branchName.length) { @@ -146,7 +150,8 @@ export default { }, isSaveButtonDisabled() { return ( - this.invalidForm || (this.isConfidentialWorkItem && !this.canCreateConfidentialMergeRequest) + this.invalidBranch || + (this.isConfidentialWorkItem && !this.canCreateConfidentialMergeRequest) ); }, saveButtonAction() { @@ -155,8 +160,7 @@ export default { attributes: { variant: 'confirm', disabled: this.isSaveButtonDisabled, - loading: - this.checkingSourceValidity || this.checkingBranchValidity || this.creatingBranch, + loading: this.checkingBranchValidity || this.creatingBranch, }, }; }, @@ -206,7 +210,7 @@ export default { if (this.canCreateBranch) { this.branchName = suggested_branch_name; /* eslint-enable camelcase */ - this.sourceName = this.defaultBranch; + this.refName = this.defaultBranch; } }, async createBranch() { @@ -226,7 +230,7 @@ export default { : null, format: 'json', issue_iid: this.workItemIid, - ref: this.sourceName, + ref: this.refName, }); this.$toast.show(__('Branch created.'), { @@ -257,7 +261,7 @@ export default { : this.workItemFullPath, workItemIid: this.workItemIid, sourceBranch: this.branchName, - targetBranch: this.sourceName, + targetBranch: this.refName, }); /** open the merge request once we have it created */ @@ -270,21 +274,14 @@ export default { this.createMergeRequest(); } }, - fetchRefs(refValue, target) { + fetchRefs(refValue) { if (!refValue || !refValue.trim().length) { - this.invalidSource = target === WORK_ITEM_CREATE_ENTITY_MODAL_TARGET_SOURCE; - this.invalidBranch = target === WORK_ITEM_CREATE_ENTITY_MODAL_TARGET_BRANCH; - this.invalidForm = true; + this.invalidBranch = true; return; } - if (target === WORK_ITEM_CREATE_ENTITY_MODAL_TARGET_SOURCE) { - this.checkingSourceValidity = true; - this.sourceDescription = __('Checking source validity…'); - } else { - this.checkingBranchValidity = true; - this.branchDescription = __('Checking branch validity…'); - } + this.checkingBranchValidity = true; + this.branchDescription = __('Checking branch validity…'); this.refCancelToken = axios.CancelToken.source(); @@ -302,17 +299,9 @@ export default { const branches = data?.Branches || []; const tags = data?.Tags || []; - if (target === WORK_ITEM_CREATE_ENTITY_MODAL_TARGET_SOURCE) { - this.invalidSource = !( - branches.indexOf(refValue) !== -1 || tags.indexOf(refValue) !== -1 - ); - } else { - this.invalidBranch = Boolean( - branches.indexOf(refValue) !== -1 || findInvalidBranchNameCharacters(refValue).length, - ); - } - - this.invalidForm = this.invalidSource || this.invalidBranch; + this.invalidBranch = Boolean( + branches.indexOf(refValue) !== -1 || findInvalidBranchNameCharacters(refValue).length, + ); }) .catch((thrown) => { if (axios.isCancel(thrown)) { @@ -324,24 +313,19 @@ export default { return false; }) .finally(() => { - this.checkingSourceValidity = false; this.checkingBranchValidity = false; }); }, - checkValidity: debounce(function debouncedCheckValidity(refValue, target) { + checkBranchValidity: debounce(function debouncedCheckBranchValidity(refValue, target) { return this.fetchRefs(refValue, target); }, 250), hideModal() { this.$emit('hideModal'); this.$nextTick(() => { this.invalidBranch = false; - this.invalidSource = false; - this.invalidForm = false; }); }, }, - WORK_ITEM_CREATE_ENTITY_MODAL_TARGET_SOURCE, - WORK_ITEM_CREATE_ENTITY_MODAL_TARGET_BRANCH, }; @@ -366,33 +350,19 @@ export default { :help-page-path="$options.mergeRequestHelpPagePath" :new-fork-path="newForkPath" /> - - +