diff --git a/ee/app/assets/javascripts/analytics/cycle_analytics/components/base.vue b/ee/app/assets/javascripts/analytics/cycle_analytics/components/base.vue
index cb8c44711c6aa58bda50ba6cb81551e648b5d74a..7bc4b05546fb72cdd9d39ae20c4eb41d4bc50130 100644
--- a/ee/app/assets/javascripts/analytics/cycle_analytics/components/base.vue
+++ b/ee/app/assets/javascripts/analytics/cycle_analytics/components/base.vue
@@ -73,7 +73,6 @@ export default {
       'selectedValueStream',
       'pagination',
       'aggregation',
-      'isCreatingAggregation',
       'groupPath',
       'features',
       'canEdit',
@@ -100,10 +99,10 @@ export default {
       return Boolean(this.selectedValueStream && !this.aggregation.lastRunAt);
     },
     shouldRenderEmptyState() {
-      return this.isLoadingValueStreams || (!this.isCreatingAggregation && !this.hasValueStreams);
+      return this.isLoadingValueStreams || !this.hasValueStreams;
     },
     shouldRenderAggregationWarning() {
-      return this.isCreatingAggregation || this.isWaitingForNextAggregation;
+      return this.isWaitingForNextAggregation;
     },
     shouldRenderStageTable() {
       return !this.isOverviewStageSelected && this.selectedStageEvents.length;
@@ -115,8 +114,7 @@ export default {
       return Boolean(
         this.enableCustomizableStages &&
           !this.shouldRenderEmptyState &&
-          !this.isLoadingValueStreams &&
-          !this.isCreatingAggregation,
+          !this.isLoadingValueStreams,
       );
     },
     hasDateRangeSet() {
diff --git a/ee/app/assets/javascripts/analytics/cycle_analytics/store/actions/value_streams.js b/ee/app/assets/javascripts/analytics/cycle_analytics/store/actions/value_streams.js
index 02c37750f8098e7bdf79c7099ba4ca3ed4b1d6ee..92d58e449f564d0a6a8411013c01a37edfee9f75 100644
--- a/ee/app/assets/javascripts/analytics/cycle_analytics/store/actions/value_streams.js
+++ b/ee/app/assets/javascripts/analytics/cycle_analytics/store/actions/value_streams.js
@@ -6,35 +6,24 @@ import {
 } from 'ee/api/analytics_api';
 import * as types from '../mutation_types';
 
-export const receiveCreateValueStreamSuccess = ({ commit }, valueStream = {}) => {
-  commit(types.RECEIVE_CREATE_VALUE_STREAM_SUCCESS, valueStream);
-  commit(types.SET_CREATING_AGGREGATION, true);
-};
-
-export const createValueStream = ({ commit, dispatch, getters }, data) => {
+export const createValueStream = ({ commit, getters }, data) => {
   const { namespaceRestApiRequestPath } = getters;
   commit(types.REQUEST_CREATE_VALUE_STREAM);
 
-  return apiCreateValueStream(namespaceRestApiRequestPath, data)
-    .then(({ data: newValueStream }) => dispatch('receiveCreateValueStreamSuccess', newValueStream))
-    .catch(({ response } = {}) => {
-      const { data: { message, payload: { errors } } = null } = response;
-      commit(types.RECEIVE_CREATE_VALUE_STREAM_ERROR, { message, errors, data });
-    });
+  return apiCreateValueStream(namespaceRestApiRequestPath, data).catch(({ response } = {}) => {
+    const { data: { message, payload: { errors } } = null } = response;
+    commit(types.RECEIVE_CREATE_VALUE_STREAM_ERROR, { message, errors, data });
+  });
 };
 
 export const updateValueStream = ({ commit, getters }, { id: valueStreamId, ...data }) => {
   const { namespaceRestApiRequestPath: namespacePath } = getters;
   commit(types.REQUEST_UPDATE_VALUE_STREAM);
 
-  return apiUpdateValueStream({ namespacePath, valueStreamId, data })
-    .then(({ data: newValueStream }) => {
-      return commit(types.RECEIVE_UPDATE_VALUE_STREAM_SUCCESS, newValueStream);
-    })
-    .catch(({ response } = {}) => {
-      const { data: { message, payload: { errors } } = null } = response;
-      commit(types.RECEIVE_UPDATE_VALUE_STREAM_ERROR, { message, errors, data });
-    });
+  return apiUpdateValueStream({ namespacePath, valueStreamId, data }).catch(({ response } = {}) => {
+    const { data: { message, payload: { errors } } = null } = response;
+    commit(types.RECEIVE_UPDATE_VALUE_STREAM_ERROR, { message, errors, data });
+  });
 };
 
 export const deleteValueStream = ({ commit, dispatch, getters }, valueStreamId) => {
diff --git a/ee/app/assets/javascripts/analytics/cycle_analytics/store/mutation_types.js b/ee/app/assets/javascripts/analytics/cycle_analytics/store/mutation_types.js
index 22768a25223cad936bf538a1bbd9ed5f96ddb1ce..502ff65c703ce302095fcccf218c3a6da6a27b13 100644
--- a/ee/app/assets/javascripts/analytics/cycle_analytics/store/mutation_types.js
+++ b/ee/app/assets/javascripts/analytics/cycle_analytics/store/mutation_types.js
@@ -7,7 +7,6 @@ export const SET_PREDEFINED_DATE_RANGE = 'SET_PREDEFINED_DATE_RANGE';
 export const SET_SELECTED_VALUE_STREAM = 'SET_SELECTED_VALUE_STREAM';
 export const SET_PAGINATION = 'SET_PAGINATION';
 export const SET_STAGE_EVENTS = 'SET_STAGE_EVENTS';
-export const SET_CREATING_AGGREGATION = 'SET_CREATING_AGGREGATION';
 
 export const REQUEST_VALUE_STREAM_DATA = 'REQUEST_VALUE_STREAM_DATA';
 export const RECEIVE_VALUE_STREAM_DATA_SUCCESS = 'RECEIVE_VALUE_STREAM_DATA_SUCCESS';
@@ -37,11 +36,9 @@ export const INITIALIZE_VSA = 'INITIALIZE_VSA';
 export const INITIALIZE_VALUE_STREAM_SUCCESS = 'INITIALIZE_VALUE_STREAM_SUCCESS';
 
 export const REQUEST_CREATE_VALUE_STREAM = 'REQUEST_CREATE_VALUE_STREAM';
-export const RECEIVE_CREATE_VALUE_STREAM_SUCCESS = 'RECEIVE_CREATE_VALUE_STREAM_SUCCESS';
 export const RECEIVE_CREATE_VALUE_STREAM_ERROR = 'RECEIVE_CREATE_VALUE_STREAM_ERROR';
 
 export const REQUEST_UPDATE_VALUE_STREAM = 'REQUEST_UPDATE_VALUE_STREAM';
-export const RECEIVE_UPDATE_VALUE_STREAM_SUCCESS = 'RECEIVE_UPDATE_VALUE_STREAM_SUCCESS';
 export const RECEIVE_UPDATE_VALUE_STREAM_ERROR = 'RECEIVE_UPDATE_VALUE_STREAM_ERROR';
 
 export const REQUEST_DELETE_VALUE_STREAM = 'REQUEST_DELETE_VALUE_STREAM';
diff --git a/ee/app/assets/javascripts/analytics/cycle_analytics/store/mutations.js b/ee/app/assets/javascripts/analytics/cycle_analytics/store/mutations.js
index c3b4d556e0432e6e187275f8484d2ca06b539818..e3e57e1b55b335629394b1bf1a269fc352dd317d 100644
--- a/ee/app/assets/javascripts/analytics/cycle_analytics/store/mutations.js
+++ b/ee/app/assets/javascripts/analytics/cycle_analytics/store/mutations.js
@@ -150,35 +150,18 @@ export default {
     state.isLoading = false;
   },
   [types.REQUEST_CREATE_VALUE_STREAM](state) {
-    state.isCreatingValueStream = true;
     state.createValueStreamErrors = {};
   },
   [types.RECEIVE_CREATE_VALUE_STREAM_ERROR](state, { data: { stages = [] }, errors = {} }) {
     const { stages: stageErrors = {}, ...rest } = errors;
     state.createValueStreamErrors = { ...rest, stages: prepareStageErrors(stages, stageErrors) };
-    state.isCreatingValueStream = false;
-  },
-  [types.RECEIVE_CREATE_VALUE_STREAM_SUCCESS](state, valueStream = {}) {
-    state.isCreatingValueStream = false;
-    state.createValueStreamErrors = {};
-    state.selectedValueStream = convertObjectPropsToCamelCase(valueStream, { deep: true });
-
-    const { stages = [] } = valueStream;
-    state.stages = transformRawStages(stages);
   },
   [types.REQUEST_UPDATE_VALUE_STREAM](state) {
-    state.isEditingValueStream = true;
     state.createValueStreamErrors = {};
   },
   [types.RECEIVE_UPDATE_VALUE_STREAM_ERROR](state, { data: { stages = [] }, errors = {} }) {
     const { stages: stageErrors = {}, ...rest } = errors;
     state.createValueStreamErrors = { ...rest, stages: prepareStageErrors(stages, stageErrors) };
-    state.isEditingValueStream = false;
-  },
-  [types.RECEIVE_UPDATE_VALUE_STREAM_SUCCESS](state, valueStream) {
-    state.isEditingValueStream = false;
-    state.createValueStreamErrors = {};
-    state.selectedValueStream = convertObjectPropsToCamelCase(valueStream, { deep: true });
   },
   [types.REQUEST_DELETE_VALUE_STREAM](state) {
     state.isDeletingValueStream = true;
@@ -222,7 +205,4 @@ export default {
       direction: direction || PAGINATION_SORT_DIRECTION_DESC,
     };
   },
-  [types.SET_CREATING_AGGREGATION](state, value) {
-    state.isCreatingAggregation = value;
-  },
 };
diff --git a/ee/app/assets/javascripts/analytics/cycle_analytics/store/state.js b/ee/app/assets/javascripts/analytics/cycle_analytics/store/state.js
index 37916446dc894c890c738862c933f076d9d0e471..98fe4c59f0d05a0e864e30fba5e33483a3e62110 100644
--- a/ee/app/assets/javascripts/analytics/cycle_analytics/store/state.js
+++ b/ee/app/assets/javascripts/analytics/cycle_analytics/store/state.js
@@ -26,11 +26,8 @@ export default () => ({
   selectedStageEvents: [],
 
   isLoadingValueStreams: false,
-  isCreatingValueStream: false,
-  isEditingValueStream: false,
   isDeletingValueStream: false,
   isFetchingGroupLabels: false,
-  isCreatingAggregation: false,
   isFetchingGroupStagesAndEvents: false,
 
   createValueStreamErrors: {},
diff --git a/ee/app/assets/javascripts/analytics/cycle_analytics/vsa_settings/components/value_stream_form.stories.js b/ee/app/assets/javascripts/analytics/cycle_analytics/vsa_settings/components/value_stream_form.stories.js
index 5c3b665a29ebd7682225ad7840952a74a24724d8..b5248877a560bc9eceba7f08eb5e136a678b201f 100644
--- a/ee/app/assets/javascripts/analytics/cycle_analytics/vsa_settings/components/value_stream_form.stories.js
+++ b/ee/app/assets/javascripts/analytics/cycle_analytics/vsa_settings/components/value_stream_form.stories.js
@@ -78,27 +78,6 @@ export const EditValueStreamWithHiddenStages = {
   },
 };
 
-export const SavingNewValueStream = {
-  render: createStoryWithState({
-    state: {
-      isCreatingValueStream: true,
-    },
-  }),
-};
-
-export const UpdatingValueStream = {
-  render: createStoryWithState({
-    state: {
-      selectedValueStream,
-      stages: selectedValueStreamStages(),
-      isEditingValueStream: true,
-    },
-  }),
-  args: {
-    isEditing: true,
-  },
-};
-
 export const WithFormSubmissionErrors = {
   render: createStoryWithState({
     state: {
diff --git a/ee/app/assets/javascripts/analytics/cycle_analytics/vsa_settings/components/value_stream_form.vue b/ee/app/assets/javascripts/analytics/cycle_analytics/vsa_settings/components/value_stream_form.vue
index e2b68c970837ef8244e62da2f2215931cf9ad955..070f14e91c886eb024a8608ca7ec8dc62d88cb63 100644
--- a/ee/app/assets/javascripts/analytics/cycle_analytics/vsa_settings/components/value_stream_form.vue
+++ b/ee/app/assets/javascripts/analytics/cycle_analytics/vsa_settings/components/value_stream_form.vue
@@ -2,7 +2,6 @@
 import { GlLoadingIcon } from '@gitlab/ui';
 // eslint-disable-next-line no-restricted-imports
 import { mapState, mapActions } from 'vuex';
-import { mergeUrlParams } from '~/lib/utils/url_utility';
 import { generateInitialStageData } from '../utils';
 import ValueStreamFormContent from './value_stream_form_content.vue';
 
@@ -12,11 +11,6 @@ export default {
     ValueStreamFormContent,
     GlLoadingIcon,
   },
-  inject: {
-    vsaPath: {
-      default: null,
-    },
-  },
   props: {
     isEditing: {
       type: Boolean,
@@ -25,44 +19,29 @@ export default {
     },
   },
   computed: {
-    ...mapState({
-      selectedValueStream: 'selectedValueStream',
-      selectedValueStreamStages: 'stages',
-      initialFormErrors: 'createValueStreamErrors',
-      defaultStageConfig: 'defaultStageConfig',
-      defaultGroupLabels: 'defaultGroupLabels',
-      isFetchingGroupStagesAndEvents: 'isFetchingGroupStagesAndEvents',
-      isFetchingGroupLabels: 'isFetchingGroupLabels',
-      isValueStreamLoading: 'isLoading',
-    }),
-    isLoading() {
-      return (
-        this.isValueStreamLoading ||
-        this.isFetchingGroupLabels ||
-        this.isFetchingGroupStagesAndEvents
-      );
+    ...mapState([
+      'selectedValueStream',
+      'stages',
+      'defaultStageConfig',
+      'defaultGroupLabels',
+      'isFetchingGroupStagesAndEvents',
+      'isFetchingGroupLabels',
+      'isLoading',
+    ]),
+    isLoadingOrFetching() {
+      return this.isLoading || this.isFetchingGroupLabels || this.isFetchingGroupStagesAndEvents;
     },
     initialData() {
       return this.isEditing
         ? {
             ...this.selectedValueStream,
-            stages: generateInitialStageData(
-              this.defaultStageConfig,
-              this.selectedValueStreamStages,
-            ),
+            stages: generateInitialStageData(this.defaultStageConfig, this.stages),
           }
         : {
             name: '',
             stages: [],
           };
     },
-    valueStreamPath() {
-      const { selectedValueStream, vsaPath } = this;
-
-      return selectedValueStream
-        ? mergeUrlParams({ value_stream_id: selectedValueStream.id }, vsaPath)
-        : vsaPath;
-    },
   },
   created() {
     if (!this.defaultGroupLabels) {
@@ -76,16 +55,14 @@ export default {
 </script>
 <template>
   <div>
-    <div v-if="isLoading" class="gl-pt-7 gl-text-center">
+    <div v-if="isLoadingOrFetching" class="gl-pt-7 gl-text-center">
       <gl-loading-icon size="lg" />
     </div>
     <value-stream-form-content
       v-else
       :initial-data="initialData"
-      :initial-form-errors="initialFormErrors"
       :default-stage-config="defaultStageConfig"
       :is-editing="isEditing"
-      :value-stream-path="valueStreamPath"
     />
   </div>
 </template>
diff --git a/ee/app/assets/javascripts/analytics/cycle_analytics/vsa_settings/components/value_stream_form_content.vue b/ee/app/assets/javascripts/analytics/cycle_analytics/vsa_settings/components/value_stream_form_content.vue
index 11e4b2b3f2bab2b50a6bc5a42259844c50fd68c8..1c03c1198f5df2e853fe348cab7437b7af6e7011 100644
--- a/ee/app/assets/javascripts/analytics/cycle_analytics/vsa_settings/components/value_stream_form_content.vue
+++ b/ee/app/assets/javascripts/analytics/cycle_analytics/vsa_settings/components/value_stream_form_content.vue
@@ -7,7 +7,7 @@ import { filterStagesByHiddenStatus } from '~/analytics/cycle_analytics/utils';
 import { swapArrayItems } from '~/lib/utils/array_utility';
 import { sprintf } from '~/locale';
 import Tracking from '~/tracking';
-import { visitUrlWithAlerts } from '~/lib/utils/url_utility';
+import { visitUrlWithAlerts, mergeUrlParams } from '~/lib/utils/url_utility';
 import { getLabelEventsIdentifiers } from 'ee/analytics/cycle_analytics/utils';
 import {
   validateValueStreamName,
@@ -59,22 +59,13 @@ export default {
     ValueStreamFormContentActions,
   },
   mixins: [Tracking.mixin()],
+  inject: ['vsaPath'],
   props: {
     initialData: {
       type: Object,
       required: false,
       default: () => ({}),
     },
-    initialPreset: {
-      type: String,
-      required: false,
-      default: PRESET_OPTIONS_DEFAULT,
-    },
-    initialFormErrors: {
-      type: Object,
-      required: false,
-      default: () => ({}),
-    },
     defaultStageConfig: {
       type: Array,
       required: true,
@@ -84,60 +75,44 @@ export default {
       required: false,
       default: false,
     },
-    valueStreamPath: {
-      type: String,
-      required: true,
-    },
   },
   data() {
     const {
       defaultStageConfig = [],
       initialData: { name: initialName, stages: initialStages = [] },
-      initialFormErrors,
-      initialPreset,
     } = this;
-    const { name: nameErrors = [], stages: stageErrors = [{}] } = initialFormErrors;
-    const additionalFields = {
-      stages: this.isEditing
-        ? initializeEditingStages(initialStages)
-        : initializeStages(defaultStageConfig, initialPreset),
-      stageErrors:
-        cloneDeep(stageErrors) || initializeStageErrors(defaultStageConfig, initialPreset),
-    };
 
     return {
       hiddenStages: filterStagesByHiddenStatus(initialStages),
-      selectedPreset: initialPreset,
+      selectedPreset: PRESET_OPTIONS_DEFAULT,
       presetOptions: PRESET_OPTIONS,
       name: initialName,
-      nameErrors,
-      stageErrors,
+      nameErrors: [],
+      stageErrors: [{}],
       showSubmitError: false,
-      isRedirecting: false,
-      ...additionalFields,
+      isSubmitting: false,
+      stages: this.isEditing
+        ? initializeEditingStages(initialStages)
+        : initializeStages(defaultStageConfig),
     };
   },
   computed: {
-    ...mapState({
-      isCreating: 'isCreatingValueStream',
-      isSaving: 'isEditingValueStream',
-      isFetchingGroupLabels: 'isFetchingGroupLabels',
-      formEvents: 'formEvents',
-      defaultGroupLabels: 'defaultGroupLabels',
-    }),
+    ...mapState([
+      'isFetchingGroupLabels',
+      'formEvents',
+      'defaultGroupLabels',
+      'createValueStreamErrors',
+      'selectedValueStream',
+    ]),
+    selectedValueStreamId() {
+      return this.selectedValueStream?.id || -1;
+    },
     isValueStreamNameValid() {
       return !this.nameErrors?.length;
     },
     invalidNameFeedback() {
       return this.nameErrors?.length ? this.nameErrors.join('\n\n') : null;
     },
-    hasInitialFormErrors() {
-      const { initialFormErrors } = this;
-      return Boolean(Object.keys(initialFormErrors).length);
-    },
-    isSubmitting() {
-      return this.isCreating || this.isSaving;
-    },
     hasFormErrors() {
       return Boolean(
         this.nameErrors.length || this.stageErrors.some((obj) => Object.keys(obj).length),
@@ -168,12 +143,18 @@ export default {
       return { id, message, variant: 'success' };
     },
   },
+  watch: {
+    createValueStreamErrors: 'refreshErrors',
+  },
+  created() {
+    this.refreshErrors();
+  },
   methods: {
     ...mapActions(['createValueStream', 'updateValueStream']),
-    onSubmit() {
+    async onSubmit() {
       this.showSubmitError = false;
       this.validate();
-      if (this.hasFormErrors) return false;
+      if (this.hasFormErrors) return;
 
       let req = this.createValueStream;
       let params = {
@@ -188,27 +169,22 @@ export default {
         };
       }
 
-      return req(params).then(() => {
-        if (this.hasInitialFormErrors) {
-          const { name: nameErrors = [], stages: stageErrors = [{}] } = this.initialFormErrors;
+      this.isSubmitting = true;
 
-          this.isRedirecting = false;
-          this.nameErrors = nameErrors;
-          this.stageErrors = stageErrors;
-          this.showSubmitError = true;
+      const response = await req(params);
 
-          return;
-        }
-
-        this.nameErrors = [];
-        this.stageErrors = initializeStageErrors(this.defaultStageConfig, this.selectedPreset);
-        this.track('submit_form', {
-          label: this.isEditing ? 'edit_value_stream' : 'create_value_stream',
-        });
-        this.isRedirecting = true;
+      if (this.hasFormErrors) {
+        this.isSubmitting = false;
+        this.showSubmitError = true;
+        return;
+      }
 
-        visitUrlWithAlerts(this.valueStreamPath, [this.submissionSuccessfulAlert]);
+      this.track('submit_form', {
+        label: this.isEditing ? 'edit_value_stream' : 'create_value_stream',
       });
+
+      const redirectPath = mergeUrlParams({ value_stream_id: response.data.id }, this.vsaPath);
+      visitUrlWithAlerts(redirectPath, [this.submissionSuccessfulAlert]);
     },
     stageGroupLabel(index) {
       return sprintf(this.$options.i18n.STAGE_INDEX, { index: index + 1 });
@@ -228,6 +204,13 @@ export default {
         }),
       );
     },
+    refreshErrors() {
+      const { defaultStageConfig, selectedPreset, createValueStreamErrors = {} } = this;
+      const { name = [], stages = [{}] } = createValueStreamErrors;
+      this.nameErrors = name;
+      this.stageErrors =
+        cloneDeep(stages) || initializeStageErrors(defaultStageConfig, selectedPreset);
+    },
     validate() {
       const { name } = this;
       this.nameErrors = validateValueStreamName({ name });
@@ -437,8 +420,8 @@ export default {
           <hr class="gl-mb-5 gl-mt-2" />
           <value-stream-form-content-actions
             :is-editing="isEditing"
-            :is-loading="isSubmitting || isRedirecting"
-            :value-stream-path="valueStreamPath"
+            :is-loading="isSubmitting"
+            :value-stream-id="selectedValueStreamId"
             @clickPrimaryAction="onSubmit"
             @clickAddStageAction="onAddStage"
           />
diff --git a/ee/app/assets/javascripts/analytics/cycle_analytics/vsa_settings/components/value_stream_form_content_actions.vue b/ee/app/assets/javascripts/analytics/cycle_analytics/vsa_settings/components/value_stream_form_content_actions.vue
index 945fd094e43f47fc54aa40f499af907dd5782f86..9cf398cc8920b8afa44d708d9eb51e9b44b3c439 100644
--- a/ee/app/assets/javascripts/analytics/cycle_analytics/vsa_settings/components/value_stream_form_content_actions.vue
+++ b/ee/app/assets/javascripts/analytics/cycle_analytics/vsa_settings/components/value_stream_form_content_actions.vue
@@ -1,5 +1,6 @@
 <script>
 import { GlButton } from '@gitlab/ui';
+import { mergeUrlParams } from '~/lib/utils/url_utility';
 import { __ } from '~/locale';
 import { i18n } from '../constants';
 
@@ -10,22 +11,23 @@ export default {
   components: {
     GlButton,
   },
+  inject: ['vsaPath'],
   props: {
     isEditing: {
       type: Boolean,
       required: false,
       default: false,
     },
+    valueStreamId: {
+      type: Number,
+      required: false,
+      default: -1,
+    },
     isLoading: {
       type: Boolean,
       required: false,
       default: false,
     },
-    valueStreamPath: {
-      type: String,
-      required: false,
-      default: null,
-    },
   },
   i18n: {
     newValueStreamAction: FORM_TITLE,
@@ -39,6 +41,11 @@ export default {
         ? this.$options.i18n.saveValueStreamAction
         : this.$options.i18n.newValueStreamAction;
     },
+    cancelHref() {
+      return this.isEditing && this.valueStreamId > 0
+        ? mergeUrlParams({ value_stream_id: this.valueStreamId }, this.vsaPath)
+        : this.vsaPath;
+    },
   },
 };
 </script>
@@ -60,7 +67,7 @@ export default {
       @click="$emit('clickAddStageAction')"
       >{{ $options.i18n.addStageAction }}</gl-button
     >
-    <gl-button data-testid="cancel-button" :href="valueStreamPath" :disabled="isLoading">{{
+    <gl-button data-testid="cancel-button" :href="cancelHref" :disabled="isLoading">{{
       $options.i18n.cancelAction
     }}</gl-button>
   </div>
diff --git a/ee/spec/frontend/analytics/cycle_analytics/components/value_stream_select_spec.js b/ee/spec/frontend/analytics/cycle_analytics/components/value_stream_select_spec.js
index df33e2e31cf342ca8b72c64a9204b2d2536a226a..a0c05ecf58bcdc35bdff7f92b91b8f9b10e5eb4a 100644
--- a/ee/spec/frontend/analytics/cycle_analytics/components/value_stream_select_spec.js
+++ b/ee/spec/frontend/analytics/cycle_analytics/components/value_stream_select_spec.js
@@ -35,7 +35,6 @@ describe('ValueStreamSelect', () => {
   const fakeStore = ({ initialState = {} }) =>
     new Vuex.Store({
       state: {
-        isCreatingValueStream: false,
         isDeletingValueStream: false,
         createValueStreamErrors: {},
         deleteValueStreamError: null,
diff --git a/ee/spec/frontend/analytics/cycle_analytics/store/actions/value_streams_spec.js b/ee/spec/frontend/analytics/cycle_analytics/store/actions/value_streams_spec.js
index 420f391f56cda85d7677ddd8f07d42ab7da563d2..fb111a343875c766c3907e4881ed585c9c09c491 100644
--- a/ee/spec/frontend/analytics/cycle_analytics/store/actions/value_streams_spec.js
+++ b/ee/spec/frontend/analytics/cycle_analytics/store/actions/value_streams_spec.js
@@ -85,18 +85,12 @@ describe('Value Stream Analytics actions / value streams', () => {
         mock.onPost(endpoints.valueStreamData).replyOnce(HTTP_STATUS_OK, createResp);
       });
 
-      it(`commits the ${types.REQUEST_CREATE_VALUE_STREAM} and ${types.RECEIVE_CREATE_VALUE_STREAM_SUCCESS} actions`, () => {
-        return testAction(
-          actions.createValueStream,
-          payload,
-          state,
-          [
-            {
-              type: types.REQUEST_CREATE_VALUE_STREAM,
-            },
-          ],
-          [{ type: 'receiveCreateValueStreamSuccess', payload: createResp }],
-        );
+      it(`commits ${types.REQUEST_CREATE_VALUE_STREAM}`, () => {
+        return testAction(actions.createValueStream, payload, state, [
+          {
+            type: types.REQUEST_CREATE_VALUE_STREAM,
+          },
+        ]);
       });
     });
 
@@ -126,24 +120,6 @@ describe('Value Stream Analytics actions / value streams', () => {
     });
   });
 
-  describe('receiveCreateValueStreamSuccess', () => {
-    beforeEach(() => {
-      state = { ...state, valueStream: {} };
-    });
-
-    it(`will dispatch the "fetchCycleAnalyticsData" action and commit the ${types.RECEIVE_CREATE_VALUE_STREAM_SUCCESS} mutation`, () => {
-      return testAction({
-        action: actions.receiveCreateValueStreamSuccess,
-        payload: selectedValueStream,
-        state,
-        expectedMutations: [
-          { type: types.RECEIVE_CREATE_VALUE_STREAM_SUCCESS, payload: selectedValueStream },
-          { type: types.SET_CREATING_AGGREGATION, payload: true },
-        ],
-      });
-    });
-  });
-
   describe('updateValueStream', () => {
     const payload = {
       name: 'cool value stream',
@@ -164,10 +140,9 @@ describe('Value Stream Analytics actions / value streams', () => {
         mock.onPut(endpoints.valueStreamData).replyOnce(HTTP_STATUS_OK, updateResp);
       });
 
-      it(`commits the ${types.REQUEST_UPDATE_VALUE_STREAM} and ${types.RECEIVE_UPDATE_VALUE_STREAM_SUCCESS} mutations`, () => {
+      it(`commits the ${types.REQUEST_UPDATE_VALUE_STREAM} mutation`, () => {
         return testAction(actions.updateValueStream, payload, state, [
           { type: types.REQUEST_UPDATE_VALUE_STREAM },
-          { type: types.RECEIVE_UPDATE_VALUE_STREAM_SUCCESS, payload: updateResp },
         ]);
       });
     });
diff --git a/ee/spec/frontend/analytics/cycle_analytics/store/mutations_spec.js b/ee/spec/frontend/analytics/cycle_analytics/store/mutations_spec.js
index 9ecefaaee511296092f249b543fc8edeacd65c8b..37ecab58eaf3f1d6d64b5f600d5ebc0a9ad37bf9 100644
--- a/ee/spec/frontend/analytics/cycle_analytics/store/mutations_spec.js
+++ b/ee/spec/frontend/analytics/cycle_analytics/store/mutations_spec.js
@@ -53,14 +53,8 @@ describe('Value Stream Analytics mutations', () => {
     ${types.REQUEST_GROUP_STAGES}                | ${'stages'}                  | ${[]}
     ${types.REQUEST_STAGE_MEDIANS}               | ${'medians'}                 | ${{}}
     ${types.RECEIVE_STAGE_MEDIANS_ERROR}         | ${'medians'}                 | ${{}}
-    ${types.REQUEST_CREATE_VALUE_STREAM}         | ${'isCreatingValueStream'}   | ${true}
-    ${types.RECEIVE_CREATE_VALUE_STREAM_SUCCESS} | ${'isCreatingValueStream'}   | ${false}
     ${types.REQUEST_CREATE_VALUE_STREAM}         | ${'createValueStreamErrors'} | ${{}}
-    ${types.RECEIVE_CREATE_VALUE_STREAM_SUCCESS} | ${'createValueStreamErrors'} | ${{}}
-    ${types.REQUEST_UPDATE_VALUE_STREAM}         | ${'isEditingValueStream'}    | ${true}
-    ${types.RECEIVE_UPDATE_VALUE_STREAM_SUCCESS} | ${'isEditingValueStream'}    | ${false}
     ${types.REQUEST_UPDATE_VALUE_STREAM}         | ${'createValueStreamErrors'} | ${{}}
-    ${types.RECEIVE_UPDATE_VALUE_STREAM_SUCCESS} | ${'createValueStreamErrors'} | ${{}}
     ${types.REQUEST_DELETE_VALUE_STREAM}         | ${'isDeletingValueStream'}   | ${true}
     ${types.RECEIVE_DELETE_VALUE_STREAM_SUCCESS} | ${'isDeletingValueStream'}   | ${false}
     ${types.REQUEST_DELETE_VALUE_STREAM}         | ${'deleteValueStreamError'}  | ${null}
@@ -95,22 +89,20 @@ describe('Value Stream Analytics mutations', () => {
   const pagination = { page: 10, hasNextPage: true, sort: null, direction: null };
 
   it.each`
-    mutation                                     | payload                                                  | expectedState
-    ${types.SET_SELECTED_PROJECTS}               | ${selectedProjects}                                      | ${{ selectedProjects }}
-    ${types.SET_DATE_RANGE}                      | ${{ createdAfter, createdBefore }}                       | ${{ createdAfter, createdBefore }}
-    ${types.SET_PREDEFINED_DATE_RANGE}           | ${predefinedDateRange}                                   | ${{ predefinedDateRange }}
-    ${types.SET_SELECTED_STAGE}                  | ${{ id: 'first-stage' }}                                 | ${{ selectedStage: { id: 'first-stage' } }}
-    ${types.RECEIVE_CREATE_VALUE_STREAM_ERROR}   | ${valueStreamErrors}                                     | ${{ createValueStreamErrors: expectedValueStreamErrors, isCreatingValueStream: false }}
-    ${types.RECEIVE_UPDATE_VALUE_STREAM_ERROR}   | ${valueStreamErrors}                                     | ${{ createValueStreamErrors: expectedValueStreamErrors, isEditingValueStream: false }}
-    ${types.RECEIVE_DELETE_VALUE_STREAM_ERROR}   | ${'Some error occurred'}                                 | ${{ deleteValueStreamError: 'Some error occurred' }}
-    ${types.RECEIVE_VALUE_STREAMS_SUCCESS}       | ${valueStreams}                                          | ${{ valueStreams, isLoadingValueStreams: false }}
-    ${types.SET_SELECTED_VALUE_STREAM}           | ${valueStreams[1].id}                                    | ${{ selectedValueStream: {} }}
-    ${types.RECEIVE_CREATE_VALUE_STREAM_SUCCESS} | ${valueStreams[1]}                                       | ${{ selectedValueStream: valueStreams[1] }}
-    ${types.RECEIVE_UPDATE_VALUE_STREAM_SUCCESS} | ${valueStreams[1]}                                       | ${{ selectedValueStream: valueStreams[1] }}
-    ${types.RECEIVE_GROUP_LABELS_SUCCESS}        | ${groupLabels}                                           | ${{ defaultGroupLabels: groupLabels }}
-    ${types.SET_PAGINATION}                      | ${pagination}                                            | ${{ pagination: { ...pagination, sort: PAGINATION_SORT_FIELD_DURATION, direction: PAGINATION_SORT_DIRECTION_DESC } }}
-    ${types.SET_PAGINATION}                      | ${{ ...pagination, sort: 'duration', direction: 'asc' }} | ${{ pagination: { ...pagination, sort: 'duration', direction: 'asc' } }}
-    ${types.SET_STAGE_EVENTS}                    | ${rawCustomStageEvents}                                  | ${{ formEvents: camelCasedStageEvents }}
+    mutation                                   | payload                                                  | expectedState
+    ${types.SET_SELECTED_PROJECTS}             | ${selectedProjects}                                      | ${{ selectedProjects }}
+    ${types.SET_DATE_RANGE}                    | ${{ createdAfter, createdBefore }}                       | ${{ createdAfter, createdBefore }}
+    ${types.SET_PREDEFINED_DATE_RANGE}         | ${predefinedDateRange}                                   | ${{ predefinedDateRange }}
+    ${types.SET_SELECTED_STAGE}                | ${{ id: 'first-stage' }}                                 | ${{ selectedStage: { id: 'first-stage' } }}
+    ${types.RECEIVE_CREATE_VALUE_STREAM_ERROR} | ${valueStreamErrors}                                     | ${{ createValueStreamErrors: expectedValueStreamErrors }}
+    ${types.RECEIVE_UPDATE_VALUE_STREAM_ERROR} | ${valueStreamErrors}                                     | ${{ createValueStreamErrors: expectedValueStreamErrors }}
+    ${types.RECEIVE_DELETE_VALUE_STREAM_ERROR} | ${'Some error occurred'}                                 | ${{ deleteValueStreamError: 'Some error occurred' }}
+    ${types.RECEIVE_VALUE_STREAMS_SUCCESS}     | ${valueStreams}                                          | ${{ valueStreams, isLoadingValueStreams: false }}
+    ${types.SET_SELECTED_VALUE_STREAM}         | ${valueStreams[1].id}                                    | ${{ selectedValueStream: {} }}
+    ${types.RECEIVE_GROUP_LABELS_SUCCESS}      | ${groupLabels}                                           | ${{ defaultGroupLabels: groupLabels }}
+    ${types.SET_PAGINATION}                    | ${pagination}                                            | ${{ pagination: { ...pagination, sort: PAGINATION_SORT_FIELD_DURATION, direction: PAGINATION_SORT_DIRECTION_DESC } }}
+    ${types.SET_PAGINATION}                    | ${{ ...pagination, sort: 'duration', direction: 'asc' }} | ${{ pagination: { ...pagination, sort: 'duration', direction: 'asc' } }}
+    ${types.SET_STAGE_EVENTS}                  | ${rawCustomStageEvents}                                  | ${{ formEvents: camelCasedStageEvents }}
   `(
     '$mutation with payload $payload will update state with $expectedState',
     ({ mutation, payload, expectedState }) => {
diff --git a/ee/spec/frontend/analytics/cycle_analytics/vsa_settings/components/value_stream_form_content_actions_spec.js b/ee/spec/frontend/analytics/cycle_analytics/vsa_settings/components/value_stream_form_content_actions_spec.js
index 63fbb36f6a4dd9caa68468dd6769a3b5c857287a..8fbb8f30648036d1e9d734ab892bc42519f48ea1 100644
--- a/ee/spec/frontend/analytics/cycle_analytics/vsa_settings/components/value_stream_form_content_actions_spec.js
+++ b/ee/spec/frontend/analytics/cycle_analytics/vsa_settings/components/value_stream_form_content_actions_spec.js
@@ -1,79 +1,84 @@
-import ValueStreamFormContentHeader from 'ee/analytics/cycle_analytics/vsa_settings/components/value_stream_form_content_actions.vue';
+import ValueStreamFormContentActions from 'ee/analytics/cycle_analytics/vsa_settings/components/value_stream_form_content_actions.vue';
 import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
-import { valueStreamPath } from '../../mock_data';
 
 describe('ValueStreamFormContentActions', () => {
+  const vsaPath = '/mockVsaPath/test';
+
   let wrapper;
 
   const findPrimaryBtn = () => wrapper.findByTestId('primary-button');
-  const findValueStreamCancelBtn = () => wrapper.findByTestId('cancel-button');
+  const findCancelBtn = () => wrapper.findByTestId('cancel-button');
   const findAddStageBtn = () => wrapper.findByTestId('add-button');
 
   const createComponent = ({ props = {} } = {}) => {
-    wrapper = shallowMountExtended(ValueStreamFormContentHeader, {
+    wrapper = shallowMountExtended(ValueStreamFormContentActions, {
+      provide: { vsaPath },
       propsData: {
-        valueStreamPath,
         ...props,
       },
     });
   };
 
   describe.each`
-    isEditing | text
-    ${false}  | ${'New value stream'}
-    ${true}   | ${'Save value stream'}
-  `('when `isEditing` is `$isEditing`', ({ isEditing, text }) => {
-    beforeEach(() => {
-      createComponent({ props: { isEditing } });
-    });
-
-    it('renders primary action correctly', () => {
-      expect(findPrimaryBtn().text()).toBe(text);
-      expect(findPrimaryBtn().props()).toMatchObject({
-        variant: 'confirm',
-        loading: false,
-        disabled: false,
+    isEditing | valueStreamId | text                   | cancelHref
+    ${false}  | ${-1}         | ${'New value stream'}  | ${vsaPath}
+    ${true}   | ${-1}         | ${'Save value stream'} | ${vsaPath}
+    ${true}   | ${13}         | ${'Save value stream'} | ${`/mockVsaPath/test?value_stream_id=13`}
+  `(
+    'when `valueStreamId` is `$valueStreamId`',
+    ({ isEditing, valueStreamId, text, cancelHref }) => {
+      beforeEach(() => {
+        createComponent({ props: { valueStreamId, isEditing } });
       });
-    });
 
-    it('emits `clickPrimaryAction` event when primary action is selected', () => {
-      findPrimaryBtn().vm.$emit('click');
+      it('renders primary action correctly', () => {
+        expect(findPrimaryBtn().text()).toBe(text);
+        expect(findPrimaryBtn().props()).toMatchObject({
+          variant: 'confirm',
+          loading: false,
+          disabled: false,
+        });
+      });
 
-      expect(wrapper.emitted('clickPrimaryAction')).toHaveLength(1);
-    });
+      it('emits `clickPrimaryAction` event when primary action is selected', () => {
+        findPrimaryBtn().vm.$emit('click');
 
-    it('renders add stage action correctly', () => {
-      expect(findAddStageBtn().props()).toMatchObject({
-        category: 'secondary',
-        variant: 'confirm',
-        disabled: false,
+        expect(wrapper.emitted('clickPrimaryAction')).toHaveLength(1);
       });
-    });
 
-    it('emits `clickAddStageAction` event when add stage action is selected', () => {
-      findAddStageBtn().vm.$emit('click');
-
-      expect(wrapper.emitted('clickAddStageAction')).toHaveLength(1);
-    });
+      it('renders add stage action correctly', () => {
+        expect(findAddStageBtn().props()).toMatchObject({
+          category: 'secondary',
+          variant: 'confirm',
+          disabled: false,
+        });
+      });
 
-    it('renders cancel button link correctly', () => {
-      expect(findValueStreamCancelBtn().props('disabled')).toBe(false);
-      expect(findValueStreamCancelBtn().attributes('href')).toBe(valueStreamPath);
-    });
+      it('emits `clickAddStageAction` event when add stage action is selected', () => {
+        findAddStageBtn().vm.$emit('click');
 
-    describe('isLoading=true', () => {
-      beforeEach(() => {
-        createComponent({ props: { isEditing, isLoading: true } });
+        expect(wrapper.emitted('clickAddStageAction')).toHaveLength(1);
       });
 
-      it('sets primary action to a loading state', () => {
-        expect(findPrimaryBtn().props('loading')).toBe(true);
+      it('renders cancel button link correctly', () => {
+        expect(findCancelBtn().props('disabled')).toBe(false);
+        expect(findCancelBtn().attributes('href')).toBe(cancelHref);
       });
 
-      it('disables all other actions', () => {
-        expect(findAddStageBtn().props('disabled')).toBe(true);
-        expect(findValueStreamCancelBtn().props('disabled')).toBe(true);
+      describe('isLoading=true', () => {
+        beforeEach(() => {
+          createComponent({ props: { valueStreamId, isEditing, isLoading: true } });
+        });
+
+        it('sets primary action to a loading state', () => {
+          expect(findPrimaryBtn().props('loading')).toBe(true);
+        });
+
+        it('disables all other actions', () => {
+          expect(findAddStageBtn().props('disabled')).toBe(true);
+          expect(findCancelBtn().props('disabled')).toBe(true);
+        });
       });
-    });
-  });
+    },
+  );
 });
diff --git a/ee/spec/frontend/analytics/cycle_analytics/vsa_settings/components/value_stream_form_content_spec.js b/ee/spec/frontend/analytics/cycle_analytics/vsa_settings/components/value_stream_form_content_spec.js
index 79c5b6a3ca04b664872e4b44ef9facd3781bbf68..ac9bbc619bec58e0c5c85448f2e73c9df9b15efe 100644
--- a/ee/spec/frontend/analytics/cycle_analytics/vsa_settings/components/value_stream_form_content_spec.js
+++ b/ee/spec/frontend/analytics/cycle_analytics/vsa_settings/components/value_stream_form_content_spec.js
@@ -1,4 +1,4 @@
-import { GlAlert, GlFormInput } from '@gitlab/ui';
+import { GlAlert } from '@gitlab/ui';
 import Vue, { nextTick } from 'vue';
 // eslint-disable-next-line no-restricted-imports
 import Vuex from 'vuex';
@@ -8,7 +8,6 @@ import {
   PRESET_OPTIONS_DEFAULT,
 } from 'ee/analytics/cycle_analytics/vsa_settings/constants';
 import CustomStageFields from 'ee/analytics/cycle_analytics/vsa_settings/components/custom_stage_fields.vue';
-import CustomStageEventField from 'ee/analytics/cycle_analytics/vsa_settings/components/custom_stage_event_field.vue';
 import DefaultStageFields from 'ee/analytics/cycle_analytics/vsa_settings/components/default_stage_fields.vue';
 import ValueStreamFormContent from 'ee/analytics/cycle_analytics/vsa_settings/components/value_stream_form_content.vue';
 import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
@@ -23,7 +22,6 @@ import {
   defaultStageConfig,
   rawCustomStage,
   groupLabels as defaultGroupLabels,
-  valueStreamPath,
 } from '../../mock_data';
 
 jest.mock('~/lib/utils/url_utility', () => ({
@@ -37,19 +35,10 @@ describe('ValueStreamFormContent', () => {
   let wrapper = null;
   let trackingSpy = null;
 
-  const createValueStreamMock = jest.fn(() => Promise.resolve());
-  const updateValueStreamMock = jest.fn(() => Promise.resolve());
-  const mockToastShow = jest.fn();
+  const mockValueStream = { id: 13 };
+  const createValueStreamMock = jest.fn(() => Promise.resolve({ data: mockValueStream }));
+  const updateValueStreamMock = jest.fn(() => Promise.resolve({ data: mockValueStream }));
   const streamName = 'Cool stream';
-  const initialFormNameErrors = { name: ['Name field required'] };
-  const initialFormStageErrors = {
-    stages: [
-      {
-        name: ['Name field is required'],
-        startEventIdentifier: ['Start event is required'],
-      },
-    ],
-  };
   const formSubmissionErrors = {
     name: ['has already been taken'],
     stages: [
@@ -65,16 +54,19 @@ describe('ValueStreamFormContent', () => {
     name: 'Editable value stream',
   };
 
-  const initialPreset = PRESET_OPTIONS_DEFAULT;
-
-  const fakeStore = ({ state }) =>
+  const fakeStore = ({ state: stateOverrides }) =>
     new Vuex.Store({
       state: {
-        isCreatingValueStream: false,
-        isEditingValueStream: false,
         formEvents,
         defaultGroupLabels,
-        ...state,
+        createValueStreamErrors: {},
+        selectedValueStream: undefined,
+        ...stateOverrides,
+      },
+      mutations: {
+        setCreateValueStreamErrors(state, value) {
+          state.createValueStreamErrors = value;
+        },
       },
       actions: {
         createValueStream: createValueStreamMock,
@@ -82,78 +74,55 @@ describe('ValueStreamFormContent', () => {
       },
     });
 
-  const createComponent = ({ props = {}, data = {}, stubs = {}, state = {} } = {}) =>
+  const createComponent = ({ props = {}, state = {} } = {}) =>
     shallowMountExtended(ValueStreamFormContent, {
       store: fakeStore({ state }),
-      data() {
-        return {
-          ...data,
-        };
-      },
+      provide: { vsaPath: '/mockPath' },
       propsData: {
         defaultStageConfig,
-        valueStreamPath,
         ...props,
       },
-      mocks: {
-        $toast: {
-          show: mockToastShow,
-        },
-      },
-      stubs: {
-        ...stubs,
-      },
     });
 
   const findFormActions = () => wrapper.findComponent(ValueStreamFormContentActions);
-  const findExtendedFormFields = () => wrapper.findByTestId('extended-form-fields');
-  const findDefaultStages = () => findExtendedFormFields().findAllComponents(DefaultStageFields);
-  const findCustomStages = () => findExtendedFormFields().findAllComponents(CustomStageFields);
+  const findDefaultStages = () => wrapper.findAllComponents(DefaultStageFields);
+  const findCustomStages = () => wrapper.findAllComponents(CustomStageFields);
   const findLastCustomStage = () => findCustomStages().wrappers.at(-1);
 
   const findPresetSelector = () => wrapper.findByTestId('vsa-preset-selector');
   const findRestoreButton = () => wrapper.findByTestId('vsa-reset-button');
   const findRestoreStageButton = (index) => wrapper.findByTestId(`stage-action-restore-${index}`);
   const findHiddenStages = () => wrapper.findAllByTestId('vsa-hidden-stage').wrappers;
-  const findCustomStageEventField = (index = 0) =>
-    wrapper.findAllComponents(CustomStageEventField).at(index);
-  const findFieldErrors = (testId) => wrapper.findByTestId(testId).attributes('invalid-feedback');
-  const findNameInput = () =>
-    wrapper.findByTestId('create-value-stream-name').findComponent(GlFormInput);
+  const findNameFormGroup = () => wrapper.findByTestId('create-value-stream-name');
+  const findNameInput = () => wrapper.findByTestId('create-value-stream-name-input');
   const findSubmitErrorAlert = () => wrapper.findComponent(GlAlert);
 
-  const fillStageNameAtIndex = (name, index) =>
-    findCustomStages().at(index).findComponent(GlFormInput).vm.$emit('input', name);
-
   const clickSubmit = () => findFormActions().vm.$emit('clickPrimaryAction');
   const clickAddStage = async () => {
     findFormActions().vm.$emit('clickAddStageAction');
     await nextTick();
   };
   const clickRestoreStageAtIndex = (index) => findRestoreStageButton(index).vm.$emit('click');
-  const expectFieldError = (testId, error = '') => expect(findFieldErrors(testId)).toBe(error);
-  const expectCustomFieldError = (index, attr, error = '') =>
-    expect(findCustomStageEventField(index).attributes(attr)).toBe(error);
   const expectStageTransitionKeys = (stages) =>
     stages.forEach((stage) => expect(stage.transitionKey).toContain('stage-'));
 
-  describe('default state', () => {
+  const changeToDefaultStages = () =>
+    findPresetSelector().vm.$emit('input', PRESET_OPTIONS_DEFAULT);
+  const changeToCustomStages = () => findPresetSelector().vm.$emit('input', PRESET_OPTIONS_BLANK);
+
+  describe('when creating value stream', () => {
     beforeEach(() => {
       wrapper = createComponent({ state: { defaultGroupLabels: null } });
     });
 
-    it('has the form header', () => {
+    it('has the form actions', () => {
       expect(findFormActions().props()).toMatchObject({
         isLoading: false,
         isEditing: false,
-        valueStreamPath,
+        valueStreamId: -1,
       });
     });
 
-    it('has the extended fields', () => {
-      expect(findExtendedFormFields().exists()).toBe(true);
-    });
-
     describe('Preset selector', () => {
       it('has the preset button', () => {
         expect(findPresetSelector().exists()).toBe(true);
@@ -163,12 +132,12 @@ describe('ValueStreamFormContent', () => {
         expect(findDefaultStages()).toHaveLength(defaultStageConfig.length);
         expect(findCustomStages()).toHaveLength(0);
 
-        await findPresetSelector().vm.$emit('input', PRESET_OPTIONS_BLANK);
+        await changeToCustomStages();
 
         expect(findDefaultStages()).toHaveLength(0);
         expect(findCustomStages()).toHaveLength(1);
 
-        await findPresetSelector().vm.$emit('input', PRESET_OPTIONS_DEFAULT);
+        await changeToDefaultStages();
 
         expect(findDefaultStages()).toHaveLength(defaultStageConfig.length);
         expect(findCustomStages()).toHaveLength(0);
@@ -179,21 +148,21 @@ describe('ValueStreamFormContent', () => {
 
         expect(findNameInput().attributes('value')).toBe(initialData.name);
 
-        await findPresetSelector().vm.$emit('input', PRESET_OPTIONS_BLANK);
+        await changeToCustomStages();
 
         expect(findNameInput().attributes('value')).toBe(initialData.name);
 
-        await findPresetSelector().vm.$emit('input', PRESET_OPTIONS_DEFAULT);
+        await changeToDefaultStages();
 
         expect(findNameInput().attributes('value')).toBe(initialData.name);
       });
 
       it('each stage has a transition key when toggling', async () => {
-        await findPresetSelector().vm.$emit('input', PRESET_OPTIONS_BLANK);
+        await changeToCustomStages();
 
         expectStageTransitionKeys(wrapper.vm.stages);
 
-        await findPresetSelector().vm.$emit('input', PRESET_OPTIONS_DEFAULT);
+        await changeToDefaultStages();
 
         expectStageTransitionKeys(wrapper.vm.stages);
       });
@@ -205,11 +174,7 @@ describe('ValueStreamFormContent', () => {
 
     describe('Add stage button', () => {
       beforeEach(() => {
-        wrapper = createComponent({
-          stubs: {
-            CustomStageFields,
-          },
-        });
+        wrapper = createComponent();
       });
 
       it('adds a blank custom stage when clicked', async () => {
@@ -237,20 +202,15 @@ describe('ValueStreamFormContent', () => {
 
     describe('field validation', () => {
       beforeEach(() => {
-        wrapper = createComponent({
-          stubs: {
-            CustomStageFields,
-          },
-        });
+        wrapper = createComponent();
       });
 
       it('validates existing fields when clicked', async () => {
-        const fieldTestId = 'create-value-stream-name';
-        expect(findFieldErrors(fieldTestId)).toBeUndefined();
+        expect(findNameFormGroup().attributes('invalid-feedback')).toBe(undefined);
 
         await clickAddStage();
 
-        expectFieldError(fieldTestId, 'Name is required');
+        expect(findNameFormGroup().attributes('invalid-feedback')).toBe('Name is required');
       });
 
       it('does not allow duplicate stage names', async () => {
@@ -258,64 +218,56 @@ describe('ValueStreamFormContent', () => {
         await findNameInput().vm.$emit('input', streamName);
 
         await clickAddStage();
-        await fillStageNameAtIndex(firstDefaultStage.name, 0);
+        await findCustomStages().at(0).vm.$emit('input', {
+          field: 'name',
+          value: firstDefaultStage.name,
+        });
 
         // Trigger the field validation
         await clickAddStage();
 
-        expectFieldError('custom-stage-name-3', 'Stage name already exists');
+        expect(findCustomStages().at(0).props().errors.name).toEqual(['Stage name already exists']);
       });
     });
 
     describe('initial form stage errors', () => {
-      const commonExtendedData = {
-        props: {
-          initialFormErrors: initialFormStageErrors,
-        },
+      const createValueStreamErrors = {
+        stages: [
+          {
+            name: ['Name field is required'],
+            startEventIdentifier: ['Start event is required'],
+          },
+        ],
       };
 
-      it('renders errors for a default stage field', () => {
+      beforeEach(() => {
         wrapper = createComponent({
-          ...commonExtendedData,
-          stubs: {
-            DefaultStageFields,
-          },
+          state: { createValueStreamErrors },
         });
-
-        expectFieldError('default-stage-name-0', initialFormStageErrors.stages[0].name[0]);
       });
 
-      it('renders errors for a custom stage field', () => {
-        wrapper = createComponent({
-          props: {
-            ...commonExtendedData.props,
-            initialPreset: PRESET_OPTIONS_BLANK,
-          },
-          stubs: {
-            CustomStageFields,
-          },
-        });
-
-        expectFieldError('custom-stage-name-0', initialFormStageErrors.stages[0].name[0]);
-        expectCustomFieldError(
-          0,
-          'identifiererror',
-          initialFormStageErrors.stages[0].startEventIdentifier[0],
-        );
+      it('renders errors for a default stage field', () => {
+        expect(findDefaultStages().at(0).props().errors).toEqual(createValueStreamErrors.stages[0]);
       });
     });
 
     describe('initial form name errors', () => {
+      const nameError = 'Name field required';
+
       beforeEach(() => {
         wrapper = createComponent({
-          props: {
-            initialFormErrors: initialFormNameErrors,
+          state: {
+            createValueStreamErrors: { name: [nameError] },
           },
         });
       });
 
-      it('renders errors for the name field', () => {
-        expectFieldError('create-value-stream-name', initialFormNameErrors.name[0]);
+      it('sets the feedback for the name form group', () => {
+        expect(findNameFormGroup().attributes('invalid-feedback')).toBe(nameError);
+      });
+
+      it('sets the state for the name input', () => {
+        expect(findNameInput().props().state).toBe(false);
       });
     });
 
@@ -328,20 +280,6 @@ describe('ValueStreamFormContent', () => {
         unmockTracking();
       });
 
-      describe('form submitting', () => {
-        beforeEach(() => {
-          wrapper = createComponent({
-            state: {
-              isCreatingValueStream: true,
-            },
-          });
-        });
-
-        it("enables form header's loading state", () => {
-          expect(findFormActions().props('isLoading')).toBe(true);
-        });
-      });
-
       describe('form submitted successfully', () => {
         beforeEach(async () => {
           wrapper = createComponent();
@@ -370,10 +308,6 @@ describe('ValueStreamFormContent', () => {
           });
         });
 
-        it('does not display a toast message', () => {
-          expect(mockToastShow).not.toHaveBeenCalled();
-        });
-
         it('sends tracking information', () => {
           expect(trackingSpy).toHaveBeenCalledWith(undefined, 'submit_form', {
             label: 'create_value_stream',
@@ -385,7 +319,7 @@ describe('ValueStreamFormContent', () => {
         });
 
         it('redirects to the new value stream page', () => {
-          expect(visitUrlWithAlerts).toHaveBeenCalledWith(valueStreamPath, [
+          expect(visitUrlWithAlerts).toHaveBeenCalledWith('/mockPath?value_stream_id=13', [
             {
               id: 'vsa-settings-form-submission-success',
               message: `'${streamName}' Value Stream has been successfully created.`,
@@ -397,17 +331,12 @@ describe('ValueStreamFormContent', () => {
 
       describe('form submission fails', () => {
         beforeEach(async () => {
-          wrapper = createComponent({
-            props: {
-              initialFormErrors: formSubmissionErrors,
-            },
-            stubs: {
-              CustomStageFields,
-            },
-          });
+          wrapper = createComponent();
 
           await findNameInput().vm.$emit('input', streamName);
           clickSubmit();
+
+          wrapper.vm.$store.commit('setCreateValueStreamErrors', formSubmissionErrors);
         });
 
         it('calls the createValueStream action', () => {
@@ -418,20 +347,18 @@ describe('ValueStreamFormContent', () => {
           expect(findNameInput().attributes('value')).toBe(streamName);
         });
 
-        it('does not display a toast message', () => {
-          expect(mockToastShow).not.toHaveBeenCalled();
-        });
-
         it('does not redirect to the new value stream page', () => {
           expect(visitUrlWithAlerts).not.toHaveBeenCalled();
         });
 
-        it('form header should not be in loading state', () => {
+        it('form actions should not be in loading state', () => {
           expect(findFormActions().props('isLoading')).toBe(false);
         });
 
         it('renders errors for the name field', () => {
-          expectFieldError('create-value-stream-name', formSubmissionErrors.name[0]);
+          expect(findNameFormGroup().attributes('invalid-feedback')).toBe(
+            formSubmissionErrors.name[0],
+          );
         });
 
         it('renders a dismissible generic alert error', async () => {
@@ -443,15 +370,17 @@ describe('ValueStreamFormContent', () => {
     });
   });
 
-  describe('isEditing=true', () => {
+  describe('when editing value stream', () => {
     const stageCount = initialData.stages.length;
     beforeEach(() => {
       wrapper = createComponent({
         props: {
-          initialPreset,
           initialData,
           isEditing: true,
         },
+        state: {
+          selectedValueStream: mockValueStream,
+        },
       });
     });
 
@@ -459,8 +388,12 @@ describe('ValueStreamFormContent', () => {
       expect(findPresetSelector().exists()).toBe(false);
     });
 
-    it("enables form header's editing state", () => {
-      expect(findFormActions().props('isEditing')).toBe(true);
+    it('passes isEditing=true to form actions', () => {
+      expect(findFormActions().props().isEditing).toBe(true);
+    });
+
+    it('passes value stream ID to form actions', () => {
+      expect(findFormActions().props().valueStreamId).toBe(mockValueStream.id);
     });
 
     it('does not display any hidden stages', () => {
@@ -503,7 +436,6 @@ describe('ValueStreamFormContent', () => {
       beforeEach(() => {
         wrapper = createComponent({
           props: {
-            initialPreset,
             initialData: { ...initialData, stages: [...initialData.stages, ...hiddenStages] },
             isEditing: true,
           },
@@ -543,13 +475,9 @@ describe('ValueStreamFormContent', () => {
       beforeEach(() => {
         wrapper = createComponent({
           props: {
-            initialPreset,
             initialData,
             isEditing: true,
           },
-          stubs: {
-            CustomStageFields,
-          },
         });
       });
 
@@ -562,13 +490,12 @@ describe('ValueStreamFormContent', () => {
       });
 
       it('validates existing fields when clicked', async () => {
-        const fieldTestId = 'create-value-stream-name';
-        expect(findFieldErrors(fieldTestId)).toBeUndefined();
+        expect(findNameInput().props().state).toBe(true);
 
         await findNameInput().vm.$emit('input', '');
         await clickAddStage();
 
-        expectFieldError(fieldTestId, 'Name is required');
+        expect(findNameInput().props().state).toBe(false);
       });
     });
 
@@ -581,32 +508,15 @@ describe('ValueStreamFormContent', () => {
         unmockTracking();
       });
 
-      describe('form submitting', () => {
+      describe('form submitted successfully', () => {
         beforeEach(() => {
           wrapper = createComponent({
             props: {
-              initialPreset,
               initialData,
               isEditing: true,
             },
             state: {
-              isEditingValueStream: true,
-            },
-          });
-        });
-
-        it("enables form header's loading state", () => {
-          expect(findFormActions().props('isLoading')).toBe(true);
-        });
-      });
-
-      describe('form submitted successfully', () => {
-        beforeEach(() => {
-          wrapper = createComponent({
-            props: {
-              initialPreset,
-              initialData,
-              isEditing: true,
+              selectedValueStream: mockValueStream,
             },
           });
 
@@ -622,12 +532,12 @@ describe('ValueStreamFormContent', () => {
           });
         });
 
-        it('form header should be in loading state', () => {
+        it('form actions should be in loading state', () => {
           expect(findFormActions().props('isLoading')).toBe(true);
         });
 
         it('redirects to the updated value stream page', () => {
-          expect(visitUrlWithAlerts).toHaveBeenCalledWith(valueStreamPath, [
+          expect(visitUrlWithAlerts).toHaveBeenCalledWith('/mockPath?value_stream_id=13', [
             {
               id: 'vsa-settings-form-submission-success',
               message: `'${initialData.name}' Value Stream has been successfully saved.`,
@@ -647,17 +557,16 @@ describe('ValueStreamFormContent', () => {
         beforeEach(() => {
           wrapper = createComponent({
             props: {
-              initialFormErrors: formSubmissionErrors,
               initialData,
-              initialPreset,
               isEditing: true,
             },
-            stubs: {
-              CustomStageFields,
+            state: {
+              selectedValueStream: mockValueStream,
             },
           });
 
           clickSubmit();
+          wrapper.vm.$store.commit('setCreateValueStreamErrors', formSubmissionErrors);
         });
 
         it('calls the updateValueStreamMock action', () => {
@@ -670,24 +579,24 @@ describe('ValueStreamFormContent', () => {
           expect(findNameInput().attributes('value')).toBe(name);
         });
 
-        it('does not display a toast message', () => {
-          expect(mockToastShow).not.toHaveBeenCalled();
-        });
-
         it('does not redirect to the value stream page', () => {
           expect(visitUrlWithAlerts).not.toHaveBeenCalled();
         });
 
-        it('form header should not be in loading state', () => {
+        it('form actions should not be in loading state', () => {
           expect(findFormActions().props('isLoading')).toBe(false);
         });
 
         it('renders errors for the name field', () => {
-          expectFieldError('create-value-stream-name', formSubmissionErrors.name[0]);
+          expect(findNameFormGroup().attributes('invalid-feedback')).toBe(
+            formSubmissionErrors.name[0],
+          );
         });
 
         it('renders errors for a custom stage field', () => {
-          expectFieldError('custom-stage-name-0', formSubmissionErrors.stages[0].name[0]);
+          expect(findCustomStages().at(0).props().errors.name[0]).toBe(
+            formSubmissionErrors.stages[0].name[0],
+          );
         });
 
         it('renders a dismissible generic alert error', async () => {
diff --git a/ee/spec/frontend/analytics/cycle_analytics/vsa_settings/components/value_stream_form_spec.js b/ee/spec/frontend/analytics/cycle_analytics/vsa_settings/components/value_stream_form_spec.js
index a2472e6f1c76acbd152f438d82544fa11db424fd..dd55da879ac6f558f634f4c23128ba6c42a5f0e7 100644
--- a/ee/spec/frontend/analytics/cycle_analytics/vsa_settings/components/value_stream_form_spec.js
+++ b/ee/spec/frontend/analytics/cycle_analytics/vsa_settings/components/value_stream_form_spec.js
@@ -10,8 +10,6 @@ import {
   rawCustomStage,
   valueStreams,
   defaultStageConfig,
-  vsaPath,
-  valueStreamPath,
   groupLabels as defaultGroupLabels,
 } from 'ee_jest/analytics/cycle_analytics/mock_data';
 
@@ -30,7 +28,6 @@ describe('ValueStreamForm', () => {
   const fakeStore = ({ state }) =>
     new Vuex.Store({
       state: {
-        createValueStreamErrors: {},
         defaultStageConfig,
         defaultGroupLabels,
         isLoading: false,
@@ -50,9 +47,6 @@ describe('ValueStreamForm', () => {
         defaultStageConfig,
         ...props,
       },
-      provide: {
-        vsaPath,
-      },
     });
   };
 
@@ -69,7 +63,6 @@ describe('ValueStreamForm', () => {
         defaultStageConfig,
         initialData,
         isEditing: false,
-        valueStreamPath: vsaPath,
       });
     });
 
@@ -100,7 +93,6 @@ describe('ValueStreamForm', () => {
         defaultStageConfig,
         initialData: populatedInitialData,
         isEditing: true,
-        valueStreamPath,
       });
     });
   });
@@ -122,19 +114,6 @@ describe('ValueStreamForm', () => {
     },
   );
 
-  describe('with createValueStreamErrors', () => {
-    const nameError = "Name can't be blank";
-    beforeEach(() => {
-      createComponent({
-        state: { createValueStreamErrors: { name: nameError } },
-      });
-    });
-
-    it(`sets the form content component's initialFormErrors prop`, () => {
-      expect(findFormContent().props('initialFormErrors')).toEqual({ name: nameError });
-    });
-  });
-
   describe('when there are no defaultGroupLabels', () => {
     beforeEach(() => {
       createComponent({