Skip to content
Snippets Groups Projects

Improve delete merged branches modal

Merged Nataliia Radina requested to merge 20384-delete-merged-branches into master
All threads resolved!
Compare and
10 files
+ 1100
20
Compare changes
  • Side-by-side
  • Inline
Files
10
<script>
import {
GlButton,
GlFormInput,
GlModal,
GlSprintf,
GlTooltipDirective,
GlCollapse,
} from '@gitlab/ui';
import csrf from '~/lib/utils/csrf';
import { sprintf, s__, __, n__ } from '~/locale';
export const maxAmountOfVisibleBranches = 10;
export const i18n = {
deleteButtonText: s__('Branches|Delete merged branches'),
buttonTooltipText: s__("Branches|Delete all branches that are merged into '%{defaultBranch}'"),
modalTitle: s__('Branches|Delete all merged branches?'),
modalTitleProtectedBranch: s__('Branches|Delete protected branch. Are you ABSOLUTELY SURE?'),
modalMessage: s__(
'Branches|You are about to %{strongStart} delete %{branchesAmount} %{subject} %{strongEnd} that %{verb} merged into %{codeStart}%{defaultBranch}%{codeEnd}.',
),
protectedBranchWarning: s__(
"Branches|A branch won't be deleted if it is protected or associated with an open merge request.",
),
permanentEffectWarning: s__(
'Branches|This bulk action is %{strongStart}permanent and cannot be undone or recovered%{strongEnd}.',
),
confirmationMessage: s__(
'Branches|Enter the number of merged branches to be deleted to confirm:',
),
cancelButtonText: __('Cancel'),
showMore: s__('Branches|Show more'),
showLess: s__('Branches|Show Less'),
};
export default {
csrf,
components: {
GlModal,
GlButton,
GlFormInput,
GlSprintf,
GlCollapse,
},
directives: {
GlTooltip: GlTooltipDirective,
},
props: {
branches: {
type: Array,
required: true,
},
formPath: {
type: String,
required: true,
},
defaultBranch: {
type: String,
required: true,
},
},
data() {
return {
areAllBranchesVisible: false,
enteredBranchesAmount: '',
};
},
computed: {
branchesAmount() {
return this.branches.length;
},
visibleBranches() {
return this.branches.slice(0, this.$options.maxAmountOfVisibleBranches);
},
isCollapseNeeded() {
return this.branches.length > this.$options.maxAmountOfVisibleBranches;
},
collapsedBranches() {
return this.isCollapseNeeded
? this.branches.slice(this.$options.maxAmountOfVisibleBranches)
: [];
},
collapseToggleText() {
return this.areAllBranchesVisible ? this.$options.i18n.showLess : this.$options.i18n.showMore;
},
buttonTooltipText() {
return sprintf(this.$options.i18n.buttonTooltipText, { defaultBranch: this.defaultBranch });
},
modalMessage() {
return sprintf(this.$options.i18n.modalMessage, {
defaultBranch: this.defaultBranch,
branchesAmount: this.branchesAmount,
subject: n__('branch', 'branches', this.branchesAmount),
verb: n__('was', 'were', this.branchesAmount),
});
},
branchesAmountConfirmed() {
return this.enteredBranchesAmount === this.branchesAmount.toString();
},
deleteButtonDisabled() {
return !this.branchesAmountConfirmed;
},
},
methods: {
toggleCollapse() {
this.areAllBranchesVisible = !this.areAllBranchesVisible;
},
openModal() {
this.$refs.modal.show();
},
submitForm() {
this.$refs.form.submit();
},
closeModal() {
this.$refs.modal.hide();
},
},
maxAmountOfVisibleBranches,
i18n,
};
</script>
<template>
<div>
<gl-button
v-gl-tooltip="buttonTooltipText"
class="gl-mr-3"
data-qa-selector="delete_merged_branches_button"
category="secondary"
variant="danger"
@click="openModal"
>{{ $options.i18n.deleteButtonText }}
</gl-button>
<gl-modal
ref="modal"
size="sm"
scrollable
modal-id="delete-merged-branches"
:title="$options.i18n.modalTitle"
>
<form ref="form" :action="formPath" method="post">
<p>
<gl-sprintf :message="modalMessage">
<template #strong="{ content }">
<strong>{{ content }}</strong>
</template>
<template #code="{ content }">
<code>{{ content }}</code>
</template>
</gl-sprintf>
</p>
<div class="gl-mb-5">
<ul class="gl-mb-0">
<li v-for="branch in visibleBranches" :key="branch" data-testid="visible-branch">
{{ branch }}
</li>
</ul>
<template v-if="isCollapseNeeded">
<gl-collapse :visible="areAllBranchesVisible" data-testid="collapse">
<ul class="gl-mb-0">
<li
v-for="branch in collapsedBranches"
:key="branch"
data-testid="collapsed-branch"
>
{{ branch }}
</li>
</ul>
</gl-collapse>
<div class="gl-ml-3">
<gl-button
class="gl-ml-7"
variant="link"
data-testid="collapse-toggle"
@click="toggleCollapse"
>
{{ collapseToggleText }}
</gl-button>
</div>
</template>
</div>
<p>
{{ $options.i18n.protectedBranchWarning }}
</p>
<p>
<gl-sprintf :message="$options.i18n.permanentEffectWarning">
<template #strong="{ content }">
<strong>{{ content }}</strong>
</template>
</gl-sprintf>
</p>
<p>
{{ $options.i18n.confirmationMessage }}
<gl-form-input
v-model="enteredBranchesAmount"
data-qa-selector="delete_merged_branches_input"
type="number"
size="xs"
class="gl-mt-2"
aria-labelledby="input-label"
autocomplete="off"
/>
</p>
<input ref="method" type="hidden" name="_method" value="delete" />
<input :value="$options.csrf.token" type="hidden" name="authenticity_token" />
</form>
<template #modal-footer>
<div
class="gl-display-flex gl-flex-direction-row gl-justify-content-end gl-flex-wrap gl-m-0 gl-mr-3"
>
<gl-button data-testid="delete-merged-branches-cancel-button" @click="closeModal">
{{ $options.i18n.cancelButtonText }}
</gl-button>
<gl-button
ref="deleteMergedBrancesButton"
:disabled="deleteButtonDisabled"
variant="danger"
data-qa-selector="delete_merged_branches_confirmation_button"
data-testid="delete-merged-branches-confirmation-button"
@click="submitForm"
>{{ $options.i18n.deleteButtonText }}</gl-button
>
</div>
</template>
</gl-modal>
</div>
</template>
Loading