diff --git a/models/interfaces.ts b/models/interfaces.ts
index 062dd49e8..454e9b77b 100644
--- a/models/interfaces.ts
+++ b/models/interfaces.ts
@@ -428,6 +428,14 @@ export interface SnapshotAction extends Action {
};
}
+export interface ConvertIndexToRemoteAction extends Action {
+ convert_index_to_remote: {
+ repository: string;
+ snapshot: string;
+ rename_pattern?: string;
+ };
+}
+
export interface IndexPriorityAction extends Action {
index_priority: {
priority?: number;
diff --git a/public/pages/Aliases/containers/Aliases/Aliases.test.tsx b/public/pages/Aliases/containers/Aliases/Aliases.test.tsx
index 39f4ff354..a978165d6 100644
--- a/public/pages/Aliases/containers/Aliases/Aliases.test.tsx
+++ b/public/pages/Aliases/containers/Aliases/Aliases.test.tsx
@@ -170,7 +170,7 @@ describe(" spec", () => {
});
});
await userEvent.click(document.getElementById(`_selection_column_${testAliasId}-checkbox`) as Element);
- await waitFor(() => {});
+ await waitFor(() => { });
await userEvent.click(document.querySelector('[data-test-subj="moreAction"] button') as Element);
await userEvent.click(document.querySelector('[data-test-subj="editAction"]') as Element);
await userEvent.click(getByTestId("cancelCreateAliasButton"));
@@ -225,7 +225,7 @@ describe(" spec", () => {
getByTestId("form-name-indexArray").querySelector('[data-test-subj="comboBoxSearchInput"]') as Element,
"1{enter}"
);
- await waitFor(() => {});
+ await waitFor(() => { });
await userEvent.click(getByTestId("createAliasButton"));
await waitFor(() => {
expect(coreServicesMock.notifications.toasts.addDanger).toBeCalledTimes(1);
diff --git a/public/pages/VisualCreatePolicy/components/UIActions/ConvertIndexToRemoteUIAction/ConvertIndexToRemoteUIAction.test.tsx b/public/pages/VisualCreatePolicy/components/UIActions/ConvertIndexToRemoteUIAction/ConvertIndexToRemoteUIAction.test.tsx
new file mode 100644
index 000000000..127793ced
--- /dev/null
+++ b/public/pages/VisualCreatePolicy/components/UIActions/ConvertIndexToRemoteUIAction/ConvertIndexToRemoteUIAction.test.tsx
@@ -0,0 +1,60 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from "react";
+import "@testing-library/jest-dom";
+import { render, screen, cleanup } from "@testing-library/react";
+import { DEFAULT_CONVERT_INDEX_TO_REMOTE } from "../../../utils/constants";
+import { ConvertIndexToRemoteAction, UIAction } from "../../../../../../models/interfaces";
+import { actionRepoSingleton } from "../../../utils/helpers";
+
+const TEST_PROPS: UIAction = {
+ action: DEFAULT_CONVERT_INDEX_TO_REMOTE,
+} as UIAction;
+
+const mockOnChangeAction = jest.fn();
+
+afterEach(() => cleanup());
+
+describe("ConvertIndexToRemoteUIAction component", () => {
+ it("renders correctly with default action", () => {
+ const { container } = render(actionRepoSingleton.getUIAction("convert_index_to_remote").render(TEST_PROPS, mockOnChangeAction));
+
+ const repositoryInput = screen.getByTestId("action-render-convert-index-to-remote-repository");
+ expect(repositoryInput).toBeInTheDocument();
+ expect(repositoryInput).toHaveValue(DEFAULT_CONVERT_INDEX_TO_REMOTE.convert_index_to_remote.repository);
+ const snapshotInput = screen.getByTestId("action-render-convert-index-to-remote-snapshot");
+ expect(snapshotInput).toBeInTheDocument();
+ expect(snapshotInput).toHaveValue(DEFAULT_CONVERT_INDEX_TO_REMOTE.convert_index_to_remote.snapshot);
+ const renamePatternInput = screen.getByTestId("action-render-convert-index-to-remote-rename-pattern");
+ expect(renamePatternInput).toBeInTheDocument();
+ // Should display the backend default fallback value
+ expect(renamePatternInput).toHaveValue("$1_remote");
+
+ expect(container).toMatchSnapshot();
+ });
+
+ it("renders correctly when rename_pattern is provided", () => {
+ const actionWithoutRenamePattern: UIAction = {
+ action: {
+ convert_index_to_remote: {
+ repository: "test-repository",
+ snapshot: "test-snapshot",
+ rename_pattern: "remote_$1",
+ },
+ },
+ } as UIAction;
+
+ const { container } = render(
+ actionRepoSingleton.getUIAction("convert_index_to_remote").render(actionWithoutRenamePattern, mockOnChangeAction)
+ );
+
+ const renamePatternInput = screen.getByTestId("action-render-convert-index-to-remote-rename-pattern");
+ expect(renamePatternInput).toBeInTheDocument();
+ expect(renamePatternInput).toHaveValue("remote_$1");
+
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/public/pages/VisualCreatePolicy/components/UIActions/ConvertIndexToRemoteUIAction/ConvertIndexToRemoteUIAction.tsx b/public/pages/VisualCreatePolicy/components/UIActions/ConvertIndexToRemoteUIAction/ConvertIndexToRemoteUIAction.tsx
new file mode 100644
index 000000000..b23a89b67
--- /dev/null
+++ b/public/pages/VisualCreatePolicy/components/UIActions/ConvertIndexToRemoteUIAction/ConvertIndexToRemoteUIAction.tsx
@@ -0,0 +1,107 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React, { ChangeEvent } from "react";
+import { DEFAULT_CONVERT_INDEX_TO_REMOTE } from "../../../utils/constants";
+import { EuiCompressedFormRow, EuiCompressedFieldText, EuiSpacer } from "@elastic/eui";
+import { ConvertIndexToRemoteAction, UIAction } from "../../../../../../models/interfaces";
+import { makeId } from "../../../../../utils/helpers";
+import { ActionType } from "../../../utils/constants";
+import EuiFormCustomLabel from "../../EuiFormCustomLabel";
+
+export default class ConvertIndexToRemoteUIAction implements UIAction {
+ id: string;
+ action: ConvertIndexToRemoteAction;
+ type = ActionType.ConvertIndexToRemote;
+
+ constructor(action: ConvertIndexToRemoteAction, id: string = makeId()) {
+ this.action = action;
+ this.id = id;
+ }
+
+ content = () => `Convert Index To Remote`;
+
+ clone = (action: ConvertIndexToRemoteAction) => new ConvertIndexToRemoteUIAction(action, this.id);
+
+ isValid = () => {
+ return !!this.action.convert_index_to_remote.snapshot && !!this.action.convert_index_to_remote.repository;
+ };
+
+ render = (action: UIAction, onChangeAction: (action: UIAction) => void) => {
+ return (
+ <>
+
+
+ ) => {
+ const repository = e.target.value;
+ onChangeAction(
+ this.clone({
+ convert_index_to_remote: {
+ ...action.action.convert_index_to_remote,
+ repository,
+ },
+ })
+ );
+ }}
+ data-test-subj="action-render-convert-index-to-remote-repository"
+ />
+
+
+
+
+ ) => {
+ const snapshot = e.target.value;
+ onChangeAction(
+ this.clone({
+ convert_index_to_remote: {
+ ...action.action.convert_index_to_remote,
+ snapshot,
+ },
+ })
+ );
+ }}
+ data-test-subj="action-render-convert-index-to-remote-snapshot"
+ />
+
+
+
+
+ ) => {
+ const rename_pattern = e.target.value;
+ onChangeAction(
+ this.clone({
+ convert_index_to_remote: {
+ ...action.action.convert_index_to_remote,
+ rename_pattern,
+ },
+ })
+ );
+ }}
+ data-test-subj="action-render-convert-index-to-remote-rename-pattern"
+ />
+
+ >
+ );
+ };
+
+ toAction = () => this.action;
+}
diff --git a/public/pages/VisualCreatePolicy/components/UIActions/ConvertIndexToRemoteUIAction/__snapshots__/ConvertIndexToRemoteUIAction.test.tsx.snap b/public/pages/VisualCreatePolicy/components/UIActions/ConvertIndexToRemoteUIAction/__snapshots__/ConvertIndexToRemoteUIAction.test.tsx.snap
new file mode 100644
index 000000000..5c50a1363
--- /dev/null
+++ b/public/pages/VisualCreatePolicy/components/UIActions/ConvertIndexToRemoteUIAction/__snapshots__/ConvertIndexToRemoteUIAction.test.tsx.snap
@@ -0,0 +1,329 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`ConvertIndexToRemoteUIAction component renders correctly when rename_pattern is provided 1`] = `
+
+`;
+
+exports[`ConvertIndexToRemoteUIAction component renders correctly with default action 1`] = `
+
+`;
diff --git a/public/pages/VisualCreatePolicy/components/UIActions/index.ts b/public/pages/VisualCreatePolicy/components/UIActions/index.ts
index 53db9ec57..6a44ac76e 100644
--- a/public/pages/VisualCreatePolicy/components/UIActions/index.ts
+++ b/public/pages/VisualCreatePolicy/components/UIActions/index.ts
@@ -6,6 +6,7 @@
import AliasUIAction from "./AliasUIAction/AliasUIAction";
import AllocationUIAction from "./AllocationUIAction";
import CloseUIAction from "./CloseUIAction";
+import ConvertIndexToRemoteUIAction from "./ConvertIndexToRemoteUIAction/ConvertIndexToRemoteUIAction";
import DeleteUIAction from "./DeleteUIAction";
import ForceMergeUIAction from "./ForceMergeUIAction";
import IndexPriorityUIAction from "./IndexPriorityUIAction";
@@ -23,6 +24,7 @@ export {
AliasUIAction,
AllocationUIAction,
CloseUIAction,
+ ConvertIndexToRemoteUIAction,
DeleteUIAction,
ForceMergeUIAction,
IndexPriorityUIAction,
diff --git a/public/pages/VisualCreatePolicy/containers/CreateAction/__snapshots__/CreateAction.test.tsx.snap b/public/pages/VisualCreatePolicy/containers/CreateAction/__snapshots__/CreateAction.test.tsx.snap
index 5931d370c..37ec3f971 100644
--- a/public/pages/VisualCreatePolicy/containers/CreateAction/__snapshots__/CreateAction.test.tsx.snap
+++ b/public/pages/VisualCreatePolicy/containers/CreateAction/__snapshots__/CreateAction.test.tsx.snap
@@ -110,6 +110,11 @@ exports[` spec renders the component 1`] = `
>
Close
+