diff --git a/.rubocop_manual_todo.yml b/.rubocop_manual_todo.yml index b795fe652d7..bf347c1b7d0 100644 --- a/.rubocop_manual_todo.yml +++ b/.rubocop_manual_todo.yml @@ -2606,7 +2606,6 @@ Style/OpenStructUse: - 'spec/models/design_management/design_at_version_spec.rb' - 'spec/models/user_spec.rb' - 'spec/presenters/packages/nuget/search_results_presenter_spec.rb' - - 'spec/requests/api/graphql/mutations/design_management/delete_spec.rb' - 'spec/requests/api/import_github_spec.rb' - 'spec/services/packages/nuget/metadata_extraction_service_spec.rb' - 'spec/services/projects/import_service_spec.rb' diff --git a/app/assets/javascripts/diffs/components/diff_line_note_form.vue b/app/assets/javascripts/diffs/components/diff_line_note_form.vue index 591800ee9be..9d355c96af1 100644 --- a/app/assets/javascripts/diffs/components/diff_line_note_form.vue +++ b/app/assets/javascripts/diffs/components/diff_line_note_form.vue @@ -2,6 +2,7 @@ import { mapState, mapGetters, mapActions } from 'vuex'; import { s__ } from '~/locale'; import diffLineNoteFormMixin from '~/notes/mixins/diff_line_note_form'; +import { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal'; import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import MultilineCommentForm from '../../notes/components/multiline_comment_form.vue'; import { @@ -177,16 +178,16 @@ export default { 'saveDiffDiscussion', 'setSuggestPopoverDismissed', ]), - handleCancelCommentForm(shouldConfirm, isDirty) { + async handleCancelCommentForm(shouldConfirm, isDirty) { if (shouldConfirm && isDirty) { const msg = s__('Notes|Are you sure you want to cancel creating this comment?'); - // eslint-disable-next-line no-alert - if (!window.confirm(msg)) { + const confirmed = await confirmAction(msg); + + if (!confirmed) { return; } } - this.cancelCommentForm({ lineCode: this.line.line_code, fileHash: this.diffFileHash, diff --git a/app/assets/javascripts/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal.js b/app/assets/javascripts/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal.js index f0908a60ac5..fdd0e045d07 100644 --- a/app/assets/javascripts/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal.js +++ b/app/assets/javascripts/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal.js @@ -1,25 +1,9 @@ import Vue from 'vue'; -export function confirmViaGlModal(message, element) { +export function confirmAction(message, { primaryBtnVariant, primaryBtnText } = {}) { return new Promise((resolve) => { let confirmed = false; - const props = {}; - - const confirmBtnVariant = element.getAttribute('data-confirm-btn-variant'); - - if (confirmBtnVariant) { - props.primaryVariant = confirmBtnVariant; - } - const screenReaderText = - element.querySelector('.gl-sr-only')?.textContent || - element.querySelector('.sr-only')?.textContent || - element.getAttribute('aria-label'); - - if (screenReaderText) { - props.primaryText = screenReaderText; - } - const component = new Vue({ components: { ConfirmModal: () => import('./confirm_modal.vue'), @@ -28,7 +12,10 @@ export function confirmViaGlModal(message, element) { return h( 'confirm-modal', { - props, + props: { + primaryVariant: primaryBtnVariant, + primaryText: primaryBtnText, + }, on: { confirmed() { confirmed = true; @@ -45,3 +32,24 @@ export function confirmViaGlModal(message, element) { }).$mount(); }); } + +export function confirmViaGlModal(message, element) { + const primaryBtnConfig = {}; + + const confirmBtnVariant = element.getAttribute('data-confirm-btn-variant'); + + if (confirmBtnVariant) { + primaryBtnConfig.primaryBtnVariant = confirmBtnVariant; + } + + const screenReaderText = + element.querySelector('.gl-sr-only')?.textContent || + element.querySelector('.sr-only')?.textContent || + element.getAttribute('aria-label'); + + if (screenReaderText) { + primaryBtnConfig.primaryBtnText = screenReaderText; + } + + return confirmAction(message, primaryBtnConfig); +} diff --git a/app/assets/javascripts/pipeline_editor/components/commit/commit_form.vue b/app/assets/javascripts/pipeline_editor/components/commit/commit_form.vue index f1fe8cf10fd..905a5f2d271 100644 --- a/app/assets/javascripts/pipeline_editor/components/commit/commit_form.vue +++ b/app/assets/javascripts/pipeline_editor/components/commit/commit_form.vue @@ -36,6 +36,11 @@ export default { required: false, default: false, }, + scrollToCommitForm: { + type: Boolean, + required: false, + default: false, + }, }, data() { return { @@ -52,6 +57,13 @@ export default { return !(this.message && this.targetBranch); }, }, + watch: { + scrollToCommitForm(flag) { + if (flag) { + this.scrollIntoView(); + } + }, + }, methods: { onSubmit() { this.$emit('submit', { @@ -63,6 +75,10 @@ export default { onReset() { this.$emit('cancel'); }, + scrollIntoView() { + this.$el.scrollIntoView({ behavior: 'smooth' }); + this.$emit('scrolled-to-commit-form'); + }, }, i18n: { commitMessage: __('Commit message'), diff --git a/app/assets/javascripts/pipeline_editor/components/commit/commit_section.vue b/app/assets/javascripts/pipeline_editor/components/commit/commit_section.vue index 9b5287afae9..14c11099756 100644 --- a/app/assets/javascripts/pipeline_editor/components/commit/commit_section.vue +++ b/app/assets/javascripts/pipeline_editor/components/commit/commit_section.vue @@ -45,6 +45,11 @@ export default { required: false, default: false, }, + scrollToCommitForm: { + type: Boolean, + required: false, + default: false, + }, }, data() { return { @@ -146,6 +151,8 @@ export default { :current-branch="currentBranch" :default-message="defaultCommitMessage" :is-saving="isSaving" + :scroll-to-commit-form="scrollToCommitForm" + v-on="$listeners" @cancel="onCommitCancel" @submit="onCommitSubmit" /> diff --git a/app/assets/javascripts/pipeline_editor/components/drawer/pipeline_editor_drawer.vue b/app/assets/javascripts/pipeline_editor/components/drawer/pipeline_editor_drawer.vue index ff1e0b6388f..d7594fb318a 100644 --- a/app/assets/javascripts/pipeline_editor/components/drawer/pipeline_editor_drawer.vue +++ b/app/assets/javascripts/pipeline_editor/components/drawer/pipeline_editor_drawer.vue @@ -2,6 +2,7 @@ import { GlButton, GlIcon } from '@gitlab/ui'; import { __ } from '~/locale'; import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue'; +import { experiment } from '~/experimentation/utils'; import { DRAWER_EXPANDED_KEY } from '../../constants'; import FirstPipelineCard from './cards/first_pipeline_card.vue'; import GettingStartedCard from './cards/getting_started_card.vue'; @@ -53,12 +54,23 @@ export default { }, methods: { setInitialExpandState() { + let isExpanded; + + experiment('pipeline_editor_walkthrough', { + control: () => { + isExpanded = true; + }, + candidate: () => { + isExpanded = false; + }, + }); + // We check in the local storage and if no value is defined, we want the default // to be true. We want to explicitly set it to true here so that the drawer // animates to open on load. const localValue = localStorage.getItem(this.$options.localDrawerKey); if (localValue === null) { - this.isExpanded = true; + this.isExpanded = isExpanded; } }, setTopPosition() { diff --git a/app/assets/javascripts/pipeline_editor/components/file_nav/branch_switcher.vue b/app/assets/javascripts/pipeline_editor/components/file_nav/branch_switcher.vue index f27c2cd9dca..baf1d17b233 100644 --- a/app/assets/javascripts/pipeline_editor/components/file_nav/branch_switcher.vue +++ b/app/assets/javascripts/pipeline_editor/components/file_nav/branch_switcher.vue @@ -112,7 +112,7 @@ export default { isBranchesLoading() { return this.$apollo.queries.availableBranches.loading || this.isSearchingBranches; }, - showBranchSwitcher() { + enableBranchSwitcher() { return this.branches.length > 0 || this.searchTerm.length > 0; }, }, @@ -230,11 +230,11 @@ export default {