@truedat/se 6.1.3 → 6.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +4 -4
- package/src/api.js +3 -3
- package/src/components/DeleteIndexButton.js +35 -0
- package/src/components/ElasticIndexes.js +69 -0
- package/src/components/SearchRoutes.js +64 -52
- package/src/components/__tests__/DeleteIndexButton.spec.js +75 -0
- package/src/components/__tests__/ElasticIndexes.spec.js +47 -0
- package/src/components/__tests__/SearchRoutes.spec.js +4 -0
- package/src/components/__tests__/__snapshots__/DeleteIndexButton.spec.js.snap +11 -0
- package/src/components/__tests__/__snapshots__/ElasticIndexes.spec.js.snap +150 -0
- package/src/components/index.js +1 -1
- package/src/hooks/__tests__/useElasticIndexes.spec.js +76 -0
- package/src/hooks/useElasticIndexes.js +37 -0
- package/src/messages/en.js +1 -1
- package/src/messages/es.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truedat/se",
|
|
3
|
-
"version": "6.1.
|
|
3
|
+
"version": "6.1.5",
|
|
4
4
|
"description": "Truedat Web Search Engine",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"jsnext:main": "src/index.js",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"@testing-library/jest-dom": "^5.16.5",
|
|
35
35
|
"@testing-library/react": "^12.0.0",
|
|
36
36
|
"@testing-library/user-event": "^13.2.1",
|
|
37
|
-
"@truedat/test": "6.1.
|
|
37
|
+
"@truedat/test": "6.1.5",
|
|
38
38
|
"babel-jest": "^28.1.0",
|
|
39
39
|
"babel-plugin-dynamic-import-node": "^2.3.3",
|
|
40
40
|
"babel-plugin-lodash": "^3.3.4",
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
]
|
|
87
87
|
},
|
|
88
88
|
"dependencies": {
|
|
89
|
-
"@truedat/core": "6.1.
|
|
89
|
+
"@truedat/core": "6.1.5",
|
|
90
90
|
"path-to-regexp": "^1.7.0",
|
|
91
91
|
"prop-types": "^15.8.1",
|
|
92
92
|
"react-intl": "^5.20.10",
|
|
@@ -103,5 +103,5 @@
|
|
|
103
103
|
"react-dom": ">= 16.8.6 < 17",
|
|
104
104
|
"semantic-ui-react": ">= 2.0.3 < 2.2"
|
|
105
105
|
},
|
|
106
|
-
"gitHead": "
|
|
106
|
+
"gitHead": "3cbadffa2227cac1cce3c21d8442245082324ac1"
|
|
107
107
|
}
|
package/src/api.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
const API_GLOBAL_SEARCH = "/api/global_search";
|
|
2
|
-
|
|
3
|
-
export
|
|
1
|
+
export const API_GLOBAL_SEARCH = "/api/global_search";
|
|
2
|
+
export const API_ELASTIC_INDEXES = "/api/elastic_indexes";
|
|
3
|
+
export const API_ELASTIC_INDEX = "/api/elastic_indexes/:index_name";
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
import { useIntl } from "react-intl";
|
|
4
|
+
import { Button } from "semantic-ui-react";
|
|
5
|
+
import { ConfirmModal } from "@truedat/core/components";
|
|
6
|
+
import { useElasticIndexDelete } from "@truedat/se/hooks/useElasticIndexes";
|
|
7
|
+
|
|
8
|
+
export default function DeleteIndexButton({ indexName }) {
|
|
9
|
+
const { formatMessage } = useIntl();
|
|
10
|
+
const { trigger: deleteIndex, isMutating: loading } =
|
|
11
|
+
useElasticIndexDelete(indexName);
|
|
12
|
+
return (
|
|
13
|
+
<ConfirmModal
|
|
14
|
+
trigger={
|
|
15
|
+
<Button
|
|
16
|
+
disabled={loading}
|
|
17
|
+
content={formatMessage({
|
|
18
|
+
id: "elastic_index.delete",
|
|
19
|
+
})}
|
|
20
|
+
/>
|
|
21
|
+
}
|
|
22
|
+
header={formatMessage({
|
|
23
|
+
id: "elastic_index.delete.confirmation.header",
|
|
24
|
+
})}
|
|
25
|
+
content={formatMessage(
|
|
26
|
+
{ id: "elastic_index.delete.confirmation.content" },
|
|
27
|
+
{ index_name: indexName }
|
|
28
|
+
)}
|
|
29
|
+
onConfirm={deleteIndex}
|
|
30
|
+
/>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
DeleteIndexButton.propTypes = {
|
|
34
|
+
indexName: PropTypes.string,
|
|
35
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { FormattedMessage } from "react-intl";
|
|
3
|
+
import {
|
|
4
|
+
Header,
|
|
5
|
+
Icon,
|
|
6
|
+
Table,
|
|
7
|
+
Segment,
|
|
8
|
+
Dimmer,
|
|
9
|
+
Loader,
|
|
10
|
+
} from "semantic-ui-react";
|
|
11
|
+
import { useElasticIndexes } from "../hooks/useElasticIndexes";
|
|
12
|
+
import DeleteIndexButton from "./DeleteIndexButton";
|
|
13
|
+
|
|
14
|
+
export default function ElasticIndexes() {
|
|
15
|
+
const { indexes, loading } = useElasticIndexes();
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<Segment>
|
|
19
|
+
<Header as="h2">
|
|
20
|
+
<Icon circular name="check" />
|
|
21
|
+
<Header.Content>
|
|
22
|
+
<FormattedMessage id="elastic_index.header" />
|
|
23
|
+
<Header.Subheader>
|
|
24
|
+
<FormattedMessage id="elastic_index.subheader" />
|
|
25
|
+
</Header.Subheader>
|
|
26
|
+
</Header.Content>
|
|
27
|
+
</Header>
|
|
28
|
+
<Dimmer.Dimmable dimmed={loading}>
|
|
29
|
+
<Dimmer active={loading} inverted>
|
|
30
|
+
<Loader />
|
|
31
|
+
</Dimmer>
|
|
32
|
+
{indexes ? (
|
|
33
|
+
<Table>
|
|
34
|
+
<Table.Header>
|
|
35
|
+
<Table.Row>
|
|
36
|
+
<Table.HeaderCell
|
|
37
|
+
content={<FormattedMessage id={`elastic_index.key`} />}
|
|
38
|
+
/>
|
|
39
|
+
<Table.HeaderCell
|
|
40
|
+
content={<FormattedMessage id={`elastic_index.alias`} />}
|
|
41
|
+
/>
|
|
42
|
+
<Table.HeaderCell
|
|
43
|
+
content={<FormattedMessage id={`elastic_index.size`} />}
|
|
44
|
+
/>
|
|
45
|
+
<Table.HeaderCell
|
|
46
|
+
content={<FormattedMessage id={`elastic_index.documents`} />}
|
|
47
|
+
/>
|
|
48
|
+
<Table.HeaderCell
|
|
49
|
+
content={<FormattedMessage id={`elastic_index.action`} />}
|
|
50
|
+
/>
|
|
51
|
+
</Table.Row>
|
|
52
|
+
</Table.Header>
|
|
53
|
+
<Table.Body>
|
|
54
|
+
{indexes.map(({ key, alias, size, documents }) => (
|
|
55
|
+
<Table.Row key={key}>
|
|
56
|
+
<Table.Cell content={key} />
|
|
57
|
+
<Table.Cell content={alias} />
|
|
58
|
+
<Table.Cell content={size} />
|
|
59
|
+
<Table.Cell content={documents} />
|
|
60
|
+
<Table.Cell content={<DeleteIndexButton indexName={key} />} />
|
|
61
|
+
</Table.Row>
|
|
62
|
+
))}
|
|
63
|
+
</Table.Body>
|
|
64
|
+
</Table>
|
|
65
|
+
) : null}
|
|
66
|
+
</Dimmer.Dimmable>
|
|
67
|
+
</Segment>
|
|
68
|
+
);
|
|
69
|
+
}
|
|
@@ -5,62 +5,74 @@ import {
|
|
|
5
5
|
SEARCH_CONCEPTS,
|
|
6
6
|
SEARCH_INGESTS,
|
|
7
7
|
SEARCH_RESULTS,
|
|
8
|
-
SEARCH_STRUCTURES
|
|
8
|
+
SEARCH_STRUCTURES,
|
|
9
|
+
ELASTICINDEXES,
|
|
9
10
|
} from "@truedat/core/routes";
|
|
11
|
+
import { Unauthorized } from "@truedat/core/components";
|
|
12
|
+
import { useAuthorized } from "@truedat/core/hooks";
|
|
10
13
|
import SearchLoader from "./SearchLoader";
|
|
11
14
|
import SearchHome from "./SearchHome";
|
|
12
15
|
import Search from "./Search";
|
|
16
|
+
import ElasticIndexes from "./ElasticIndexes";
|
|
13
17
|
|
|
14
|
-
export const SearchRoutes = () =>
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
path={
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
18
|
+
export const SearchRoutes = () => {
|
|
19
|
+
const authorized = useAuthorized();
|
|
20
|
+
return (
|
|
21
|
+
<Route
|
|
22
|
+
path={SEARCH}
|
|
23
|
+
render={() => (
|
|
24
|
+
<>
|
|
25
|
+
<Route path={SEARCH} component={SearchLoader} exact />
|
|
26
|
+
<Route path={SEARCH} component={SearchHome} exact />
|
|
27
|
+
<Route
|
|
28
|
+
path={SEARCH_RESULTS}
|
|
29
|
+
exact
|
|
30
|
+
render={() => (
|
|
31
|
+
<>
|
|
32
|
+
<SearchLoader />
|
|
33
|
+
<Search />
|
|
34
|
+
</>
|
|
35
|
+
)}
|
|
36
|
+
/>
|
|
37
|
+
<Route
|
|
38
|
+
path={SEARCH_CONCEPTS}
|
|
39
|
+
exact
|
|
40
|
+
render={() => (
|
|
41
|
+
<>
|
|
42
|
+
<SearchLoader />
|
|
43
|
+
<Search />
|
|
44
|
+
</>
|
|
45
|
+
)}
|
|
46
|
+
/>
|
|
47
|
+
<Route
|
|
48
|
+
path={SEARCH_INGESTS}
|
|
49
|
+
exact
|
|
50
|
+
render={() => (
|
|
51
|
+
<>
|
|
52
|
+
<SearchLoader />
|
|
53
|
+
<Search />
|
|
54
|
+
</>
|
|
55
|
+
)}
|
|
56
|
+
/>
|
|
57
|
+
<Route
|
|
58
|
+
path={SEARCH_STRUCTURES}
|
|
59
|
+
exact
|
|
60
|
+
render={() => (
|
|
61
|
+
<>
|
|
62
|
+
<SearchLoader />
|
|
63
|
+
<Search />
|
|
64
|
+
</>
|
|
65
|
+
)}
|
|
66
|
+
/>
|
|
67
|
+
<Route
|
|
68
|
+
path={ELASTICINDEXES}
|
|
69
|
+
exact
|
|
70
|
+
render={() => (authorized ? <ElasticIndexes /> : <Unauthorized />)}
|
|
71
|
+
/>
|
|
72
|
+
</>
|
|
73
|
+
)}
|
|
74
|
+
/>
|
|
75
|
+
);
|
|
76
|
+
};
|
|
65
77
|
|
|
66
78
|
export default SearchRoutes;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render } from "@truedat/test/render";
|
|
3
|
+
import userEvent from "@testing-library/user-event";
|
|
4
|
+
import { useElasticIndexDelete } from "@truedat/se/hooks/useElasticIndexes";
|
|
5
|
+
import DeleteIndexButton from "../DeleteIndexButton";
|
|
6
|
+
import en from "../../messages/en";
|
|
7
|
+
|
|
8
|
+
jest.mock("@truedat/se/hooks/useElasticIndexes", () => {
|
|
9
|
+
const originalModule = jest.requireActual(
|
|
10
|
+
"@truedat/se/hooks/useElasticIndexes"
|
|
11
|
+
);
|
|
12
|
+
const trigger = jest.fn();
|
|
13
|
+
return {
|
|
14
|
+
__esModule: true,
|
|
15
|
+
...originalModule,
|
|
16
|
+
useElasticIndexDelete: jest.fn(() => ({
|
|
17
|
+
trigger,
|
|
18
|
+
isMutating: false,
|
|
19
|
+
})),
|
|
20
|
+
};
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const renderOpts = {
|
|
24
|
+
messages: {
|
|
25
|
+
en: {
|
|
26
|
+
...en,
|
|
27
|
+
"confirmation.yes": "yes",
|
|
28
|
+
"confirmation.no": "no",
|
|
29
|
+
"elastic_index.delete": "elastic_index.delete",
|
|
30
|
+
"elastic_index.delete.confirmation.header":
|
|
31
|
+
"elastic_index.delete.confirmation.header",
|
|
32
|
+
"elastic_index.delete.confirmation.content":
|
|
33
|
+
"elastic_index.delete.confirmation.content",
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
describe("<DeleteIndexButton />", () => {
|
|
39
|
+
const indexName = "test_index";
|
|
40
|
+
it("matches the last snapshot", () => {
|
|
41
|
+
const { container } = render(
|
|
42
|
+
<DeleteIndexButton indexName={indexName} />,
|
|
43
|
+
renderOpts
|
|
44
|
+
);
|
|
45
|
+
expect(container).toMatchSnapshot();
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it("triggers useElasticIndexDelete hook on confirm", () => {
|
|
49
|
+
const { getByRole } = render(
|
|
50
|
+
<DeleteIndexButton indexName={indexName} />,
|
|
51
|
+
renderOpts
|
|
52
|
+
);
|
|
53
|
+
userEvent.click(getByRole("button", { name: /delete/i }));
|
|
54
|
+
userEvent.click(getByRole("button", { name: "modal-affirmative-action" }));
|
|
55
|
+
|
|
56
|
+
expect(useElasticIndexDelete).toHaveBeenCalledWith(indexName);
|
|
57
|
+
const { trigger } = useElasticIndexDelete();
|
|
58
|
+
|
|
59
|
+
expect(trigger).toHaveBeenCalled();
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it("do not triggers useElasticIndexDelete hook on cancel", () => {
|
|
63
|
+
jest.clearAllMocks();
|
|
64
|
+
const { getByRole } = render(
|
|
65
|
+
<DeleteIndexButton indexName={indexName} />,
|
|
66
|
+
renderOpts
|
|
67
|
+
);
|
|
68
|
+
userEvent.click(getByRole("button", { name: /delete/i }));
|
|
69
|
+
userEvent.click(getByRole("button", { name: "modal-negative-action" }));
|
|
70
|
+
|
|
71
|
+
expect(useElasticIndexDelete).toHaveBeenCalledWith(indexName);
|
|
72
|
+
const { trigger } = useElasticIndexDelete();
|
|
73
|
+
expect(trigger).toHaveBeenCalledTimes(0);
|
|
74
|
+
});
|
|
75
|
+
});
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render } from "@truedat/test/render";
|
|
3
|
+
import ElasticIndexes from "../ElasticIndexes";
|
|
4
|
+
import en from "../../messages/en";
|
|
5
|
+
|
|
6
|
+
jest.mock("@truedat/se/hooks/useElasticIndexes", () => {
|
|
7
|
+
const originalModule = jest.requireActual(
|
|
8
|
+
"@truedat/se/hooks/useElasticIndexes"
|
|
9
|
+
);
|
|
10
|
+
return {
|
|
11
|
+
__esModule: true,
|
|
12
|
+
...originalModule,
|
|
13
|
+
useElasticIndexes: jest.fn(() => ({
|
|
14
|
+
indexes: [
|
|
15
|
+
{ key: "index_1", alias: "alias_1", size: 123456, documents: 5 },
|
|
16
|
+
{ key: "index_2", alias: "alias_2", size: 987654321, documents: 42 },
|
|
17
|
+
],
|
|
18
|
+
})),
|
|
19
|
+
};
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const renderOpts = {
|
|
23
|
+
messages: {
|
|
24
|
+
en: {
|
|
25
|
+
...en,
|
|
26
|
+
"elastic_index.action": "elastic_index.action",
|
|
27
|
+
"elastic_index.documents": "elastic_index.documents",
|
|
28
|
+
"elastic_index.size": "elastic_index.size",
|
|
29
|
+
"elastic_index.alias": "elastic_index.alias",
|
|
30
|
+
"elastic_index.key": "elastic_index.key",
|
|
31
|
+
"elastic_index.delete": "elastic_index.delete",
|
|
32
|
+
"elastic_index.header": "elastic_index.header",
|
|
33
|
+
"elastic_index.subheader": "elastic_index.subheader",
|
|
34
|
+
"elastic_index.delete.confirmation.header":
|
|
35
|
+
"elastic_index.delete.confirmation.header",
|
|
36
|
+
"elastic_index.delete.confirmation.content":
|
|
37
|
+
"elastic_index.delete.confirmation.content",
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
describe("<ElasticIndexes />", () => {
|
|
43
|
+
it("matches the last snapshot", () => {
|
|
44
|
+
const { container } = render(<ElasticIndexes />, renderOpts);
|
|
45
|
+
expect(container).toMatchSnapshot();
|
|
46
|
+
});
|
|
47
|
+
});
|
|
@@ -2,6 +2,10 @@ import React from "react";
|
|
|
2
2
|
import { shallow } from "enzyme";
|
|
3
3
|
import { SearchRoutes } from "../SearchRoutes";
|
|
4
4
|
|
|
5
|
+
jest.mock("@truedat/core/hooks", () => ({
|
|
6
|
+
useAuthorized: jest.fn(() => true),
|
|
7
|
+
}));
|
|
8
|
+
|
|
5
9
|
describe("<SearchRoutes />", () => {
|
|
6
10
|
it("matches the latest snapshot", () => {
|
|
7
11
|
const wrapper = shallow(<SearchRoutes />);
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`<ElasticIndexes /> matches the last snapshot 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<div
|
|
6
|
+
class="ui segment"
|
|
7
|
+
>
|
|
8
|
+
<h2
|
|
9
|
+
class="ui header"
|
|
10
|
+
>
|
|
11
|
+
<i
|
|
12
|
+
aria-hidden="true"
|
|
13
|
+
class="check circular icon"
|
|
14
|
+
/>
|
|
15
|
+
<div
|
|
16
|
+
class="content"
|
|
17
|
+
>
|
|
18
|
+
elastic_index.header
|
|
19
|
+
<div
|
|
20
|
+
class="sub header"
|
|
21
|
+
>
|
|
22
|
+
elastic_index.subheader
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
</h2>
|
|
26
|
+
<div
|
|
27
|
+
class="dimmable"
|
|
28
|
+
>
|
|
29
|
+
<div
|
|
30
|
+
class="ui inverted dimmer"
|
|
31
|
+
>
|
|
32
|
+
<div
|
|
33
|
+
class="content"
|
|
34
|
+
>
|
|
35
|
+
<div
|
|
36
|
+
class="ui loader"
|
|
37
|
+
/>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
<table
|
|
41
|
+
class="ui table"
|
|
42
|
+
>
|
|
43
|
+
<thead
|
|
44
|
+
class=""
|
|
45
|
+
>
|
|
46
|
+
<tr
|
|
47
|
+
class=""
|
|
48
|
+
>
|
|
49
|
+
<th
|
|
50
|
+
class=""
|
|
51
|
+
>
|
|
52
|
+
elastic_index.key
|
|
53
|
+
</th>
|
|
54
|
+
<th
|
|
55
|
+
class=""
|
|
56
|
+
>
|
|
57
|
+
elastic_index.alias
|
|
58
|
+
</th>
|
|
59
|
+
<th
|
|
60
|
+
class=""
|
|
61
|
+
>
|
|
62
|
+
elastic_index.size
|
|
63
|
+
</th>
|
|
64
|
+
<th
|
|
65
|
+
class=""
|
|
66
|
+
>
|
|
67
|
+
elastic_index.documents
|
|
68
|
+
</th>
|
|
69
|
+
<th
|
|
70
|
+
class=""
|
|
71
|
+
>
|
|
72
|
+
elastic_index.action
|
|
73
|
+
</th>
|
|
74
|
+
</tr>
|
|
75
|
+
</thead>
|
|
76
|
+
<tbody
|
|
77
|
+
class=""
|
|
78
|
+
>
|
|
79
|
+
<tr
|
|
80
|
+
class=""
|
|
81
|
+
>
|
|
82
|
+
<td
|
|
83
|
+
class=""
|
|
84
|
+
>
|
|
85
|
+
index_1
|
|
86
|
+
</td>
|
|
87
|
+
<td
|
|
88
|
+
class=""
|
|
89
|
+
>
|
|
90
|
+
alias_1
|
|
91
|
+
</td>
|
|
92
|
+
<td
|
|
93
|
+
class=""
|
|
94
|
+
>
|
|
95
|
+
123456
|
|
96
|
+
</td>
|
|
97
|
+
<td
|
|
98
|
+
class=""
|
|
99
|
+
>
|
|
100
|
+
5
|
|
101
|
+
</td>
|
|
102
|
+
<td
|
|
103
|
+
class=""
|
|
104
|
+
>
|
|
105
|
+
<button
|
|
106
|
+
class="ui button"
|
|
107
|
+
>
|
|
108
|
+
elastic_index.delete
|
|
109
|
+
</button>
|
|
110
|
+
</td>
|
|
111
|
+
</tr>
|
|
112
|
+
<tr
|
|
113
|
+
class=""
|
|
114
|
+
>
|
|
115
|
+
<td
|
|
116
|
+
class=""
|
|
117
|
+
>
|
|
118
|
+
index_2
|
|
119
|
+
</td>
|
|
120
|
+
<td
|
|
121
|
+
class=""
|
|
122
|
+
>
|
|
123
|
+
alias_2
|
|
124
|
+
</td>
|
|
125
|
+
<td
|
|
126
|
+
class=""
|
|
127
|
+
>
|
|
128
|
+
987654321
|
|
129
|
+
</td>
|
|
130
|
+
<td
|
|
131
|
+
class=""
|
|
132
|
+
>
|
|
133
|
+
42
|
|
134
|
+
</td>
|
|
135
|
+
<td
|
|
136
|
+
class=""
|
|
137
|
+
>
|
|
138
|
+
<button
|
|
139
|
+
class="ui button"
|
|
140
|
+
>
|
|
141
|
+
elastic_index.delete
|
|
142
|
+
</button>
|
|
143
|
+
</td>
|
|
144
|
+
</tr>
|
|
145
|
+
</tbody>
|
|
146
|
+
</table>
|
|
147
|
+
</div>
|
|
148
|
+
</div>
|
|
149
|
+
</div>
|
|
150
|
+
`;
|
package/src/components/index.js
CHANGED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import { compile } from "path-to-regexp";
|
|
3
|
+
import useSWR from "swr";
|
|
4
|
+
import useSWRMutations from "swr/mutation";
|
|
5
|
+
import { renderHook } from "@testing-library/react-hooks";
|
|
6
|
+
import { apiJson, apiJsonDelete, JSON_OPTS } from "@truedat/core/services/api";
|
|
7
|
+
import { API_ELASTIC_INDEXES, API_ELASTIC_INDEX } from "../../api";
|
|
8
|
+
import { useElasticIndexes, useElasticIndexDelete } from "../useElasticIndexes";
|
|
9
|
+
|
|
10
|
+
jest.mock("swr", () => ({
|
|
11
|
+
__esModule: true,
|
|
12
|
+
...jest.requireActual("swr"),
|
|
13
|
+
default: jest.fn(() => ({
|
|
14
|
+
data: {
|
|
15
|
+
data: {
|
|
16
|
+
data: [
|
|
17
|
+
{ index_name: "index1", size: 123456 },
|
|
18
|
+
{ index_name: "index2", size: 987654321 },
|
|
19
|
+
],
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
error: null,
|
|
23
|
+
mutate: jest.fn(),
|
|
24
|
+
})),
|
|
25
|
+
}));
|
|
26
|
+
|
|
27
|
+
jest.mock("swr/mutation", () => ({
|
|
28
|
+
__esModule: true,
|
|
29
|
+
...jest.requireActual("swr/mutation"),
|
|
30
|
+
default: jest.fn(),
|
|
31
|
+
}));
|
|
32
|
+
|
|
33
|
+
jest.mock("@truedat/core/services/api", () => ({
|
|
34
|
+
__esModule: true,
|
|
35
|
+
...jest.requireActual("@truedat/core/services/api"),
|
|
36
|
+
apiJsonDelete: jest.fn(),
|
|
37
|
+
}));
|
|
38
|
+
|
|
39
|
+
describe("useElasticIndexes", () => {
|
|
40
|
+
it("useElasticIndexes calls useSWR with correct api route", () => {
|
|
41
|
+
const { result } = renderHook(() => useElasticIndexes());
|
|
42
|
+
|
|
43
|
+
expect(result.current).toMatchObject({
|
|
44
|
+
indexes: [{ index_name: "index1" }, { index_name: "index2" }],
|
|
45
|
+
error: null,
|
|
46
|
+
loading: false,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
expect(useSWR).toHaveBeenCalledWith(API_ELASTIC_INDEXES, apiJson);
|
|
50
|
+
});
|
|
51
|
+
it("useElasticIndexes translates index size to megabytes", () => {
|
|
52
|
+
const { result } = renderHook(() => useElasticIndexes());
|
|
53
|
+
|
|
54
|
+
expect(result.current).toMatchObject({
|
|
55
|
+
indexes: [
|
|
56
|
+
{ index_name: "index1", size: "0.12" },
|
|
57
|
+
{ index_name: "index2", size: "941.90" },
|
|
58
|
+
],
|
|
59
|
+
error: null,
|
|
60
|
+
loading: false,
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
expect(useSWR).toHaveBeenCalledWith(API_ELASTIC_INDEXES, apiJson);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it("useElasticIndexDelete calls useSWRMutations with correct api route", () => {
|
|
67
|
+
const index_name = "index_name_1";
|
|
68
|
+
renderHook(() => useElasticIndexDelete(index_name));
|
|
69
|
+
const [url, func] = _.last(useSWRMutations.mock.calls);
|
|
70
|
+
|
|
71
|
+
expect(url).toBe(compile(API_ELASTIC_INDEX)({ index_name }));
|
|
72
|
+
func(url);
|
|
73
|
+
|
|
74
|
+
expect(apiJsonDelete).toHaveBeenCalledWith(url, JSON_OPTS);
|
|
75
|
+
});
|
|
76
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { compile } from "path-to-regexp";
|
|
2
|
+
import useSWR, { useSWRConfig } from "swr";
|
|
3
|
+
import useSWRMutations from "swr/mutation";
|
|
4
|
+
import { apiJson, apiJsonDelete, JSON_OPTS } from "@truedat/core/services/api";
|
|
5
|
+
import { API_ELASTIC_INDEXES, API_ELASTIC_INDEX } from "../api";
|
|
6
|
+
|
|
7
|
+
const sizeInMb = (indexes) => {
|
|
8
|
+
return indexes
|
|
9
|
+
? indexes.map((index) => ({
|
|
10
|
+
...index,
|
|
11
|
+
size: (index.size / (1024 * 1024)).toFixed(2),
|
|
12
|
+
}))
|
|
13
|
+
: indexes;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const useElasticIndexes = () => {
|
|
17
|
+
const { data, error, mutate } = useSWR(API_ELASTIC_INDEXES, apiJson);
|
|
18
|
+
|
|
19
|
+
const indexes = sizeInMb(data?.data?.data);
|
|
20
|
+
|
|
21
|
+
return { indexes, error, loading: !error && !data, mutate };
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const useElasticIndexDelete = (index_name) => {
|
|
25
|
+
const { mutate } = useSWRConfig();
|
|
26
|
+
const url = compile(API_ELASTIC_INDEX)({ index_name });
|
|
27
|
+
|
|
28
|
+
return useSWRMutations(
|
|
29
|
+
url,
|
|
30
|
+
(url) => {
|
|
31
|
+
apiJsonDelete(url, JSON_OPTS);
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
onSuccess: () => mutate(API_ELASTIC_INDEXES),
|
|
35
|
+
}
|
|
36
|
+
);
|
|
37
|
+
};
|
package/src/messages/en.js
CHANGED
package/src/messages/es.js
CHANGED