Skip to content

Commit b9645f1

Browse files
authored
Added PolicySettings and DeleteModal components for PolicyDetails UI (#50)
* Added PolicySettings and DeleteModal components for View Policy UI * Added PolicySettings test snapshot and fixed placeholder edit button * Fixing DeleteModal renders component test * Fixed interface duplication, cleaned up PolicySettings, fixed PolicySettings test * Simplified ISMTemplate handling, removed unnecessary coversion function * Added ISM Template count to panel title * Fixing timezone dependency on PolicySettings test Signed-off-by: Eric Lobdell <[email protected]>
1 parent ea320d4 commit b9645f1

File tree

9 files changed

+801
-1
lines changed

9 files changed

+801
-1
lines changed

models/interfaces.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,9 @@ export interface DocumentTransform {
9292
export interface Policy {
9393
description: string;
9494
default_state: string;
95+
error_notification?: ErrorNotification;
9596
states: State[];
96-
ism_template: any;
97+
ism_template?: ISMTemplate[] | ISMTemplate | null;
9798
}
9899

99100
export interface ErrorNotification {
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
*
4+
* The OpenSearch Contributors require contributions made to
5+
* this file be licensed under the Apache-2.0 license or a
6+
* compatible open source license.
7+
*
8+
* Modifications Copyright OpenSearch Contributors. See
9+
* GitHub history for details.
10+
*/
11+
12+
import React from "react";
13+
import "@testing-library/jest-dom/extend-expect";
14+
import { screen, render } from "@testing-library/react";
15+
import DeleteModal from "./DeleteModal";
16+
import { fireEvent } from "@testing-library/dom";
17+
import userEvent from "@testing-library/user-event/dist";
18+
19+
describe("<DeleteModal /> spec", () => {
20+
it("renders the component", () => {
21+
const { baseElement } = render(
22+
<DeleteModal
23+
policyId="some_id"
24+
closeDeleteModal={() => {}}
25+
onClickDelete={() => {}}
26+
/>
27+
);
28+
expect(baseElement).toMatchSnapshot();
29+
});
30+
31+
it("calls closeDeleteModal when cancel button is clicked", () => {
32+
const closeDeleteModal = jest.fn();
33+
const { getByTestId } = render(
34+
<DeleteModal
35+
policyId="some_id"
36+
closeDeleteModal={closeDeleteModal}
37+
onClickDelete={() => {}}
38+
/>
39+
);
40+
41+
userEvent.click(getByTestId("confirmModalCancelButton"));
42+
expect(closeDeleteModal).toHaveBeenCalled();
43+
});
44+
45+
it("calls onClickDelete when delete button is clicked", () => {
46+
const onClickDelete = jest.fn();
47+
const { getByTestId } = render(
48+
<DeleteModal
49+
policyId="some_id"
50+
closeDeleteModal={() => {}}
51+
onClickDelete={onClickDelete}
52+
/>
53+
);
54+
55+
fireEvent.focus(getByTestId("deleteTextField"));
56+
userEvent.type(getByTestId("deleteTextField"), `delete`);
57+
userEvent.click(getByTestId("confirmModalConfirmButton"));
58+
59+
expect(onClickDelete).toHaveBeenCalled();
60+
});
61+
});
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
*
4+
* The OpenSearch Contributors require contributions made to
5+
* this file be licensed under the Apache-2.0 license or a
6+
* compatible open source license.
7+
*
8+
* Modifications Copyright OpenSearch Contributors. See
9+
* GitHub history for details.
10+
*/
11+
12+
import React, { ChangeEvent, Component, Fragment } from "react";
13+
import { EuiConfirmModal, EuiForm, EuiFormRow, EuiFieldText, EuiOverlayMask, EuiSpacer } from "@elastic/eui";
14+
15+
interface DeleteModalProps {
16+
policyId: string;
17+
closeDeleteModal: (event?: any) => void;
18+
onClickDelete: (event?: any) => void;
19+
}
20+
21+
interface DeleteModalState {
22+
confirmDeleteText: string;
23+
}
24+
25+
export default class DeleteModal extends Component<DeleteModalProps, DeleteModalState> {
26+
state = { confirmDeleteText: "" };
27+
28+
onChange = (e: ChangeEvent<HTMLInputElement>): void => {
29+
this.setState({ confirmDeleteText: e.target.value });
30+
};
31+
32+
render() {
33+
const { policyId, closeDeleteModal, onClickDelete } = this.props;
34+
const { confirmDeleteText } = this.state;
35+
36+
return (
37+
<EuiOverlayMask>
38+
<EuiConfirmModal
39+
title="Delete policy"
40+
onCancel={closeDeleteModal}
41+
onConfirm={onClickDelete}
42+
cancelButtonText="Cancel"
43+
confirmButtonText="Delete policy"
44+
buttonColor="danger"
45+
defaultFocusedButton="confirm"
46+
confirmButtonDisabled={confirmDeleteText != "delete"}
47+
>
48+
<EuiForm>
49+
<Fragment>
50+
Delete "<strong>{policyId}</strong>" permanently? Indices will no
51+
longer be managed using this policy
52+
</Fragment>
53+
<EuiSpacer size="s" />
54+
<EuiFormRow helpText="To confirm deletion, type delete">
55+
<EuiFieldText value={confirmDeleteText} placeholder="delete" onChange={this.onChange} data-test-subj="deleteTextField" />
56+
</EuiFormRow>
57+
</EuiForm>
58+
</EuiConfirmModal>
59+
</EuiOverlayMask>
60+
);
61+
}
62+
}
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`<DeleteModal /> spec renders the component 1`] = `
4+
<body
5+
class="euiBody-hasOverlayMask"
6+
>
7+
<div
8+
aria-hidden="true"
9+
data-aria-hidden="true"
10+
/>
11+
<div
12+
class="euiOverlayMask euiOverlayMask--aboveHeader"
13+
>
14+
<div
15+
aria-hidden="true"
16+
data-aria-hidden="true"
17+
data-focus-guard="true"
18+
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
19+
tabindex="0"
20+
/>
21+
<div
22+
aria-hidden="true"
23+
data-aria-hidden="true"
24+
data-focus-guard="true"
25+
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
26+
tabindex="1"
27+
/>
28+
<div
29+
data-focus-lock-disabled="false"
30+
>
31+
<div
32+
class="euiModal euiModal--maxWidth-default euiModal--confirmation"
33+
tabindex="0"
34+
>
35+
<button
36+
aria-label="Closes this modal window"
37+
class="euiButtonIcon euiButtonIcon--text euiModal__closeIcon"
38+
type="button"
39+
>
40+
EuiIconMock
41+
</button>
42+
<div
43+
class="euiModal__flex"
44+
>
45+
<div
46+
class="euiModalHeader"
47+
>
48+
<div
49+
class="euiModalHeader__title"
50+
data-test-subj="confirmModalTitleText"
51+
>
52+
Delete policy
53+
</div>
54+
</div>
55+
<div
56+
class="euiModalBody"
57+
>
58+
<div
59+
class="euiModalBody__overflow"
60+
>
61+
<div
62+
class="euiText euiText--medium"
63+
data-test-subj="confirmModalBodyText"
64+
>
65+
<div
66+
class="euiForm"
67+
>
68+
Delete "
69+
<strong>
70+
some_id
71+
</strong>
72+
" permanently? Indices will no longer be managed using this policy
73+
<div
74+
class="euiSpacer euiSpacer--s"
75+
/>
76+
<div
77+
class="euiFormRow"
78+
id="some_html_id-row"
79+
>
80+
<div
81+
class="euiFormRow__fieldWrapper"
82+
>
83+
<div
84+
class="euiFormControlLayout"
85+
>
86+
<div
87+
class="euiFormControlLayout__childrenWrapper"
88+
>
89+
<input
90+
aria-describedby="some_html_id-help"
91+
class="euiFieldText"
92+
data-test-subj="deleteTextField"
93+
id="some_html_id"
94+
placeholder="delete"
95+
type="text"
96+
value=""
97+
/>
98+
</div>
99+
</div>
100+
<div
101+
class="euiFormHelpText euiFormRow__text"
102+
id="some_html_id-help"
103+
>
104+
To confirm deletion, type delete
105+
</div>
106+
</div>
107+
</div>
108+
</div>
109+
</div>
110+
</div>
111+
</div>
112+
<div
113+
class="euiModalFooter"
114+
>
115+
<button
116+
class="euiButtonEmpty euiButtonEmpty--primary"
117+
data-test-subj="confirmModalCancelButton"
118+
type="button"
119+
>
120+
<span
121+
class="euiButtonContent euiButtonEmpty__content"
122+
>
123+
<span
124+
class="euiButtonEmpty__text"
125+
>
126+
Cancel
127+
</span>
128+
</span>
129+
</button>
130+
<button
131+
class="euiButton euiButton--danger euiButton--fill euiButton-isDisabled"
132+
data-test-subj="confirmModalConfirmButton"
133+
disabled=""
134+
type="button"
135+
>
136+
<span
137+
class="euiButtonContent euiButton__content"
138+
>
139+
<span
140+
class="euiButton__text"
141+
>
142+
Delete policy
143+
</span>
144+
</span>
145+
</button>
146+
</div>
147+
</div>
148+
</div>
149+
</div>
150+
<div
151+
aria-hidden="true"
152+
data-aria-hidden="true"
153+
data-focus-guard="true"
154+
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
155+
tabindex="0"
156+
/>
157+
</div>
158+
</body>
159+
`;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
*
4+
* The OpenSearch Contributors require contributions made to
5+
* this file be licensed under the Apache-2.0 license or a
6+
* compatible open source license.
7+
*
8+
* Modifications Copyright OpenSearch Contributors. See
9+
* GitHub history for details.
10+
*/
11+
12+
import DeleteModal from "./DeleteModal";
13+
14+
export default DeleteModal;
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
*
4+
* The OpenSearch Contributors require contributions made to
5+
* this file be licensed under the Apache-2.0 license or a
6+
* compatible open source license.
7+
*
8+
* Modifications Copyright OpenSearch Contributors. See
9+
* GitHub history for details.
10+
*/
11+
12+
import React from "react";
13+
import "@testing-library/jest-dom/extend-expect";
14+
import { render } from "@testing-library/react";
15+
import PolicySettings from "./PolicySettings";
16+
17+
describe("<PolicySettings /> spec", () => {
18+
beforeAll(() => {
19+
jest.useFakeTimers('modern');
20+
jest.setSystemTime(new Date(2021, 7, 1));
21+
});
22+
23+
afterAll(() => {
24+
jest.useRealTimers();
25+
});
26+
27+
it("renders the component", () => {
28+
const { container } = render(
29+
<PolicySettings
30+
policyId={"some_id"}
31+
channelId={"some_channel_id"}
32+
primaryTerm={1}
33+
lastUpdated={new Date().toString()}
34+
description={"some description"}
35+
sequenceNumber={2}
36+
schemaVersion={3}
37+
ismTemplates={[]}
38+
/>
39+
);
40+
41+
expect(container.firstChild).toMatchSnapshot();
42+
});
43+
});

0 commit comments

Comments
 (0)