diff --git a/app/services/chat_names/find_user_service.rb b/app/services/chat_names/find_user_service.rb
index 3dd3ba7f01c4c51ab4ecae1c609f58baeed41701..ba6ebb7206bfa278c9a5633f8284d3dea3ee1684 100644
--- a/app/services/chat_names/find_user_service.rb
+++ b/app/services/chat_names/find_user_service.rb
@@ -19,6 +19,13 @@ def execute
 
     # rubocop: disable CodeReuse/ActiveRecord
     def find_chat_name
+      if @integration.nil?
+        return ChatName.find_by(
+          team_id: @params[:team_id],
+          chat_id: @params[:user_id]
+        )
+      end
+
       ChatName.find_by(
         integration: @integration,
         team_id: @params[:team_id],
diff --git a/ee/app/services/integrations/slack_interactions/incident_management/incident_modal_submit_service.rb b/ee/app/services/integrations/slack_interactions/incident_management/incident_modal_submit_service.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f55fd0ed033e1c7b75f69a109786c025809f6292
--- /dev/null
+++ b/ee/app/services/integrations/slack_interactions/incident_management/incident_modal_submit_service.rb
@@ -0,0 +1,121 @@
+# frozen_string_literal: true
+
+module Integrations
+  module SlackInteractions
+    module IncidentManagement
+      class IncidentModalSubmitService
+        include GitlabRoutingHelper
+        include Gitlab::Routing
+
+        IssueCreateError = Class.new(StandardError)
+
+        def initialize(params)
+          @params = params
+          @values = params.dig(:view, :state, :values)
+          @team_id = params.dig(:team, :id)
+          @user_id = params.dig(:user, :id)
+        end
+
+        attr_accessor :params, :values, :team_id, :user_id
+
+        def execute
+          create_response = Issues::CreateService.new(
+            project: project,
+            current_user: find_user.user,
+            params: incident_params,
+            spam_params: nil
+          ).execute
+
+          raise IssueCreateError, create_response.errors.to_sentence if create_response.error?
+
+          incident = create_response.payload[:issue]
+          incident_link = incident_link_text(incident)
+          response = send_to_slack(incident_link)
+
+          return ServiceResponse.success(payload: { incident: incident }) if response['ok']
+
+          ServiceResponse.error(
+            message: _('Something went wrong when sending the incident link to Slack.'),
+            payload: response
+          ).track_exception(
+            response: response.to_h,
+            slack_workspace_id: team_id,
+            slack_user_id: user_id
+          )
+        rescue StandardError => e
+          send_to_slack(_('There was a problem creating the incident. Please try again.'))
+
+          ServiceResponse
+            .error(
+              message: e.message
+            ).track_exception(
+              slack_workspace_id: team_id,
+              slack_user_id: user_id,
+              as: e.class
+            )
+        end
+
+        private
+
+        def incident_params
+          {
+            "title": values.dig(:title_input, :title, :value),
+            "severity": severity,
+            "confidential": confidential?,
+            "description": description,
+            "issue_type": "incident"
+          }
+        end
+
+        def send_to_slack(text)
+          response_url = params.dig(:view, :private_metadata)
+
+          body = {
+            'replace_original': 'true',
+            'text': text
+          }
+
+          Gitlab::HTTP.post(
+            response_url,
+            body: Gitlab::Json.dump(body),
+            headers: { 'Content-Type' => 'application/json' }
+          )
+        end
+
+        def incident_link_text(incident)
+          "#{_('New incident has been created')}: <#{issue_url(incident)}|#{incident.to_reference} - #{incident.title}>"
+        end
+
+        def project
+          full_path = values.dig(:project_and_severity_selector, :project, :selected_option, :value)
+
+          Project.find_by_full_path(full_path)
+        end
+
+        def find_user
+          ChatNames::FindUserService.new(
+            nil,
+            { team_id: team_id, user_id: user_id }
+          ).execute
+        end
+
+        def description
+          description = values.dig(:incident_description, :description, :value)
+          zoom_link = values.dig(:zoom, :link, :value)
+
+          return description if zoom_link.blank?
+
+          "#{description} \n/zoom #{zoom_link}"
+        end
+
+        def confidential?
+          values.dig(:confidentiality, :confidential, :selected_options).present?
+        end
+
+        def severity
+          values.dig(:project_and_severity_selector, :severity, :selected_option, :value) || 'unknown'
+        end
+      end
+    end
+  end
+end
diff --git a/ee/app/workers/integrations/slack_interactivity_worker.rb b/ee/app/workers/integrations/slack_interactivity_worker.rb
index 8ef16ae4734bf0f0670bf95df4a832d628f3517c..5223f3fe058a5c517b172784b6c12402d945ec84 100644
--- a/ee/app/workers/integrations/slack_interactivity_worker.rb
+++ b/ee/app/workers/integrations/slack_interactivity_worker.rb
@@ -10,7 +10,8 @@ class SlackInteractivityWorker # rubocop:disable Scalability/IdempotentWorker
     include ApplicationWorker
 
     INTERACTIONS = {
-      'view_closed' => SlackInteractions::IncidentManagement::IncidentModalClosedService
+      'view_closed' => SlackInteractions::IncidentManagement::IncidentModalClosedService,
+      'view_submission' => SlackInteractions::IncidentManagement::IncidentModalSubmitService
     }.freeze
 
     feature_category :integrations
diff --git a/ee/spec/services/integrations/slack_interactions/incident_management/incident_modal_submit_service_spec.rb b/ee/spec/services/integrations/slack_interactions/incident_management/incident_modal_submit_service_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..9349cb5d46c0f149252f1263571fd82486c6e75a
--- /dev/null
+++ b/ee/spec/services/integrations/slack_interactions/incident_management/incident_modal_submit_service_spec.rb
@@ -0,0 +1,197 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Integrations::SlackInteractions::IncidentManagement::IncidentModalSubmitService,
+  feature_category: :incident_management do
+  describe '#execute' do
+    let_it_be(:slack_installation) { create(:slack_integration) }
+    let_it_be(:project) { create(:project) }
+    let_it_be(:user) { create(:user) }
+    let_it_be(:api_url) { 'https://api.slack.com/id/1234' }
+
+    let_it_be(:chat_name) do
+      create(:chat_name,
+        user: user,
+        team_id: slack_installation.team_id,
+        chat_id: slack_installation.user_id,
+        integration: slack_installation.integration
+      )
+    end
+
+    # Setting below params as they are optional, have added values wherever required in specs
+    let(:zoom_link) { '' }
+    let(:severity) { {} }
+    let(:confidential_selected_options) { [] }
+    let(:confidential) { { selected_options: confidential_selected_options } }
+    let(:title) { 'Incident title' }
+
+    let(:zoom) do
+      {
+        link: {
+          value: zoom_link
+        }
+      }
+    end
+
+    let(:params) do
+      {
+        team: {
+          id: slack_installation.team_id
+        },
+        user: {
+          id: slack_installation.user_id
+        },
+        view: {
+          private_metadata: api_url,
+          state: {
+            values: {
+              title_input: {
+                title: {
+                  value: title
+                }
+              },
+              incident_description: {
+                description: {
+                  value: 'Incident description'
+                }
+              },
+              project_and_severity_selector: {
+                project: {
+                  selected_option: {
+                    value: project.full_path
+                  }
+                },
+                severity: severity
+              },
+              confidentiality: {
+                confidential: confidential
+              },
+              zoom: zoom
+            }
+          }
+        }
+      }
+    end
+
+    subject(:execute_service) { described_class.new(params).execute }
+
+    shared_examples 'error in creation' do |error_message|
+      it 'returns error and raises exception' do
+        expect(::Gitlab::ErrorTracking).to receive(:track_exception)
+          .with(
+            described_class::IssueCreateError.new(error_message),
+            {
+              slack_workspace_id: slack_installation.team_id,
+              slack_user_id: slack_installation.user_id
+            }
+          )
+
+        expect(Gitlab::HTTP).to receive(:post)
+          .with(
+            api_url,
+            body: Gitlab::Json.dump(
+              {
+                'replace_original': 'true',
+                'text': 'There was a problem creating the incident. Please try again.'
+              }
+            ),
+            headers: { 'Content-Type' => 'application/json' }
+          )
+
+        response = execute_service
+
+        expect(response).to be_error
+        expect(response.message).to eq(error_message)
+      end
+    end
+
+    context 'when user has permissions to create incidents' do
+      let(:api_response) { '{"ok":true}' }
+
+      before do
+        project.add_developer(user)
+        stub_request(:post, api_url)
+          .to_return(body: api_response, headers: { 'Content-Type' => 'application/json' })
+      end
+
+      context 'with non-optional params' do
+        it 'creates incident' do
+          response = execute_service
+          incident = response[:incident]
+
+          expect(response).to be_success
+          expect(incident).not_to be_nil
+          expect(incident.description).to eq('Incident description')
+          expect(incident.author).to eq(user)
+          expect(incident.severity).to eq('unknown')
+          expect(incident.confidential).to be_falsey
+        end
+
+        it 'sends incident link to slack' do
+          execute_service
+
+          expect(WebMock).to have_requested(:post, api_url)
+        end
+      end
+
+      context 'with zoom_link' do
+        let(:zoom_link) { 'https://gitlab.zoom.us/j/1234' }
+
+        it 'sets zoom link as quick action' do
+          incident = execute_service[:incident]
+          zoom_meeting = ZoomMeeting.find_by_issue_id(incident.id)
+
+          expect(incident.description).to eq("Incident description")
+          expect(zoom_meeting.url).to eq(zoom_link)
+        end
+      end
+
+      context 'with confidential and severity' do
+        let(:confidential_selected_options) { ['confidential'] }
+        let(:severity) do
+          {
+            selected_option: {
+              value: 'high'
+            }
+          }
+        end
+
+        it 'sets confidential and severity' do
+          incident = execute_service[:incident]
+
+          expect(incident.confidential).to be_truthy
+          expect(incident.severity).to eq('high')
+        end
+      end
+
+      context 'when response is not ok' do
+        let(:api_response) { '{"ok":false}' }
+
+        it 'returns error response and tracks the exception' do
+          expect(::Gitlab::ErrorTracking).to receive(:track_exception)
+            .with(
+              StandardError.new('Something went wrong when sending the incident link to Slack.'),
+              {
+                response: { 'ok' => false },
+                slack_workspace_id: slack_installation.team_id,
+                slack_user_id: slack_installation.user_id
+              }
+            )
+
+          execute_service
+        end
+      end
+
+      context 'when incident creation fails' do
+        let(:title) { '' }
+
+        it_behaves_like 'error in creation', "Title can't be blank"
+      end
+    end
+
+    context 'when user does not have permission to create incidents' do
+      it_behaves_like 'error in creation', 'Operation not allowed'
+    end
+  end
+end
diff --git a/ee/spec/workers/integrations/slack_interactivity_worker_spec.rb b/ee/spec/workers/integrations/slack_interactivity_worker_spec.rb
index 4195e0a1641613282c9aad58642ca61b362447db..99f3ecfba70b8c8bcacda20174dce9bc9eaa5288 100644
--- a/ee/spec/workers/integrations/slack_interactivity_worker_spec.rb
+++ b/ee/spec/workers/integrations/slack_interactivity_worker_spec.rb
@@ -3,19 +3,23 @@
 require 'spec_helper'
 
 RSpec.describe Integrations::SlackInteractivityWorker, :clean_gitlab_redis_shared_state do
-  describe '.interaction?' do
-    subject { described_class.interaction?(slack_interaction) }
-
-    context 'when slack_interaction is known' do
-      let(:slack_interaction) { 'view_closed' }
+  using RSpec::Parameterized::TableSyntax
 
-      it { is_expected.to be_truthy }
-    end
+  let_it_be(:slack_integration) { create(:slack_integration) }
 
-    context 'when slack_interaction is not known' do
-      let(:slack_interaction) { 'foo' }
+  describe '.interaction?' do
+    context 'when slack_interaction is known/unknown' do
+      where(:slack_interaction, :result) do
+        'view_closed'     | true
+        'view_submission' | true
+        'foo'             | false
+      end
 
-      it { is_expected.to be_falsey }
+      with_them do
+        it 'returns correct result' do
+          expect(described_class.interaction?(slack_interaction)).to be(result)
+        end
+      end
     end
   end
 
@@ -30,8 +34,6 @@
     end
 
     let(:worker) { described_class.new }
-    let(:slack_interaction) { 'view_closed' }
-    let(:service_class) { ::Integrations::SlackInteractions::IncidentManagement::IncidentModalClosedService }
 
     let(:args) do
       {
@@ -43,13 +45,16 @@
     let(:params) do
       {
         user: {
-          id: 'U0123ABCDEF'
+          id: slack_integration.user_id
         },
         team: {
-          id: 'T0123A456BC'
+          id: slack_integration.team_id
         },
         view: {
-          private_metadata: 'https://response.slack.com/id/123'
+          private_metadata: 'https://response.slack.com/id/123',
+          state: {
+            values: {}
+          }
         }
       }
     end
@@ -57,28 +62,52 @@
     shared_examples 'logs extra metadata on done' do
       specify do
         expect(worker).to receive(:log_extra_metadata_on_done).with(:slack_interaction, slack_interaction)
-        expect(worker).to receive(:log_extra_metadata_on_done).with(:slack_user_id, 'U0123ABCDEF')
-        expect(worker).to receive(:log_extra_metadata_on_done).with(:slack_workspace_id, 'T0123A456BC')
+        expect(worker).to receive(:log_extra_metadata_on_done).with(:slack_user_id, slack_integration.user_id)
+        expect(worker).to receive(:log_extra_metadata_on_done).with(:slack_workspace_id, slack_integration.team_id)
 
         worker.perform(args)
       end
     end
 
-    it 'executes the correct service' do
-      expect_next_instance_of(service_class, params) do |service|
-        expect(service).to receive(:execute).and_return(ServiceResponse.success)
+    context 'when view is closed' do
+      let(:slack_interaction) { 'view_closed' }
+
+      it 'executes the correct service' do
+        view_closed_service = described_class::INTERACTIONS['view_closed']
+
+        expect_next_instance_of(view_closed_service, params) do |service|
+          expect(service).to receive(:execute).and_return(ServiceResponse.success)
+        end
+
+        worker.perform(args)
       end
 
-      worker.perform(args)
+      it_behaves_like 'logs extra metadata on done'
     end
 
-    it_behaves_like 'logs extra metadata on done'
+    context 'when view is submitted' do
+      let(:slack_interaction) { 'view_submission' }
+
+      it 'executes the submission service' do
+        view_submission_service = described_class::INTERACTIONS['view_submission']
+
+        expect_next_instance_of(view_submission_service, params) do |service|
+          expect(service).to receive(:execute).and_return(ServiceResponse.success)
+        end
+
+        worker.perform(args)
+      end
+
+      it_behaves_like 'logs extra metadata on done'
+    end
 
     context 'when slack_interaction is not known' do
       let(:slack_interaction) { 'foo' }
 
-      it 'does not execute the service class' do
-        expect(service_class).not_to receive(:new)
+      it 'does not execute a service class' do
+        described_class::INTERACTIONS.each_value do |service_class|
+          expect(service_class).not_to receive(:new)
+        end
 
         worker.perform(args)
       end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index ca3b0449826f04ec5bb04b8fd1e7c25561e3427c..0256549ddbe2f347a6b9f2681f71ce774e70d044 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -27129,6 +27129,9 @@ msgstr ""
 msgid "New incident"
 msgstr ""
 
+msgid "New incident has been created"
+msgstr ""
+
 msgid "New issue"
 msgstr ""
 
@@ -38676,6 +38679,9 @@ msgstr ""
 msgid "Something went wrong when reordering designs. Please try again"
 msgstr ""
 
+msgid "Something went wrong when sending the incident link to Slack."
+msgstr ""
+
 msgid "Something went wrong while adding timeline event."
 msgstr ""
 
@@ -41497,6 +41503,9 @@ msgstr ""
 msgid "There was a problem communicating with your device."
 msgstr ""
 
+msgid "There was a problem creating the incident. Please try again."
+msgstr ""
+
 msgid "There was a problem fetching CRM contacts."
 msgstr ""
 
diff --git a/spec/services/chat_names/find_user_service_spec.rb b/spec/services/chat_names/find_user_service_spec.rb
index 4b0a12045587f24226d510871ef1124455a0f2ba..b65a76ca37c99171b8ddfcd032248ab5c1e0b6de 100644
--- a/spec/services/chat_names/find_user_service_spec.rb
+++ b/spec/services/chat_names/find_user_service_spec.rb
@@ -40,6 +40,14 @@
 
           expect(chat_name.reload.last_used_at).to eq(time)
         end
+
+        context 'when integration is not passed' do
+          it 'returns chat name' do
+            requested_chat_name = described_class.new(nil, params).execute
+
+            expect(requested_chat_name).to eq(chat_name)
+          end
+        end
       end
 
       context 'when different user is requested' do