Skip to content

Commit

Permalink
Adds transition component (#57)
Browse files Browse the repository at this point in the history
Signed-off-by: Drew Baugher <[email protected]>
  • Loading branch information
dbbaughe authored Aug 11, 2021
1 parent 19883f7 commit 131becf
Show file tree
Hide file tree
Showing 4 changed files with 260 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*
* Modifications Copyright OpenSearch Contributors. See
* GitHub history for details.
*/

import React from "react";
import "@testing-library/jest-dom/extend-expect";
import { render } from "@testing-library/react";
import Transition from "./Transition";

describe("<Transition /> spec", () => {
it("renders the component", () => {
const { container } = render(
<Transition
uiTransition={{ id: "123", transition: { state_name: "some_state", conditions: { min_index_age: "30d" } } }}
onChangeTransition={() => {}}
/>
);
expect(container.firstChild).toMatchSnapshot();
});
});
210 changes: 210 additions & 0 deletions public/pages/VisualCreatePolicy/components/Transition/Transition.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*
* Modifications Copyright OpenSearch Contributors. See
* GitHub history for details.
*/

import React, { ChangeEvent } from "react";
import { EuiFormRow, EuiSelect, EuiSpacer, EuiFieldText, EuiFieldNumber } from "@elastic/eui";
import moment from "moment-timezone";
import EuiFormCustomLabel from "../EuiFormCustomLabel";
import { UITransition } from "../../../../../models/interfaces";

const timezones = moment.tz.names().map((tz) => ({ label: tz, text: tz }));

const conditionTypeOptions = [
{ value: "min_index_age", text: "Minimum index age" },
{ value: "min_doc_count", text: "Minimum doc count" },
{ value: "min_size", text: "Minimum size" },
{ value: "cron", text: "Cron expression" },
];

interface TransitionProps {
uiTransition: UITransition;
onChangeTransition: (transition: UITransition) => void;
}

const Transition = ({ uiTransition, onChangeTransition }: TransitionProps) => {
// We currently only support one transition condition
const conditionType = Object.keys(uiTransition.transition?.conditions || []).pop() || "min_index_age";
return (
<>
<EuiFormCustomLabel title="Condition" helpText="Specify the condition needed to be met to transition to the destination state." />
<EuiFormRow isInvalid={false} error={null}>
<EuiSelect
id="condition-type"
options={conditionTypeOptions}
value={conditionType}
style={{ textTransform: "capitalize" }}
onChange={(e) => {
const selectedConditionType = e.target.value;
let conditionValue = {};
if (selectedConditionType === "min_index_age") conditionValue = { min_index_age: "30d" };
if (selectedConditionType === "min_doc_count") conditionValue = { min_doc_count: 1000000 };
if (selectedConditionType === "min_size") conditionValue = { min_size: "50gb" };
if (selectedConditionType === "cron")
conditionValue = { cron: { expression: "* 17 * * SAT", timezone: "America/Los_Angeles" } };
onChangeTransition({
...uiTransition,
transition: {
...uiTransition.transition,
conditions: {
[selectedConditionType]: conditionValue,
},
},
});
}}
data-test-subj="create-state-action-type"
/>
</EuiFormRow>

<EuiSpacer />

{conditionType === "min_index_age" && (
<>
<EuiFormCustomLabel title="Minimum index age" helpText="The minimum age required to transition to the next state." />
<EuiFormRow isInvalid={false} error={null}>
<EuiFieldText
value={uiTransition.transition.conditions?.min_index_age}
style={{ textTransform: "capitalize" }}
onChange={(e: ChangeEvent<HTMLInputElement>) => {
const minIndexAge = e.target.value;
onChangeTransition({
...uiTransition,
transition: {
...uiTransition.transition,
conditions: {
min_index_age: minIndexAge,
},
},
});
}}
data-test-subj="transition-render-conditions-min-index-age"
/>
</EuiFormRow>
</>
)}

{conditionType === "min_doc_count" && (
<>
<EuiFormCustomLabel
title="Minimum doc count"
helpText="The minimum number of documents required to transition to the next state."
/>
<EuiFormRow isInvalid={false} error={null}>
<EuiFieldNumber
value={uiTransition.transition.conditions?.min_doc_count}
style={{ textTransform: "capitalize" }}
onChange={(e: ChangeEvent<HTMLInputElement>) => {
const minDocCount = e.target.valueAsNumber;
onChangeTransition({
...uiTransition,
transition: {
...uiTransition.transition,
conditions: {
min_doc_count: minDocCount,
},
},
});
}}
data-test-subj="transition-render-conditions-min-doc-count"
/>
</EuiFormRow>
</>
)}

{conditionType === "min_size" && (
<>
<EuiFormCustomLabel
title="Minimum index size"
helpText="The minimum size of the total primary shard storage required to transition to the next state."
/>
<EuiFormRow isInvalid={false} error={null}>
<EuiFieldText
value={uiTransition.transition.conditions?.min_size}
style={{ textTransform: "capitalize" }}
onChange={(e: ChangeEvent<HTMLInputElement>) => {
const minSize = e.target.value;
onChangeTransition({
...uiTransition,
transition: {
...uiTransition.transition,
conditions: {
min_size: minSize,
},
},
});
}}
data-test-subj="transition-render-conditions-min-size"
/>
</EuiFormRow>
</>
)}

{conditionType === "cron" && (
<>
<EuiFormCustomLabel title="Cron expression" helpText="The matching cron expression required to transition to the next state." />
<EuiFormRow isInvalid={false} error={null}>
<EuiFieldText
value={uiTransition.transition.conditions?.cron?.cron.expression}
style={{ textTransform: "capitalize" }}
onChange={(e: ChangeEvent<HTMLInputElement>) => {
const expression = e.target.value;
onChangeTransition({
...uiTransition,
transition: {
...uiTransition.transition,
conditions: {
cron: {
cron: {
expression,
timezone: uiTransition.transition.conditions?.cron?.cron.timezone || "",
},
},
},
},
});
}}
data-test-subj="transition-render-conditions-min-size"
/>
</EuiFormRow>

<EuiSpacer />

<EuiFormCustomLabel title="Timezone" helpText="A day starts from 00:00:00 in the specified timezone." />
<EuiFormRow isInvalid={false} error={null}>
<EuiSelect
id="timezone"
options={timezones}
value={uiTransition.transition.conditions?.cron?.cron.timezone}
onChange={(e: ChangeEvent<HTMLSelectElement>) => {
const timezone = e.target.value;
onChangeTransition({
...uiTransition,
transition: {
...uiTransition.transition,
conditions: {
cron: {
cron: {
expression: uiTransition.transition.conditions?.cron?.cron.expression || "",
timezone,
},
},
},
},
});
}}
/>
</EuiFormRow>
</>
)}
</>
);
};

export default Transition;
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`<Transition /> spec renders the component 1`] = `
<div
class="euiText euiText--medium"
style="margin-bottom: 5px;"
>
<h5
style="margin-bottom: 2px;"
>
Condition
</h5>
<p>
<span
style="color: grey; font-weight: 200; font-size: 12px;"
>
Specify the condition needed to be met to transition to the destination state.
</span>
</p>
</div>
`;
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* GitHub history for details.
*/

import Transition from "./Transition";
import TransitionContent from "./TransitionContent";

export { TransitionContent };
Expand Down

0 comments on commit 131becf

Please sign in to comment.