diff --git a/app/assets/javascripts/lib/utils/confirm_via_gl_modal/confirm_modal.vue b/app/assets/javascripts/lib/utils/confirm_via_gl_modal/confirm_modal.vue
new file mode 100644
index 0000000000000000000000000000000000000000..733d0f69f5d855b65a06134f410ea72d38916ccc
--- /dev/null
+++ b/app/assets/javascripts/lib/utils/confirm_via_gl_modal/confirm_modal.vue
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
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
new file mode 100644
index 0000000000000000000000000000000000000000..f0908a60ac53d535869e407bb84474d111ae622d
--- /dev/null
+++ b/app/assets/javascripts/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal.js
@@ -0,0 +1,47 @@
+import Vue from 'vue';
+
+export function confirmViaGlModal(message, element) {
+ 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'),
+ },
+ render(h) {
+ return h(
+ 'confirm-modal',
+ {
+ props,
+ on: {
+ confirmed() {
+ confirmed = true;
+ },
+ closed() {
+ component.$destroy();
+ resolve(confirmed);
+ },
+ },
+ },
+ [message],
+ );
+ },
+ }).$mount();
+ });
+}
diff --git a/app/assets/javascripts/lib/utils/rails_ujs.js b/app/assets/javascripts/lib/utils/rails_ujs.js
index 8b40cc7bd111690bc38a33e2ae92e5a9af6bf455..6b1985a23baa4ac6ffb52208fdd1ffffd7fe8e3b 100644
--- a/app/assets/javascripts/lib/utils/rails_ujs.js
+++ b/app/assets/javascripts/lib/utils/rails_ujs.js
@@ -1,4 +1,42 @@
import Rails from '@rails/ujs';
+import { confirmViaGlModal } from './confirm_via_gl_modal/confirm_via_gl_modal';
+
+function monkeyPatchConfirmModal() {
+ /**
+ * This function is used to replace the `Rails.confirm` which uses `window.confirm`
+ *
+ * This function opens a confirmation modal which will resolve in a promise.
+ * Because the `Rails.confirm` API is synchronous, we go with a little hack here:
+ *
+ * 1. User clicks on something with `data-confirm`
+ * 2. We open the modal and return `false`, ending the "Rails" event chain
+ * 3. If the modal is closed and the user "confirmed" the action
+ * 1. replace the `Rails.confirm` with a function that always returns `true`
+ * 2. click the same element programmatically
+ *
+ * @param message {String} Message to be shown in the modal
+ * @param element {HTMLElement} Element that was clicked on
+ * @returns {boolean}
+ */
+ function confirmViaModal(message, element) {
+ confirmViaGlModal(message, element)
+ .then((confirmed) => {
+ if (confirmed) {
+ Rails.confirm = () => true;
+ element.click();
+ Rails.confirm = confirmViaModal;
+ }
+ })
+ .catch(() => {});
+ return false;
+ }
+
+ Rails.confirm = confirmViaModal;
+}
+
+if (gon?.features?.bootstrapConfirmationModals) {
+ monkeyPatchConfirmModal();
+}
export const initRails = () => {
// eslint-disable-next-line no-underscore-dangle
diff --git a/config/feature_flags/development/bootstrap_confirmation_modals.yml b/config/feature_flags/development/bootstrap_confirmation_modals.yml
new file mode 100644
index 0000000000000000000000000000000000000000..e67fd03fea658c2a23d4ca6ebfcffa5d67e33950
--- /dev/null
+++ b/config/feature_flags/development/bootstrap_confirmation_modals.yml
@@ -0,0 +1,8 @@
+---
+name: bootstrap_confirmation_modals
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73167
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/344658
+milestone: '14.5'
+type: development
+group: group::foundations
+default_enabled: false
diff --git a/ee/spec/features/admin/admin_settings_spec.rb b/ee/spec/features/admin/admin_settings_spec.rb
index 70acb198c28e86c51c1a3007a68b13c11906de62..a772a4de3f2d4d3d9c1e15cc96e659b767045b53 100644
--- a/ee/spec/features/admin/admin_settings_spec.rb
+++ b/ee/spec/features/admin/admin_settings_spec.rb
@@ -6,6 +6,7 @@
include StubENV
before do
+ stub_feature_flags(bootstrap_confirmation_modals: false)
stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
admin = create(:admin)
sign_in(admin)
diff --git a/ee/spec/features/admin/subscriptions/admin_views_subscription_spec.rb b/ee/spec/features/admin/subscriptions/admin_views_subscription_spec.rb
index bc6c10101bd24309167cc0961bc9c1a598290bbb..c7bcdf1db0151e9e9aeca3b4021ea7d32a1b864e 100644
--- a/ee/spec/features/admin/subscriptions/admin_views_subscription_spec.rb
+++ b/ee/spec/features/admin/subscriptions/admin_views_subscription_spec.rb
@@ -6,6 +6,7 @@
let_it_be(:admin) { create(:admin) }
before do
+ stub_feature_flags(bootstrap_confirmation_modals: false)
sign_in(admin)
gitlab_enable_admin_mode_sign_in(admin)
end
diff --git a/ee/spec/features/epic_boards/epic_boards_spec.rb b/ee/spec/features/epic_boards/epic_boards_spec.rb
index 227a7516611700789b33b563ade570599d5dcfc2..9c9e9fbb611d12f72a6c8064f1eba06b12575898 100644
--- a/ee/spec/features/epic_boards/epic_boards_spec.rb
+++ b/ee/spec/features/epic_boards/epic_boards_spec.rb
@@ -115,6 +115,8 @@
context 'lists' do
let_it_be(:label_list2) { create(:epic_list, epic_board: epic_board, label: label2, position: 1) }
+ stub_feature_flags(bootstrap_confirmation_modals: false)
+
it 'changes position of list' do
expect(find_board_list(2)).to have_content(label.title)
expect(find_board_list(3)).to have_content(label2.title)
diff --git a/ee/spec/features/groups/members/leave_group_spec.rb b/ee/spec/features/groups/members/leave_group_spec.rb
index 4b2ccb0d2c5cf05bc35cf26426411799c27231c8..4b2a76e6d085d88a1bc16b00f18c3a456ba975e9 100644
--- a/ee/spec/features/groups/members/leave_group_spec.rb
+++ b/ee/spec/features/groups/members/leave_group_spec.rb
@@ -13,6 +13,7 @@
before do
user.update!(provisioned_by_group: group)
sign_in(user)
+ stub_feature_flags(bootstrap_confirmation_modals: false)
end
context 'with block_password_auth_for_saml_users feature flag switched on' do
diff --git a/ee/spec/features/projects/path_locks_spec.rb b/ee/spec/features/projects/path_locks_spec.rb
index 35c42ed7eedfb85c048bf701f302923508cc8b1a..60006abc568e4b30592825532327b6ddd62607e4 100644
--- a/ee/spec/features/projects/path_locks_spec.rb
+++ b/ee/spec/features/projects/path_locks_spec.rb
@@ -9,6 +9,7 @@
before do
allow(project).to receive(:feature_available?).with(:file_locks) { true }
+ stub_feature_flags(bootstrap_confirmation_modals: false)
project.add_maintainer(user)
sign_in(user)
diff --git a/ee/spec/features/projects/settings/protected_environments_spec.rb b/ee/spec/features/projects/settings/protected_environments_spec.rb
index 08af51dbe7c4b5207bce315be91028c9f588408d..05d1f98b2cc2a80dd6f0af3d1b981c7acfe412a1 100644
--- a/ee/spec/features/projects/settings/protected_environments_spec.rb
+++ b/ee/spec/features/projects/settings/protected_environments_spec.rb
@@ -34,6 +34,7 @@
context 'logged in as a maintainer' do
before do
+ stub_feature_flags(bootstrap_confirmation_modals: false)
project.add_maintainer(user)
visit project_settings_ci_cd_path(project)
diff --git a/ee/spec/support/shared_examples/features/protected_branches_access_control_shared_examples.rb b/ee/spec/support/shared_examples/features/protected_branches_access_control_shared_examples.rb
index 98431236cc890918d6191856edc4ca8df281eeda..9ad5f9b03eeb53d67297f4cd88bc92046a9ac962 100644
--- a/ee/spec/support/shared_examples/features/protected_branches_access_control_shared_examples.rb
+++ b/ee/spec/support/shared_examples/features/protected_branches_access_control_shared_examples.rb
@@ -173,6 +173,7 @@ def last_access_levels(git_operation)
let!(:protected_branch) { create(:protected_branch, project: project) }
before do
+ stub_feature_flags(bootstrap_confirmation_modals: false)
stub_licensed_features(unprotection_restrictions: true)
end
diff --git a/lib/gitlab/gon_helper.rb b/lib/gitlab/gon_helper.rb
index 6faf3575bc1b927929a526c9cf6a01d3cfb33fc7..027551df15d0440bcd8d13042b11e1ede61482d1 100644
--- a/lib/gitlab/gon_helper.rb
+++ b/lib/gitlab/gon_helper.rb
@@ -58,6 +58,7 @@ def add_gon_variables
push_frontend_feature_flag(:new_header_search, default_enabled: :yaml)
push_frontend_feature_flag(:suppress_apollo_errors_during_navigation, current_user, default_enabled: :yaml)
push_frontend_feature_flag(:configure_iac_scanning_via_mr, current_user, default_enabled: :yaml)
+ push_frontend_feature_flag(:bootstrap_confirmation_modals, default_enabled: :yaml)
end
# Exposes the state of a feature flag to the frontend code.
diff --git a/spec/features/admin/admin_disables_two_factor_spec.rb b/spec/features/admin/admin_disables_two_factor_spec.rb
index 1f34c4ed17c6fbd798103de5436676bd9d39f018..f65e85b4cb62c6021b47af36285f17a941aeeaf1 100644
--- a/spec/features/admin/admin_disables_two_factor_spec.rb
+++ b/spec/features/admin/admin_disables_two_factor_spec.rb
@@ -4,6 +4,7 @@
RSpec.describe 'Admin disables 2FA for a user' do
it 'successfully', :js do
+ stub_feature_flags(bootstrap_confirmation_modals: false)
admin = create(:admin)
sign_in(admin)
gitlab_enable_admin_mode_sign_in(admin)
diff --git a/spec/features/admin/admin_groups_spec.rb b/spec/features/admin/admin_groups_spec.rb
index 8315b8f44b02225030d5a8a441180abb788cf0d1..8d4e7a7442c31c2ebc34b2328c7c8eac36dfc959 100644
--- a/spec/features/admin/admin_groups_spec.rb
+++ b/spec/features/admin/admin_groups_spec.rb
@@ -252,6 +252,7 @@
describe 'admin remove themself from a group', :js, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/222342' do
it 'removes admin from the group' do
+ stub_feature_flags(bootstrap_confirmation_modals: false)
group.add_user(current_user, Gitlab::Access::DEVELOPER)
visit group_group_members_path(group)
diff --git a/spec/features/admin/admin_hooks_spec.rb b/spec/features/admin/admin_hooks_spec.rb
index a501efd82edd41e97182bb5b4ba21176b3af15d2..32e4d18227edcef3d4d7fda8cc372168224fd1ad 100644
--- a/spec/features/admin/admin_hooks_spec.rb
+++ b/spec/features/admin/admin_hooks_spec.rb
@@ -79,6 +79,7 @@
let(:hook_url) { generate(:url) }
before do
+ stub_feature_flags(bootstrap_confirmation_modals: false)
create(:system_hook, url: hook_url)
end
diff --git a/spec/features/admin/admin_labels_spec.rb b/spec/features/admin/admin_labels_spec.rb
index 08d81906d9f002645030b86deca3711870a002ea..65de1160cfdaa920dc20aeedff9327a72475b062 100644
--- a/spec/features/admin/admin_labels_spec.rb
+++ b/spec/features/admin/admin_labels_spec.rb
@@ -14,6 +14,7 @@
describe 'list' do
before do
+ stub_feature_flags(bootstrap_confirmation_modals: false)
visit admin_labels_path
end
diff --git a/spec/features/admin/admin_users_impersonation_tokens_spec.rb b/spec/features/admin/admin_users_impersonation_tokens_spec.rb
index ed8ea84fbf821c97f587faa0642d544d154b43d9..6643ebe82e69d7f3688084760b2be7fd79145e6f 100644
--- a/spec/features/admin/admin_users_impersonation_tokens_spec.rb
+++ b/spec/features/admin/admin_users_impersonation_tokens_spec.rb
@@ -74,6 +74,7 @@ def created_impersonation_token
let!(:impersonation_token) { create(:personal_access_token, :impersonation, user: user) }
it "allows revocation of an active impersonation token" do
+ stub_feature_flags(bootstrap_confirmation_modals: false)
visit admin_user_impersonation_tokens_path(user_id: user.username)
accept_confirm { click_on "Revoke" }
diff --git a/spec/features/admin/admin_uses_repository_checks_spec.rb b/spec/features/admin/admin_uses_repository_checks_spec.rb
index 0e4484460859669a3d25b9f48564cbc7217948c3..c13313609b595ba043345f14885c55b20f8248a7 100644
--- a/spec/features/admin/admin_uses_repository_checks_spec.rb
+++ b/spec/features/admin/admin_uses_repository_checks_spec.rb
@@ -8,6 +8,7 @@
let(:admin) { create(:admin) }
before do
+ stub_feature_flags(bootstrap_confirmation_modals: false)
stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
sign_in(admin)
end
diff --git a/spec/features/admin/users/user_spec.rb b/spec/features/admin/users/user_spec.rb
index 624bfde7359823bd7b106b5368aeab32caed6d04..73477fb93dd0dbc7c6cd0d7f46f39c316740bcce 100644
--- a/spec/features/admin/users/user_spec.rb
+++ b/spec/features/admin/users/user_spec.rb
@@ -9,6 +9,7 @@
let_it_be(:current_user) { create(:admin) }
before do
+ stub_feature_flags(bootstrap_confirmation_modals: false)
sign_in(current_user)
gitlab_enable_admin_mode_sign_in(current_user)
end
diff --git a/spec/features/admin/users/users_spec.rb b/spec/features/admin/users/users_spec.rb
index 119b01ff552e3d2deb81a2c609620590764f63f4..3968b055819a686e2d90f81527a844fa6405a9e5 100644
--- a/spec/features/admin/users/users_spec.rb
+++ b/spec/features/admin/users/users_spec.rb
@@ -9,6 +9,7 @@
let_it_be(:current_user) { create(:admin) }
before do
+ stub_feature_flags(bootstrap_confirmation_modals: false)
sign_in(current_user)
gitlab_enable_admin_mode_sign_in(current_user)
end
diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb
index 9a5b5bbfc343b492dca9bd8fd08d7132c7bf2501..2f21961d1fca9e485e1cd9d88550867309362919 100644
--- a/spec/features/boards/boards_spec.rb
+++ b/spec/features/boards/boards_spec.rb
@@ -536,6 +536,7 @@
let_it_be(:user_guest) { create(:user) }
before do
+ stub_feature_flags(bootstrap_confirmation_modals: false)
project.add_guest(user_guest)
sign_in(user_guest)
visit project_board_path(project, board)
diff --git a/spec/features/groups/members/leave_group_spec.rb b/spec/features/groups/members/leave_group_spec.rb
index b73313745e9c6537e9c8a77fb951087428fb204b..e6bf1ffc2f736645c5036e383e89df1d19722ce4 100644
--- a/spec/features/groups/members/leave_group_spec.rb
+++ b/spec/features/groups/members/leave_group_spec.rb
@@ -10,6 +10,7 @@
let(:group) { create(:group) }
before do
+ stub_feature_flags(bootstrap_confirmation_modals: false)
sign_in(user)
end
diff --git a/spec/features/merge_request/user_comments_on_diff_spec.rb b/spec/features/merge_request/user_comments_on_diff_spec.rb
index 54c3fe738d2f31a2839005a0d53c60d7d4105dc3..f9b554c5ed288fa4a833139b87a852edcb53c536 100644
--- a/spec/features/merge_request/user_comments_on_diff_spec.rb
+++ b/spec/features/merge_request/user_comments_on_diff_spec.rb
@@ -14,6 +14,7 @@
let(:user) { create(:user) }
before do
+ stub_feature_flags(bootstrap_confirmation_modals: false)
project.add_maintainer(user)
sign_in(user)
diff --git a/spec/features/merge_request/user_posts_diff_notes_spec.rb b/spec/features/merge_request/user_posts_diff_notes_spec.rb
index c339a7d9976ce2ffb982404884989d6c0d7e6985..dcd289c76270f73d368be9c32262f11aeaee80ab 100644
--- a/spec/features/merge_request/user_posts_diff_notes_spec.rb
+++ b/spec/features/merge_request/user_posts_diff_notes_spec.rb
@@ -18,6 +18,7 @@
project.add_developer(user)
sign_in(user)
+ stub_feature_flags(bootstrap_confirmation_modals: false)
end
context 'when hovering over a parallel view diff file' do
diff --git a/spec/features/merge_request/user_posts_notes_spec.rb b/spec/features/merge_request/user_posts_notes_spec.rb
index 83d9388914b7c58f392893c87f1fd33b5e34be0e..0416474218fc80eb0447ca3effd99049ffe5862c 100644
--- a/spec/features/merge_request/user_posts_notes_spec.rb
+++ b/spec/features/merge_request/user_posts_notes_spec.rb
@@ -18,8 +18,10 @@
end
before do
+ stub_feature_flags(bootstrap_confirmation_modals: false)
project.add_maintainer(user)
sign_in(user)
+
visit project_merge_request_path(project, merge_request)
end
diff --git a/spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb b/spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb
index 90cdc28d1bda4b38fdb82eecd0cb2fcb58989f13..64cd5aa2bb14708dea4051a662b55272fb4249c7 100644
--- a/spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb
+++ b/spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb
@@ -79,6 +79,7 @@
%w(parallel).each do |view|
context "#{view} view" do
before do
+ stub_feature_flags(bootstrap_confirmation_modals: false)
visit diffs_project_merge_request_path(project, merge_request, view: view)
wait_for_requests
diff --git a/spec/features/merge_request/user_sees_deployment_widget_spec.rb b/spec/features/merge_request/user_sees_deployment_widget_spec.rb
index 873cc0a89c6491819651b4f53aecbf134d315cfa..345404cc28f4061ac2003f4075bf957fe1000557 100644
--- a/spec/features/merge_request/user_sees_deployment_widget_spec.rb
+++ b/spec/features/merge_request/user_sees_deployment_widget_spec.rb
@@ -110,6 +110,7 @@
let(:manual) { create(:ci_build, :manual, pipeline: pipeline, name: 'close_app') }
before do
+ stub_feature_flags(bootstrap_confirmation_modals: false)
build.success!
deployment.update!(on_stop: manual.name)
visit project_merge_request_path(project, merge_request)
diff --git a/spec/features/profile_spec.rb b/spec/features/profile_spec.rb
index 9a261c6d9c86336f0c959d5e673812efc93ba757..7d935298f38989274ef73e65692d0809eb649e82 100644
--- a/spec/features/profile_spec.rb
+++ b/spec/features/profile_spec.rb
@@ -6,6 +6,7 @@
let(:user) { create(:user) }
before do
+ stub_feature_flags(bootstrap_confirmation_modals: false)
sign_in(user)
end
@@ -80,6 +81,7 @@
describe 'when I reset incoming email token' do
before do
allow(Gitlab.config.incoming_email).to receive(:enabled).and_return(true)
+ stub_feature_flags(bootstrap_confirmation_modals: false)
visit profile_personal_access_tokens_path
end
diff --git a/spec/features/profiles/active_sessions_spec.rb b/spec/features/profiles/active_sessions_spec.rb
index fd64704b7c8c68705669c012374ed65caf0d24b1..a515c7b1c1f51a351acf8179c012afa51a6f5486 100644
--- a/spec/features/profiles/active_sessions_spec.rb
+++ b/spec/features/profiles/active_sessions_spec.rb
@@ -11,6 +11,10 @@
let(:admin) { create(:admin) }
+ before do
+ stub_feature_flags(bootstrap_confirmation_modals: false)
+ end
+
it 'user sees their active sessions' do
travel_to(Time.zone.parse('2018-03-12 09:06')) do
Capybara::Session.new(:session1)
diff --git a/spec/features/profiles/oauth_applications_spec.rb b/spec/features/profiles/oauth_applications_spec.rb
index 2735f60130733d785ce45473613db15ce9e98171..6827dff5434b8182751b9b8f3dfbfc7b4731894e 100644
--- a/spec/features/profiles/oauth_applications_spec.rb
+++ b/spec/features/profiles/oauth_applications_spec.rb
@@ -7,6 +7,7 @@
let(:application) { create(:oauth_application, owner: user) }
before do
+ stub_feature_flags(bootstrap_confirmation_modals: false)
sign_in(user)
end
diff --git a/spec/features/profiles/personal_access_tokens_spec.rb b/spec/features/profiles/personal_access_tokens_spec.rb
index 8f44299b18fd87c558036985d48d101c355e4d74..74505633cae8ce39eb48364b04566e6068965c44 100644
--- a/spec/features/profiles/personal_access_tokens_spec.rb
+++ b/spec/features/profiles/personal_access_tokens_spec.rb
@@ -34,6 +34,7 @@ def disallow_personal_access_token_saves!
end
before do
+ stub_feature_flags(bootstrap_confirmation_modals: false)
sign_in(user)
end
diff --git a/spec/features/projects/branches/user_deletes_branch_spec.rb b/spec/features/projects/branches/user_deletes_branch_spec.rb
index 3b8f49accc5d61e11e766f5e7cea764b69af36ec..8fc5c3d2e1b417e38288886801b6d06d2ff353cf 100644
--- a/spec/features/projects/branches/user_deletes_branch_spec.rb
+++ b/spec/features/projects/branches/user_deletes_branch_spec.rb
@@ -35,6 +35,7 @@
context 'when the feature flag :delete_branch_confirmation_modals is disabled' do
before do
+ stub_feature_flags(bootstrap_confirmation_modals: false)
stub_feature_flags(delete_branch_confirmation_modals: false)
end
diff --git a/spec/features/projects/branches_spec.rb b/spec/features/projects/branches_spec.rb
index 0a79719f14a5f12ceb6ce367446fb8a6ac924926..2725c6a91bec02848ef105b92d135b68f1b318d4 100644
--- a/spec/features/projects/branches_spec.rb
+++ b/spec/features/projects/branches_spec.rb
@@ -179,6 +179,7 @@
context 'when the delete_branch_confirmation_modals feature flag is disabled' do
it 'removes branch after confirmation', :js do
stub_feature_flags(delete_branch_confirmation_modals: false)
+ stub_feature_flags(bootstrap_confirmation_modals: false)
visit project_branches_filtered_path(project, state: 'all')
diff --git a/spec/features/projects/commit/comments/user_deletes_comments_spec.rb b/spec/features/projects/commit/comments/user_deletes_comments_spec.rb
index 431cbb4ffbb51876726ef40dd0af8bd8b12dc286..67d3276fc14690e4e2050d31fb65e53fb360b729 100644
--- a/spec/features/projects/commit/comments/user_deletes_comments_spec.rb
+++ b/spec/features/projects/commit/comments/user_deletes_comments_spec.rb
@@ -11,6 +11,7 @@
let(:user) { create(:user) }
before do
+ stub_feature_flags(bootstrap_confirmation_modals: false)
sign_in(user)
project.add_developer(user)
diff --git a/spec/features/projects/commit/user_comments_on_commit_spec.rb b/spec/features/projects/commit/user_comments_on_commit_spec.rb
index 6997c2d8338340f34b631272a622685218019c1d..b0be6edb24555d833e9431fe87dcbff4b7e43d06 100644
--- a/spec/features/projects/commit/user_comments_on_commit_spec.rb
+++ b/spec/features/projects/commit/user_comments_on_commit_spec.rb
@@ -93,6 +93,8 @@
context "when deleting comment" do
before do
+ stub_feature_flags(bootstrap_confirmation_modals: false)
+
visit(project_commit_path(project, sample_commit.id))
add_note(comment_text)
diff --git a/spec/features/projects/environments/environments_spec.rb b/spec/features/projects/environments/environments_spec.rb
index 2404fbf01ca2d5f2bd885f935f54bd331b8bd779..3b83c25b6290fe24bde47da601146a4c3bdc05e3 100644
--- a/spec/features/projects/environments/environments_spec.rb
+++ b/spec/features/projects/environments/environments_spec.rb
@@ -143,6 +143,8 @@ def upcoming_deployment_content_selector
create(:environment, project: project, state: :available)
end
+ stub_feature_flags(bootstrap_confirmation_modals: false)
+
context 'when there are no deployments' do
before do
visit_environments(project)
diff --git a/spec/features/projects/jobs/user_browses_job_spec.rb b/spec/features/projects/jobs/user_browses_job_spec.rb
index 5d7a761cb17bf36b18446fc6da0b8b8f4bb98ef7..12e88bbf6a53916e7924a4e1c84fbdfbdfaeed4c 100644
--- a/spec/features/projects/jobs/user_browses_job_spec.rb
+++ b/spec/features/projects/jobs/user_browses_job_spec.rb
@@ -12,6 +12,7 @@
before do
project.add_maintainer(user)
project.enable_ci
+ stub_feature_flags(bootstrap_confirmation_modals: false)
sign_in(user)
diff --git a/spec/features/projects/members/member_leaves_project_spec.rb b/spec/features/projects/members/member_leaves_project_spec.rb
index c4bd0b81dc09ea0ae434e5fa0da1ec73f32c06e9..4881a7bdf1a5228f575f90481cc0828905e503ba 100644
--- a/spec/features/projects/members/member_leaves_project_spec.rb
+++ b/spec/features/projects/members/member_leaves_project_spec.rb
@@ -9,6 +9,7 @@
before do
project.add_developer(user)
sign_in(user)
+ stub_feature_flags(bootstrap_confirmation_modals: false)
end
it 'user leaves project' do
diff --git a/spec/features/projects/members/user_requests_access_spec.rb b/spec/features/projects/members/user_requests_access_spec.rb
index 113ba69249788e026bbb315b9cf858319a00457c..dcaef5f4ef0d265280dca0a3538635324fdb5193 100644
--- a/spec/features/projects/members/user_requests_access_spec.rb
+++ b/spec/features/projects/members/user_requests_access_spec.rb
@@ -11,6 +11,7 @@
before do
sign_in(user)
visit project_path(project)
+ stub_feature_flags(bootstrap_confirmation_modals: false)
end
it 'request access feature is disabled' do
diff --git a/spec/features/projects/pages/user_adds_domain_spec.rb b/spec/features/projects/pages/user_adds_domain_spec.rb
index de9effe3dc7a40305c4fd2c9b5c4281d510bdcfc..06f130ae69c82e071e2f91bfc7ad3a0175dbf8bc 100644
--- a/spec/features/projects/pages/user_adds_domain_spec.rb
+++ b/spec/features/projects/pages/user_adds_domain_spec.rb
@@ -14,6 +14,8 @@
project.add_maintainer(user)
sign_in(user)
+
+ stub_feature_flags(bootstrap_confirmation_modals: false)
end
context 'when pages are exposed on external HTTP address', :http_pages_enabled do
diff --git a/spec/features/projects/pages/user_edits_lets_encrypt_settings_spec.rb b/spec/features/projects/pages/user_edits_lets_encrypt_settings_spec.rb
index cf8438d5e6fa6aaedd41a71ab9cffa2c7fabf6db..a3fc5804e1325ffc6b67e892ade3f063a978a4d0 100644
--- a/spec/features/projects/pages/user_edits_lets_encrypt_settings_spec.rb
+++ b/spec/features/projects/pages/user_edits_lets_encrypt_settings_spec.rb
@@ -14,6 +14,7 @@
before do
allow(Gitlab.config.pages).to receive(:enabled).and_return(true)
stub_lets_encrypt_settings
+ stub_feature_flags(bootstrap_confirmation_modals: false)
project.add_role(user, role)
sign_in(user)
diff --git a/spec/features/projects/pages/user_edits_settings_spec.rb b/spec/features/projects/pages/user_edits_settings_spec.rb
index 71d4cce278402bea7ea30ee4dbb927ff834834c9..1226e1dc2edce9662f9c8bee5626b791f0f1fe62 100644
--- a/spec/features/projects/pages/user_edits_settings_spec.rb
+++ b/spec/features/projects/pages/user_edits_settings_spec.rb
@@ -176,6 +176,7 @@
describe 'Remove page' do
context 'when pages are deployed' do
before do
+ stub_feature_flags(bootstrap_confirmation_modals: false)
project.mark_pages_as_deployed
end
diff --git a/spec/features/projects/pipeline_schedules_spec.rb b/spec/features/projects/pipeline_schedules_spec.rb
index 94e3331b173a4533161d3c5825b483fd01a1e1d1..9df430c0f78ae33cbbf1d36fb0867a6edb2e0551 100644
--- a/spec/features/projects/pipeline_schedules_spec.rb
+++ b/spec/features/projects/pipeline_schedules_spec.rb
@@ -11,6 +11,7 @@
context 'logged in as maintainer' do
before do
+ stub_feature_flags(bootstrap_confirmation_modals: false)
project.add_maintainer(user)
gitlab_sign_in(user)
end
diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb
index 3a60087818d2ee2f8354bc72c27f6483e15c0997..e38c4989f26f64e8f260a27a697e2ac29ec79064 100644
--- a/spec/features/projects/pipelines/pipelines_spec.rb
+++ b/spec/features/projects/pipelines/pipelines_spec.rb
@@ -317,6 +317,7 @@
end
before do
+ stub_feature_flags(bootstrap_confirmation_modals: false)
visit_project_pipelines
end
diff --git a/spec/features/projects/settings/access_tokens_spec.rb b/spec/features/projects/settings/access_tokens_spec.rb
index 4941b936c0c68a8875d450d7df1edbb9f85b51b9..d8de9e0449eaad58b62c4da35ea5d06920a7fbf1 100644
--- a/spec/features/projects/settings/access_tokens_spec.rb
+++ b/spec/features/projects/settings/access_tokens_spec.rb
@@ -13,6 +13,7 @@
end
before do
+ stub_feature_flags(bootstrap_confirmation_modals: false)
sign_in(user)
end
diff --git a/spec/features/projects/settings/user_searches_in_settings_spec.rb b/spec/features/projects/settings/user_searches_in_settings_spec.rb
index 7ed96d01189d85df3b19c303611f4f7d85b84b03..44b5464a1b0e4772bbc4b555f200a75ed8b25909 100644
--- a/spec/features/projects/settings/user_searches_in_settings_spec.rb
+++ b/spec/features/projects/settings/user_searches_in_settings_spec.rb
@@ -7,6 +7,7 @@
let_it_be(:project) { create(:project, :repository, namespace: user.namespace, pages_https_only: false) }
before do
+ stub_feature_flags(bootstrap_confirmation_modals: false)
sign_in(user)
end
diff --git a/spec/features/snippets/notes_on_personal_snippets_spec.rb b/spec/features/snippets/notes_on_personal_snippets_spec.rb
index fc88cd9205c1aa909df66a4995197836b3d3ad87..6bd31d7314cdae39a4e46a8984a08a8ee7628233 100644
--- a/spec/features/snippets/notes_on_personal_snippets_spec.rb
+++ b/spec/features/snippets/notes_on_personal_snippets_spec.rb
@@ -18,6 +18,7 @@
end
before do
+ stub_feature_flags(bootstrap_confirmation_modals: false)
sign_in user
visit snippet_path(snippet)
diff --git a/spec/features/snippets/user_creates_snippet_spec.rb b/spec/features/snippets/user_creates_snippet_spec.rb
index ca050daa62a32fdabebec7ab3a1c500571e2978a..82fe895d397b0c85ae571256ee9b8142432d042e 100644
--- a/spec/features/snippets/user_creates_snippet_spec.rb
+++ b/spec/features/snippets/user_creates_snippet_spec.rb
@@ -16,6 +16,7 @@
let(:snippet_title_field) { 'snippet-title' }
before do
+ stub_feature_flags(bootstrap_confirmation_modals: false)
sign_in(user)
visit new_snippet_path
diff --git a/spec/features/triggers_spec.rb b/spec/features/triggers_spec.rb
index 6fa805d8c74611da3ea71a56026cbaf855d915cf..2ddd86dd8075fa7b6e22bc8253fc798224b22ec2 100644
--- a/spec/features/triggers_spec.rb
+++ b/spec/features/triggers_spec.rb
@@ -72,6 +72,7 @@
describe 'trigger "Revoke" workflow' do
before do
+ stub_feature_flags(bootstrap_confirmation_modals: false)
create(:ci_trigger, owner: user2, project: @project, description: trigger_title)
visit project_settings_ci_cd_path(@project)
end
diff --git a/spec/frontend/lib/utils/confirm_via_gl_modal/confirm_modal_spec.js b/spec/frontend/lib/utils/confirm_via_gl_modal/confirm_modal_spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..d19f9352bbc816eb8b273c449048faf2bc04b825
--- /dev/null
+++ b/spec/frontend/lib/utils/confirm_via_gl_modal/confirm_modal_spec.js
@@ -0,0 +1,59 @@
+import { GlModal } from '@gitlab/ui';
+import { mount } from '@vue/test-utils';
+import ConfirmModal from '~/lib/utils/confirm_via_gl_modal/confirm_modal.vue';
+
+describe('Confirm Modal', () => {
+ let wrapper;
+ let modal;
+
+ const createComponent = ({ primaryText, primaryVariant } = {}) => {
+ wrapper = mount(ConfirmModal, {
+ propsData: {
+ primaryText,
+ primaryVariant,
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ const findGlModal = () => wrapper.findComponent(GlModal);
+
+ describe('Modal events', () => {
+ beforeEach(() => {
+ createComponent();
+ modal = findGlModal();
+ });
+
+ it('should emit `confirmed` event on `primary` modal event', () => {
+ findGlModal().vm.$emit('primary');
+ expect(wrapper.emitted('confirmed')).toBeTruthy();
+ });
+
+ it('should emit closed` event on `hidden` modal event', () => {
+ modal.vm.$emit('hidden');
+ expect(wrapper.emitted('closed')).toBeTruthy();
+ });
+ });
+
+ describe('Custom properties', () => {
+ it('should pass correct custom primary text & button variant to the modal when provided', () => {
+ const primaryText = "Let's do it!";
+ const primaryVariant = 'danger';
+
+ createComponent({ primaryText, primaryVariant });
+ const customProps = findGlModal().props('actionPrimary');
+ expect(customProps.text).toBe(primaryText);
+ expect(customProps.attributes.variant).toBe(primaryVariant);
+ });
+
+ it('should pass default primary text & button variant to the modal if no custom values provided', () => {
+ createComponent();
+ const customProps = findGlModal().props('actionPrimary');
+ expect(customProps.text).toBe('OK');
+ expect(customProps.attributes.variant).toBe('confirm');
+ });
+ });
+});
diff --git a/spec/support/shared_examples/features/2fa_shared_examples.rb b/spec/support/shared_examples/features/2fa_shared_examples.rb
index ddc03e178ba8088173a46a6a34c4eb1ace8603f5..94c91556ea786665b248887e49b4cd346bb5aa80 100644
--- a/spec/support/shared_examples/features/2fa_shared_examples.rb
+++ b/spec/support/shared_examples/features/2fa_shared_examples.rb
@@ -18,6 +18,7 @@ def register_device(device_type, **kwargs)
let(:user) { create(:user) }
before do
+ stub_feature_flags(bootstrap_confirmation_modals: false)
gitlab_sign_in(user)
user.update_attribute(:otp_required_for_login, true)
end