diff --git a/packages/kubernetes/src/kubernetes.module.ts b/packages/kubernetes/src/kubernetes.module.ts
index 11b19a50951..a3a825a0972 100644
--- a/packages/kubernetes/src/kubernetes.module.ts
+++ b/packages/kubernetes/src/kubernetes.module.ts
@@ -33,7 +33,6 @@ import { ManifestWizard } from './manifest/wizard/ManifestWizard';
 import './pipelines/stages';
 import { KUBERNETES_DISABLE_MANIFEST_STAGE } from './pipelines/stages/traffic/disableManifest.stage';
 import { KUBERNETES_ENABLE_MANIFEST_STAGE } from './pipelines/stages/traffic/enableManifest.stage';
-import { KUBERNETES_UNDO_ROLLOUT_MANIFEST_STAGE } from './pipelines/stages/undoRolloutManifest/undoRolloutManifestStage';
 import './pipelines/validation/manifestSelector.validator';
 import { KUBERNETS_RAW_RESOURCE_MODULE } from './rawResource';
 import { KUBERNETES_RESOURCE_STATES } from './resources/resources.state';
@@ -71,7 +70,6 @@ const requires = [
   KUBERNETES_MANIFEST_ARTIFACT,
   KUBERNETES_LOAD_BALANCER_TRANSFORMER,
   KUBERNETES_SECURITY_GROUP_TRANSFORMER,
-  KUBERNETES_UNDO_ROLLOUT_MANIFEST_STAGE,
   KUBERNETES_MANIFEST_SELECTOR,
   KUBERNETES_MANIFEST_LABELS,
   KUBERNETES_MANIFEST_EVENTS,
diff --git a/packages/kubernetes/src/pipelines/stages/index.ts b/packages/kubernetes/src/pipelines/stages/index.ts
index fd647fcefb1..ee346cb7c30 100644
--- a/packages/kubernetes/src/pipelines/stages/index.ts
+++ b/packages/kubernetes/src/pipelines/stages/index.ts
@@ -4,4 +4,5 @@ export * from './findArtifactsFromResource/findArtifactsFromResourceStage';
 export * from './patchManifest/patchManifestStage';
 export * from './rolloutRestartManifest/rolloutRestartManifestStage';
 export * from './runJob/runJobStage';
+export * from './undoRolloutManifest/undoRolloutManifestStage';
 export * from './scaleManifest/scaleManifestStage';
diff --git a/packages/kubernetes/src/pipelines/stages/undoRolloutManifest/UndoRolloutManifestConfig.tsx b/packages/kubernetes/src/pipelines/stages/undoRolloutManifest/UndoRolloutManifestConfig.tsx
new file mode 100644
index 00000000000..0a503915d24
--- /dev/null
+++ b/packages/kubernetes/src/pipelines/stages/undoRolloutManifest/UndoRolloutManifestConfig.tsx
@@ -0,0 +1,37 @@
+import { defaults } from 'lodash';
+import React, { useEffect } from 'react';
+
+import type { IFormikStageConfigInjectedProps, IStageConfigProps } from '@spinnaker/core';
+import { FormikStageConfig } from '@spinnaker/core';
+
+import { UndoRolloutManifestStageForm } from './UndoRolloutManifestStageForm';
+
+export function UndoRolloutManifestConfig({
+  application,
+  pipeline,
+  stage,
+  updateStage,
+  stageFieldUpdated,
+}: IStageConfigProps) {
+  useEffect(() => {
+    defaults(stage, {
+      cloudProvider: 'kubernetes',
+    });
+
+    if (stage.isNew) {
+      stage.numRevisionsBack = 1;
+    }
+  }, []);
+
+  return (
+    <FormikStageConfig
+      application={application}
+      pipeline={pipeline}
+      stage={stage}
+      onChange={updateStage}
+      render={(props: IFormikStageConfigInjectedProps) => (
+        <UndoRolloutManifestStageForm {...props} stageFieldUpdated={stageFieldUpdated} />
+      )}
+    />
+  );
+}
diff --git a/packages/kubernetes/src/pipelines/stages/undoRolloutManifest/UndoRolloutManifestStageForm.tsx b/packages/kubernetes/src/pipelines/stages/undoRolloutManifest/UndoRolloutManifestStageForm.tsx
new file mode 100644
index 00000000000..1716daccdeb
--- /dev/null
+++ b/packages/kubernetes/src/pipelines/stages/undoRolloutManifest/UndoRolloutManifestStageForm.tsx
@@ -0,0 +1,60 @@
+import React from 'react';
+
+import type { IFormikStageConfigInjectedProps } from '@spinnaker/core';
+import { NumberInput, StageConfigField } from '@spinnaker/core';
+
+import type { IManifestSelector } from '../../../manifest/selector/IManifestSelector';
+import { SelectorMode } from '../../../manifest/selector/IManifestSelector';
+import { ManifestSelector } from '../../../manifest/selector/ManifestSelector';
+
+interface IUndoRolloutManifestStageConfigFormProps {
+  stageFieldUpdated: () => void;
+}
+
+export function UndoRolloutManifestStageForm({
+  application,
+  formik,
+  stageFieldUpdated,
+}: IUndoRolloutManifestStageConfigFormProps & IFormikStageConfigInjectedProps) {
+  const stage = formik.values;
+
+  const onManifestSelectorChange = () => {
+    stageFieldUpdated();
+  };
+
+  const onRevisionsChange = (e: React.ChangeEvent<any>) => {
+    formik.setFieldValue('numRevisionsBack', e.target.value);
+  };
+
+  return (
+    <div className="form-horizontal">
+      <h4>Manifest</h4>
+      <div className="horizontal-rule" />
+      <ManifestSelector
+        application={application}
+        selector={(stage as unknown) as IManifestSelector}
+        modes={[SelectorMode.Static, SelectorMode.Dynamic]}
+        onChange={onManifestSelectorChange}
+        includeSpinnakerKinds={null}
+      />
+      <h4>Settings</h4>
+      <div className="horizontal-rule" />
+      <StageConfigField
+        label="Revisions Back"
+        helpKey="kubernetes.manifest.undoRollout.revisionsBack"
+        fieldColumns={4}
+        groupClassName="form-group form-inline"
+      >
+        <div className="input-group">
+          <NumberInput
+            inputClassName="input-sm highlight-pristine"
+            onChange={onRevisionsChange}
+            value={stage.numRevisionsBack}
+            min={1}
+          />
+          <span className="input-group-addon">{stage.numRevisionsBack === '1' ? 'revision' : 'revisions'}</span>
+        </div>
+      </StageConfigField>
+    </div>
+  );
+}
diff --git a/packages/kubernetes/src/pipelines/stages/undoRolloutManifest/undoRolloutManifestConfig.controller.ts b/packages/kubernetes/src/pipelines/stages/undoRolloutManifest/undoRolloutManifestConfig.controller.ts
deleted file mode 100644
index c55256f9956..00000000000
--- a/packages/kubernetes/src/pipelines/stages/undoRolloutManifest/undoRolloutManifestConfig.controller.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import type { IController, IScope } from 'angular';
-
-export class KubernetesV2UndoRolloutManifestConfigCtrl implements IController {
-  public static $inject = ['$scope'];
-  constructor(private $scope: IScope) {
-    if (this.$scope.stage.isNew) {
-      Object.assign(this.$scope.stage, {
-        location: '',
-        account: '',
-        cloudProvider: 'kubernetes',
-        numRevisionsBack: 1,
-      });
-    }
-  }
-
-  public handleManifestSelectorChange = (): void => {
-    this.$scope.$applyAsync();
-  };
-}
diff --git a/packages/kubernetes/src/pipelines/stages/undoRolloutManifest/undoRolloutManifestConfig.html b/packages/kubernetes/src/pipelines/stages/undoRolloutManifest/undoRolloutManifestConfig.html
deleted file mode 100644
index 8d033167b2a..00000000000
--- a/packages/kubernetes/src/pipelines/stages/undoRolloutManifest/undoRolloutManifestConfig.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<div class="form-horizontal">
-  <h4>Manifest</h4>
-  <div class="horizontal-rule"></div>
-  <kubernetes-manifest-selector
-    on-change="ctrl.handleManifestSelectorChange"
-    selector="stage"
-  ></kubernetes-manifest-selector>
-  <h4>Settings</h4>
-  <div class="form-horizontal">
-    <div class="form-group form-inline">
-      <div class="col-md-3 sm-label-right">
-        Revisions Back
-        <help-field key="kubernetes.manifest.undoRollout.revisionsBack"></help-field>
-      </div>
-      <div class="col-md-4">
-        <div class="input-group">
-          <input
-            type="number"
-            class="form-control input-sm highlight-pristine"
-            ng-model="stage.numRevisionsBack"
-            min="1"
-          />
-          <span class="input-group-addon">revision<span ng-if="ctrl.$scope.stage.numRevisionsBack !== 1">s</span></span>
-        </div>
-      </div>
-    </div>
-  </div>
-</div>
diff --git a/packages/kubernetes/src/pipelines/stages/undoRolloutManifest/undoRolloutManifestStage.ts b/packages/kubernetes/src/pipelines/stages/undoRolloutManifest/undoRolloutManifestStage.ts
index c68e1f93949..a94bc019ff1 100644
--- a/packages/kubernetes/src/pipelines/stages/undoRolloutManifest/undoRolloutManifestStage.ts
+++ b/packages/kubernetes/src/pipelines/stages/undoRolloutManifest/undoRolloutManifestStage.ts
@@ -1,30 +1,21 @@
-import { module } from 'angular';
+import { ExecutionDetailsTasks, Registry } from '@spinnaker/core';
 
-import type { IStage } from '@spinnaker/core';
-import { Registry } from '@spinnaker/core';
+import { manifestExecutionDetails } from '../ManifestExecutionDetails';
+import { UndoRolloutManifestConfig } from './UndoRolloutManifestConfig';
+import { manifestSelectorValidators } from '../validators/manifestSelectorValidators';
 
-import { KubernetesV2UndoRolloutManifestConfigCtrl } from './undoRolloutManifestConfig.controller';
+const STAGE_NAME = 'Undo Rollout (Manifest)';
+const STAGE_KEY = 'undoRolloutManifest';
 
-export const KUBERNETES_UNDO_ROLLOUT_MANIFEST_STAGE = 'spinnaker.kubernetes.v2.pipeline.stage.undoRolloutManifestStage';
-
-module(KUBERNETES_UNDO_ROLLOUT_MANIFEST_STAGE, [])
-  .config(() => {
-    Registry.pipeline.registerStage({
-      label: 'Undo Rollout (Manifest)',
-      description: 'Rollback a manifest a target number of revisions.',
-      key: 'undoRolloutManifest',
-      cloudProvider: 'kubernetes',
-      templateUrl: require('./undoRolloutManifestConfig.html'),
-      controller: 'KubernetesV2UndoRolloutManifestConfigCtrl',
-      controllerAs: 'ctrl',
-      accountExtractor: (stage: IStage): string[] => (stage.account ? [stage.account] : []),
-      configAccountExtractor: (stage: any): string[] => (stage.account ? [stage.account] : []),
-      validators: [
-        { type: 'requiredField', fieldName: 'location', fieldLabel: 'Namespace' },
-        { type: 'requiredField', fieldName: 'account', fieldLabel: 'Account' },
-        { type: 'requiredField', fieldName: 'numRevisionsBack', fieldLabel: 'Number of Revisions' },
-        { type: 'manifestSelector' },
-      ],
-    });
-  })
-  .controller('KubernetesV2UndoRolloutManifestConfigCtrl', KubernetesV2UndoRolloutManifestConfigCtrl);
+Registry.pipeline.registerStage({
+  label: STAGE_NAME,
+  description: 'Rollback a manifest a target number of revisions.',
+  key: STAGE_KEY,
+  cloudProvider: 'kubernetes',
+  component: UndoRolloutManifestConfig,
+  executionDetailsSections: [manifestExecutionDetails(STAGE_KEY), ExecutionDetailsTasks],
+  validators: [
+    ...manifestSelectorValidators(STAGE_NAME),
+    { type: 'requiredField', fieldName: 'numRevisionsBack', fieldLabel: 'Number of Revisions' },
+  ],
+});