@truedat/dq 7.11.0 → 7.11.2
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 +3 -3
- package/src/api.js +12 -0
- package/src/components/ImplementationSearchResults.js +24 -42
- package/src/components/ImplementationUploadJobBreadcrumbs.js +25 -0
- package/src/components/Implementations.js +31 -17
- package/src/components/ImplementationsRoutes.js +9 -0
- package/src/components/ImplementationsUploadButton.js +38 -50
- package/src/components/ImplementationsUploadJob.js +217 -0
- package/src/components/ImplementationsUploadJobs.js +128 -0
- package/src/components/RuleFormImplementations.js +29 -10
- package/src/components/RuleImplementationActions.js +10 -20
- package/src/components/RuleImplementationsActions.js +15 -37
- package/src/components/RuleImplementationsDownload.js +26 -31
- package/src/components/RuleImplementationsDownloadXlsx.js +47 -0
- package/src/components/RuleImplementationsLabelResults.js +30 -39
- package/src/components/RuleImplementationsOptions.js +5 -3
- package/src/components/RuleImplementationsTable.js +7 -3
- package/src/components/RuleRoutes.js +1 -4
- package/src/components/SimpleRuleImplementationsTable.js +68 -0
- package/src/components/__tests__/ImplementationSearchResults.spec.js +32 -4
- package/src/components/__tests__/ImplementationUploadJobBreadcrumbs.spec.js +28 -0
- package/src/components/__tests__/Implementations.spec.js +43 -0
- package/src/components/__tests__/ImplementationsUploadButton.spec.js +67 -40
- package/src/components/__tests__/ImplementationsUploadJob.spec.js +112 -0
- package/src/components/__tests__/ImplementationsUploadJobs.spec.js +60 -0
- package/src/components/__tests__/RuleImplementationsActions.spec.js +71 -56
- package/src/components/__tests__/RuleImplementationsOptions.spec.js +28 -3
- package/src/components/__tests__/RuleImplementationsTable.spec.js +24 -0
- package/src/components/__tests__/__snapshots__/ImplementationSearchResults.spec.js.snap +113 -46
- package/src/components/__tests__/__snapshots__/ImplementationUploadJobBreadcrumbs.spec.js.snap +42 -0
- package/src/components/__tests__/__snapshots__/Implementations.spec.js.snap +125 -24
- package/src/components/__tests__/__snapshots__/RuleImplementationsActions.spec.js.snap +4 -8
- package/src/components/__tests__/__snapshots__/RuleImplementationsOptions.spec.js.snap +5 -8
- package/src/components/__tests__/implementationsUploadJobParser.spec.js +105 -0
- package/src/components/implementationsUploadJobParser.js +276 -0
- package/src/components/index.js +0 -2
- package/src/hooks/useImplementations.js +80 -0
- package/src/reducers/index.js +2 -0
- package/src/reducers/ruleImplementationSelectedFilter.js +1 -1
- package/src/reducers/ruleImplementationsDownloadingXlsx.js +14 -0
- package/src/routines.js +3 -0
- package/src/sagas/downloadRuleImplementationsXlsx.js +52 -0
- package/src/sagas/index.js +3 -0
- package/src/components/RuleImplementationFilters.js +0 -25
- package/src/components/RuleImplementationSelectedFilters.js +0 -99
- package/src/components/RuleImplementationsFromRuleLoader.js +0 -60
- package/src/components/RuleImplementationsPagination.js +0 -18
- package/src/components/RuleImplementationsSearch.js +0 -39
- package/src/components/__tests__/RuleImplementationsFromRuleLoader.spec.js +0 -63
- package/src/components/__tests__/RuleImplementationsSearch.spec.js +0 -29
- package/src/components/__tests__/__snapshots__/RuleImplementationsFromRuleLoader.spec.js.snap +0 -3
- package/src/components/__tests__/__snapshots__/RuleImplementationsSearch.spec.js.snap +0 -50
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { compile } from "path-to-regexp";
|
|
2
|
+
import useSWR from "swr";
|
|
3
|
+
import useSWRMutations from "swr/mutation";
|
|
4
|
+
import FileSaver from "file-saver";
|
|
5
|
+
import {
|
|
6
|
+
apiJson,
|
|
7
|
+
apiJsonPost,
|
|
8
|
+
JSON_OPTS,
|
|
9
|
+
UPLOAD_JSON_OPTS,
|
|
10
|
+
} from "@truedat/core/services/api";
|
|
11
|
+
import {
|
|
12
|
+
API_RULE_IMPLEMENTATIONS_SEARCH,
|
|
13
|
+
API_RULE_IMPLEMENTATION_FILTERS_SEARCH,
|
|
14
|
+
API_RULE_IMPLEMENTATIONS_XLSX_DOWNLOAD,
|
|
15
|
+
API_RULE_IMPLEMENTATIONS_XLSX_UPLOAD,
|
|
16
|
+
API_RULE_IMPLEMENTATIONS_XLSX_UPLOAD_JOBS,
|
|
17
|
+
API_RULE_IMPLEMENTATIONS_XLSX_UPLOAD_JOB,
|
|
18
|
+
} from "../api";
|
|
19
|
+
|
|
20
|
+
function saveFile({ data, headers }) {
|
|
21
|
+
const contentDisposition = headers["content-disposition"];
|
|
22
|
+
const regex = /filename=(.+)$/;
|
|
23
|
+
const match = regex.exec(contentDisposition);
|
|
24
|
+
const fileName = match ? match[1] : "structures.xlsx";
|
|
25
|
+
|
|
26
|
+
FileSaver.saveAs(data, fileName);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const useRuleImplementationFilters = () => {
|
|
30
|
+
return useSWRMutations(
|
|
31
|
+
API_RULE_IMPLEMENTATION_FILTERS_SEARCH,
|
|
32
|
+
(url, { arg }) => {
|
|
33
|
+
return apiJsonPost(url, arg);
|
|
34
|
+
}
|
|
35
|
+
);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const useRuleImplementationSearch = () => {
|
|
39
|
+
return useSWRMutations(API_RULE_IMPLEMENTATIONS_SEARCH, (url, { arg }) => {
|
|
40
|
+
return apiJsonPost(url, arg);
|
|
41
|
+
});
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export const useImplementationsDownload = () => {
|
|
45
|
+
return useSWRMutations(
|
|
46
|
+
API_RULE_IMPLEMENTATIONS_XLSX_DOWNLOAD,
|
|
47
|
+
(url, { arg }) => {
|
|
48
|
+
return apiJsonPost(url, arg, { ...JSON_OPTS, responseType: "blob" }).then(
|
|
49
|
+
({ data, headers }) => {
|
|
50
|
+
saveFile({ data, headers });
|
|
51
|
+
}
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
);
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export const useImplementationsUpload = () => {
|
|
58
|
+
return useSWRMutations(
|
|
59
|
+
API_RULE_IMPLEMENTATIONS_XLSX_UPLOAD,
|
|
60
|
+
(url, { arg }) => {
|
|
61
|
+
return apiJsonPost(url, arg, UPLOAD_JSON_OPTS);
|
|
62
|
+
}
|
|
63
|
+
);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export const useImplementationsUploadJobs = () => {
|
|
67
|
+
const { data, error, mutate } = useSWR(
|
|
68
|
+
API_RULE_IMPLEMENTATIONS_XLSX_UPLOAD_JOBS,
|
|
69
|
+
apiJson
|
|
70
|
+
);
|
|
71
|
+
return { data: data?.data, error, loading: !error && !data, mutate };
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export const useImplementationsUploadJob = (id) => {
|
|
75
|
+
const url = compile(API_RULE_IMPLEMENTATIONS_XLSX_UPLOAD_JOB)({
|
|
76
|
+
id: `${id}`,
|
|
77
|
+
});
|
|
78
|
+
const { data, error, mutate } = useSWR(url, apiJson);
|
|
79
|
+
return { data: data?.data, error, loading: !error && !data, mutate };
|
|
80
|
+
};
|
package/src/reducers/index.js
CHANGED
|
@@ -32,6 +32,7 @@ import { ruleImplementationSaving } from "./ruleImplementationSaving";
|
|
|
32
32
|
import { ruleImplementationSelectedFilter } from "./ruleImplementationSelectedFilter";
|
|
33
33
|
import { ruleImplementations } from "./ruleImplementations";
|
|
34
34
|
import { ruleImplementationsDownloading } from "./ruleImplementationsDownloading";
|
|
35
|
+
import { ruleImplementationsDownloadingXlsx } from "./ruleImplementationsDownloadingXlsx";
|
|
35
36
|
import { ruleImplementationsLoading } from "./ruleImplementationsLoading";
|
|
36
37
|
import { ruleImplementationsPageSize } from "./ruleImplementationsPageSize";
|
|
37
38
|
import { ruleLoading } from "./ruleLoading";
|
|
@@ -83,6 +84,7 @@ export {
|
|
|
83
84
|
ruleImplementationSelectedFilter,
|
|
84
85
|
ruleImplementations,
|
|
85
86
|
ruleImplementationsDownloading,
|
|
87
|
+
ruleImplementationsDownloadingXlsx,
|
|
86
88
|
ruleImplementationsLoading,
|
|
87
89
|
ruleImplementationsPageSize,
|
|
88
90
|
ruleLoading,
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { downloadImplementationsXlsx } from "../routines";
|
|
2
|
+
|
|
3
|
+
const ruleImplementationsDownloadingXlsx = (state = false, { type }) => {
|
|
4
|
+
switch (type) {
|
|
5
|
+
case downloadImplementationsXlsx.TRIGGER:
|
|
6
|
+
return true;
|
|
7
|
+
case downloadImplementationsXlsx.FULFILL:
|
|
8
|
+
return false;
|
|
9
|
+
default:
|
|
10
|
+
return state;
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export { ruleImplementationsDownloadingXlsx };
|
package/src/routines.js
CHANGED
|
@@ -47,6 +47,9 @@ export const deprecateImplementation = createRoutine("CREATE_IMPLEMENTATION");
|
|
|
47
47
|
export const downloadImplementations = createRoutine(
|
|
48
48
|
"DOWNLOAD_IMPLEMENTATIONS"
|
|
49
49
|
);
|
|
50
|
+
export const downloadImplementationsXlsx = createRoutine(
|
|
51
|
+
"DOWNLOAD_IMPLEMENTATIONS_XLSX"
|
|
52
|
+
);
|
|
50
53
|
export const fetchConceptRules = createRoutine("FETCH_CONCEPT_RULES");
|
|
51
54
|
export const fetchExecutionGroup = createRoutine("FETCH_EXECUTION_GROUP");
|
|
52
55
|
export const fetchImplementationFilters = createRoutine(
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import FileSaver from "file-saver";
|
|
3
|
+
import { call, put, select, takeLatest } from "redux-saga/effects";
|
|
4
|
+
import { apiJsonPost, JSON_OPTS } from "@truedat/core/services/api";
|
|
5
|
+
import { downloadImplementationsXlsx } from "../routines";
|
|
6
|
+
import { getPreviousRuleImplementationQuery } from "../selectors";
|
|
7
|
+
import { API_RULE_IMPLEMENTATIONS_XLSX_DOWNLOAD } from "../api";
|
|
8
|
+
|
|
9
|
+
export function saveFile(data) {
|
|
10
|
+
if (!_.isEmpty(data)) {
|
|
11
|
+
const blob = new Blob([String.fromCharCode(0xfeff), data], {
|
|
12
|
+
type: "text/csv;charset=utf-8",
|
|
13
|
+
});
|
|
14
|
+
FileSaver.saveAs(blob, "implementations.csv");
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function* downloadRuleImplementationsXlsxSaga({ payload }) {
|
|
19
|
+
try {
|
|
20
|
+
const headerLabels = _.propOr({}, "headerLabels")(payload);
|
|
21
|
+
const contentLabels = _.propOr({}, "contentLabels")(payload);
|
|
22
|
+
const lang = _.propOr("es", "lang")(payload);
|
|
23
|
+
const query = yield select(getPreviousRuleImplementationQuery);
|
|
24
|
+
const body = {
|
|
25
|
+
header_labels: headerLabels,
|
|
26
|
+
content_labels: contentLabels,
|
|
27
|
+
lang,
|
|
28
|
+
...query,
|
|
29
|
+
};
|
|
30
|
+
const url = API_RULE_IMPLEMENTATIONS_XLSX_DOWNLOAD;
|
|
31
|
+
yield put(downloadImplementationsXlsx.request(body));
|
|
32
|
+
const { data } = yield call(apiJsonPost, url, body, JSON_OPTS);
|
|
33
|
+
yield call(saveFile, data);
|
|
34
|
+
yield put(downloadImplementationsXlsx.success(data));
|
|
35
|
+
} catch (error) {
|
|
36
|
+
if (error.response) {
|
|
37
|
+
const { status, data } = error.response;
|
|
38
|
+
yield put(downloadImplementationsXlsx.failure({ status, data }));
|
|
39
|
+
} else {
|
|
40
|
+
yield put(downloadImplementationsXlsx.failure(error.message));
|
|
41
|
+
}
|
|
42
|
+
} finally {
|
|
43
|
+
yield put(downloadImplementationsXlsx.fulfill());
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function* downloadRuleImplementationsXlsxRequestSaga() {
|
|
48
|
+
yield takeLatest(
|
|
49
|
+
downloadImplementationsXlsx.TRIGGER,
|
|
50
|
+
downloadRuleImplementationsXlsxSaga
|
|
51
|
+
);
|
|
52
|
+
}
|
package/src/sagas/index.js
CHANGED
|
@@ -9,6 +9,7 @@ import { deleteRemediationRequestSaga } from "./deleteRemediation";
|
|
|
9
9
|
import { deleteRuleRequestSaga } from "./deleteRule";
|
|
10
10
|
import { deleteRuleResultRequestSaga } from "./deleteRuleResult";
|
|
11
11
|
import { downloadRuleImplementationsRequestSaga } from "./downloadRuleImplementations";
|
|
12
|
+
import { downloadRuleImplementationsXlsxRequestSaga } from "./downloadRuleImplementationsXlsx";
|
|
12
13
|
import { fetchConceptRulesRequestSaga } from "./fetchConceptRules";
|
|
13
14
|
import { fetchExecutionGroupRequestSaga } from "./fetchExecutionGroup";
|
|
14
15
|
import { fetchRemediationRequestSaga } from "./fetchRemediation";
|
|
@@ -43,6 +44,7 @@ export {
|
|
|
43
44
|
deleteRuleRequestSaga,
|
|
44
45
|
deleteRuleResultRequestSaga,
|
|
45
46
|
downloadRuleImplementationsRequestSaga,
|
|
47
|
+
downloadRuleImplementationsXlsxRequestSaga,
|
|
46
48
|
fetchConceptRulesRequestSaga,
|
|
47
49
|
fetchExecutionGroupRequestSaga,
|
|
48
50
|
fetchRemediationRequestSaga,
|
|
@@ -78,6 +80,7 @@ export default [
|
|
|
78
80
|
deleteRuleRequestSaga(),
|
|
79
81
|
deleteRuleResultRequestSaga(),
|
|
80
82
|
downloadRuleImplementationsRequestSaga(),
|
|
83
|
+
downloadRuleImplementationsXlsxRequestSaga(),
|
|
81
84
|
fetchConceptRulesRequestSaga(),
|
|
82
85
|
fetchExecutionGroupRequestSaga(),
|
|
83
86
|
fetchRemediationRequestSaga(),
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { connect } from "react-redux";
|
|
2
|
-
import { bindActionCreators } from "redux";
|
|
3
|
-
import { AvailableFilters } from "@truedat/core/components";
|
|
4
|
-
import {
|
|
5
|
-
addImplementationFilter,
|
|
6
|
-
resetImplementationFilters,
|
|
7
|
-
} from "../routines";
|
|
8
|
-
import { getRuleImplementationAvailableFilters } from "../selectors";
|
|
9
|
-
|
|
10
|
-
const mapStateToProps = (state) => ({
|
|
11
|
-
filters: getRuleImplementationAvailableFilters(state),
|
|
12
|
-
disabled: state.ruleFiltersLoading,
|
|
13
|
-
loading: state.ruleFiltersLoading,
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
const mapDispatchToProps = (dispatch) =>
|
|
17
|
-
bindActionCreators(
|
|
18
|
-
{
|
|
19
|
-
addFilter: addImplementationFilter,
|
|
20
|
-
resetFilters: resetImplementationFilters,
|
|
21
|
-
},
|
|
22
|
-
dispatch
|
|
23
|
-
);
|
|
24
|
-
|
|
25
|
-
export default connect(mapStateToProps, mapDispatchToProps)(AvailableFilters);
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import _ from "lodash/fp";
|
|
2
|
-
import { bindActionCreators, compose } from "redux";
|
|
3
|
-
import { connect } from "react-redux";
|
|
4
|
-
import { injectIntl } from "react-intl";
|
|
5
|
-
import { makeOption } from "@truedat/core/services/i18n";
|
|
6
|
-
import { SelectedFilters, StructureFilterItem } from "@truedat/core/components";
|
|
7
|
-
import { StructuresLoader } from "@truedat/dd/components";
|
|
8
|
-
|
|
9
|
-
import {
|
|
10
|
-
applyUserSearchFilter,
|
|
11
|
-
deleteUserSearchFilter,
|
|
12
|
-
saveUserSearchFilters,
|
|
13
|
-
searchStructures,
|
|
14
|
-
} from "@truedat/dd/routines";
|
|
15
|
-
import {
|
|
16
|
-
closeImplementationFilter,
|
|
17
|
-
openImplementationFilter,
|
|
18
|
-
removeImplementationFilter,
|
|
19
|
-
resetImplementationFilters,
|
|
20
|
-
toggleImplementationFilterValue,
|
|
21
|
-
} from "../routines";
|
|
22
|
-
|
|
23
|
-
import {
|
|
24
|
-
getRuleImplementationSelectedFilterActiveValues,
|
|
25
|
-
getRuleImplementationSelectedFilters,
|
|
26
|
-
getRuleImplementationSelectedFilterValues,
|
|
27
|
-
getRuleImplementationFilterTypes,
|
|
28
|
-
} from "../selectors";
|
|
29
|
-
|
|
30
|
-
const translations = (formatMessage) => ({
|
|
31
|
-
"execution_result_info.result_text": (v) =>
|
|
32
|
-
formatMessage({ id: v, defaultMessage: v }),
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
export const mapStateToProps = (state, ownProps) => {
|
|
36
|
-
const formatMessage = _.pathOr(_.prop("id"), "intl.formatMessage")(ownProps);
|
|
37
|
-
const {
|
|
38
|
-
ruleImplementationFiltersLoading: loading,
|
|
39
|
-
ruleImplementationSelectedFilter: selectedFilter,
|
|
40
|
-
} = state;
|
|
41
|
-
const i18nValues = _.flow(
|
|
42
|
-
getRuleImplementationSelectedFilterValues,
|
|
43
|
-
_.map(makeOption(translations(formatMessage), selectedFilter))
|
|
44
|
-
)(state);
|
|
45
|
-
|
|
46
|
-
const {
|
|
47
|
-
selectedUserSearchFilter: selectedUserFilter,
|
|
48
|
-
ruleImplementationActiveFilters: activeFilters,
|
|
49
|
-
userSearchFilters: userFilters,
|
|
50
|
-
} = state;
|
|
51
|
-
|
|
52
|
-
const searchFiltersPropsMapping = {
|
|
53
|
-
linked_structures_ids: {
|
|
54
|
-
query: state.structureQuery?.query,
|
|
55
|
-
searchCallback: searchStructures,
|
|
56
|
-
options: state.structures,
|
|
57
|
-
placeholder: formatMessage({ id: "structures.search.placeholder" }),
|
|
58
|
-
FilterDataLoader: StructuresLoader,
|
|
59
|
-
loaderProps: { pageSize: 50 },
|
|
60
|
-
FilterItem: StructureFilterItem,
|
|
61
|
-
},
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
return {
|
|
65
|
-
loading,
|
|
66
|
-
filterTypes: getRuleImplementationFilterTypes(state),
|
|
67
|
-
selectedFilter,
|
|
68
|
-
selectedFilters: getRuleImplementationSelectedFilters(state),
|
|
69
|
-
selectedFilterActiveValues:
|
|
70
|
-
getRuleImplementationSelectedFilterActiveValues(state),
|
|
71
|
-
selectedFilterValues: i18nValues,
|
|
72
|
-
selectedUserFilter,
|
|
73
|
-
activeFilters,
|
|
74
|
-
userFilters,
|
|
75
|
-
userFilterScope: "rule_implementation",
|
|
76
|
-
searchFiltersPropsMapping,
|
|
77
|
-
};
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
const mapDispatchToProps = (dispatch) =>
|
|
81
|
-
bindActionCreators(
|
|
82
|
-
{
|
|
83
|
-
applyUserFilter: applyUserSearchFilter,
|
|
84
|
-
closeFilter: closeImplementationFilter,
|
|
85
|
-
deleteUserFilter: deleteUserSearchFilter,
|
|
86
|
-
openFilter: openImplementationFilter,
|
|
87
|
-
removeFilter: removeImplementationFilter,
|
|
88
|
-
resetFilters: resetImplementationFilters,
|
|
89
|
-
toggleFilterValue: toggleImplementationFilterValue,
|
|
90
|
-
saveFilters: saveUserSearchFilters,
|
|
91
|
-
searchFilterDispacher: (searchCall) => dispatch(searchCall),
|
|
92
|
-
},
|
|
93
|
-
dispatch
|
|
94
|
-
);
|
|
95
|
-
|
|
96
|
-
export default compose(
|
|
97
|
-
injectIntl,
|
|
98
|
-
connect(mapStateToProps, mapDispatchToProps)
|
|
99
|
-
)(SelectedFilters);
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { useEffect } from "react";
|
|
2
|
-
import { useParams } from "react-router";
|
|
3
|
-
import PropTypes from "prop-types";
|
|
4
|
-
import { connect } from "react-redux";
|
|
5
|
-
import { Dimmer, Loader } from "semantic-ui-react";
|
|
6
|
-
import {
|
|
7
|
-
clearRuleImplementations,
|
|
8
|
-
fetchRuleImplementations,
|
|
9
|
-
} from "../routines";
|
|
10
|
-
|
|
11
|
-
export const RuleImplementationsFromRuleLoader = ({
|
|
12
|
-
clearRuleImplementations,
|
|
13
|
-
fetchRuleImplementations,
|
|
14
|
-
ruleImplementationsLoading,
|
|
15
|
-
}) => {
|
|
16
|
-
const { id } = useParams();
|
|
17
|
-
useEffect(() => {
|
|
18
|
-
if (id) {
|
|
19
|
-
fetchRuleImplementations({
|
|
20
|
-
id,
|
|
21
|
-
filters: {
|
|
22
|
-
must_not: {
|
|
23
|
-
status: ["versioned"],
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
}, [clearRuleImplementations, fetchRuleImplementations, id]);
|
|
29
|
-
|
|
30
|
-
useEffect(() => {
|
|
31
|
-
return () => {
|
|
32
|
-
clearRuleImplementations();
|
|
33
|
-
};
|
|
34
|
-
}, [clearRuleImplementations]);
|
|
35
|
-
return ruleImplementationsLoading ? (
|
|
36
|
-
<Dimmer active={ruleImplementationsLoading} inverted>
|
|
37
|
-
<Loader size="massive" inverted />
|
|
38
|
-
</Dimmer>
|
|
39
|
-
) : null;
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
RuleImplementationsFromRuleLoader.propTypes = {
|
|
43
|
-
clearRuleImplementations: PropTypes.func,
|
|
44
|
-
fetchRuleImplementations: PropTypes.func,
|
|
45
|
-
ruleImplementationsLoading: PropTypes.bool,
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
const mapDispatchToProps = {
|
|
49
|
-
clearRuleImplementations,
|
|
50
|
-
fetchRuleImplementations,
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
const mapStateToProps = ({ ruleImplementationsLoading }) => ({
|
|
54
|
-
ruleImplementationsLoading,
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
export default connect(
|
|
58
|
-
mapStateToProps,
|
|
59
|
-
mapDispatchToProps
|
|
60
|
-
)(RuleImplementationsFromRuleLoader);
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { connect } from "react-redux";
|
|
2
|
-
import { bindActionCreators } from "redux";
|
|
3
|
-
import { Pagination } from "@truedat/core/components";
|
|
4
|
-
import { selectImplementationPage } from "../routines";
|
|
5
|
-
|
|
6
|
-
const mapDispatchToProps = (dispatch) =>
|
|
7
|
-
bindActionCreators({ selectPage: selectImplementationPage }, dispatch);
|
|
8
|
-
|
|
9
|
-
const mapStateToProps = ({
|
|
10
|
-
ruleImplementationQuery,
|
|
11
|
-
ruleImplementationCount,
|
|
12
|
-
ruleImplementationsPageSize,
|
|
13
|
-
}) => ({
|
|
14
|
-
activePage: ruleImplementationQuery?.page,
|
|
15
|
-
totalPages: Math.ceil(ruleImplementationCount / ruleImplementationsPageSize),
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
export default connect(mapStateToProps, mapDispatchToProps)(Pagination);
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import PropTypes from "prop-types";
|
|
2
|
-
import { connect } from "react-redux";
|
|
3
|
-
import { Input } from "semantic-ui-react";
|
|
4
|
-
import { useIntl } from "react-intl";
|
|
5
|
-
import { searchImplementations } from "../routines";
|
|
6
|
-
import RuleImplementationFilters from "./RuleImplementationFilters";
|
|
7
|
-
|
|
8
|
-
export const RuleImplementationsSearch = ({
|
|
9
|
-
query,
|
|
10
|
-
searchImplementations,
|
|
11
|
-
loading,
|
|
12
|
-
}) => {
|
|
13
|
-
const { formatMessage } = useIntl();
|
|
14
|
-
return (
|
|
15
|
-
<Input
|
|
16
|
-
value={query}
|
|
17
|
-
onChange={(_e, data) => searchImplementations({ query: data.value })}
|
|
18
|
-
icon={{ name: "search", link: true }}
|
|
19
|
-
iconPosition="left"
|
|
20
|
-
action={<RuleImplementationFilters />}
|
|
21
|
-
placeholder={formatMessage({ id: "implementations.search.placeholder" })}
|
|
22
|
-
loading={loading}
|
|
23
|
-
/>
|
|
24
|
-
);
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
RuleImplementationsSearch.propTypes = {
|
|
28
|
-
query: PropTypes.string,
|
|
29
|
-
searchImplementations: PropTypes.func,
|
|
30
|
-
loading: PropTypes.bool,
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
const mapStateToProps = ({ ruleImplementationQuery }) => ({
|
|
34
|
-
query: ruleImplementationQuery?.query,
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
export default connect(mapStateToProps, { searchImplementations })(
|
|
38
|
-
RuleImplementationsSearch
|
|
39
|
-
);
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { useParams } from "react-router";
|
|
2
|
-
import { render, waitForLoad } from "@truedat/test/render";
|
|
3
|
-
import { RuleImplementationsFromRuleLoader } from "../RuleImplementationsFromRuleLoader";
|
|
4
|
-
|
|
5
|
-
jest.mock("react-router", () => ({
|
|
6
|
-
...jest.requireActual("react-router"),
|
|
7
|
-
useParams: jest.fn(),
|
|
8
|
-
}));
|
|
9
|
-
|
|
10
|
-
afterEach(() => {
|
|
11
|
-
jest.clearAllMocks();
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
describe("<RuleImplementationsFromRuleLoader />", () => {
|
|
15
|
-
const fetchRuleImplementations = jest.fn();
|
|
16
|
-
const clearRuleImplementations = jest.fn();
|
|
17
|
-
const deletionQuery = { deleted: false };
|
|
18
|
-
|
|
19
|
-
const props = {
|
|
20
|
-
deletionQuery,
|
|
21
|
-
fetchRuleImplementations,
|
|
22
|
-
clearRuleImplementations,
|
|
23
|
-
ruleImplementationsLoading: false,
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
beforeEach(() => {
|
|
27
|
-
useParams.mockImplementation(() => ({ id: 1 }));
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
it("matches the latest snapshot", async () => {
|
|
31
|
-
const rendered = render(<RuleImplementationsFromRuleLoader {...props} />);
|
|
32
|
-
await waitForLoad(rendered);
|
|
33
|
-
expect(rendered.container).toMatchSnapshot();
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it("calls fetchRuleImplementations when component mounts, clearRuleImplementations when component unmounts", async () => {
|
|
37
|
-
const rendered = render(<RuleImplementationsFromRuleLoader {...props} />);
|
|
38
|
-
await waitForLoad(rendered);
|
|
39
|
-
|
|
40
|
-
expect(clearRuleImplementations).toHaveBeenCalledTimes(0);
|
|
41
|
-
expect(fetchRuleImplementations).toHaveBeenCalledTimes(1);
|
|
42
|
-
expect(fetchRuleImplementations).toHaveBeenCalledWith({
|
|
43
|
-
id: 1,
|
|
44
|
-
filters: { must_not: { status: ["versioned"] } },
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
rendered.unmount();
|
|
48
|
-
expect(clearRuleImplementations).toHaveBeenCalledTimes(1);
|
|
49
|
-
expect(fetchRuleImplementations).toHaveBeenCalledTimes(1);
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it("renders dimmer when rule implementations loading", async () => {
|
|
53
|
-
const rendered = render(
|
|
54
|
-
<RuleImplementationsFromRuleLoader
|
|
55
|
-
{...props}
|
|
56
|
-
ruleImplementationsLoading
|
|
57
|
-
/>
|
|
58
|
-
);
|
|
59
|
-
expect(
|
|
60
|
-
rendered.container.querySelector(".dimmer.active")
|
|
61
|
-
).toBeInTheDocument();
|
|
62
|
-
});
|
|
63
|
-
});
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import userEvent from "@testing-library/user-event";
|
|
2
|
-
import { render, waitForLoad } from "@truedat/test/render";
|
|
3
|
-
import { RuleImplementationsSearch } from "../RuleImplementationsSearch";
|
|
4
|
-
|
|
5
|
-
describe("<RuleImplementationsSearch/>", () => {
|
|
6
|
-
it("matches the latest snapshot", async () => {
|
|
7
|
-
const searchImplementations = jest.fn();
|
|
8
|
-
const loading = false;
|
|
9
|
-
const query = "";
|
|
10
|
-
const props = { searchImplementations, loading, query };
|
|
11
|
-
const rendered = render(<RuleImplementationsSearch {...props} />);
|
|
12
|
-
await waitForLoad(rendered);
|
|
13
|
-
expect(rendered.container).toMatchSnapshot();
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
it("dispatches onChange when Input changes", async () => {
|
|
17
|
-
const searchImplementations = jest.fn();
|
|
18
|
-
const loading = false;
|
|
19
|
-
const query = "";
|
|
20
|
-
const props = { searchImplementations, loading, query };
|
|
21
|
-
const rendered = render(<RuleImplementationsSearch {...props} />);
|
|
22
|
-
await waitForLoad(rendered);
|
|
23
|
-
|
|
24
|
-
const user = userEvent.setup({ delay: null });
|
|
25
|
-
await user.type(rendered.getByRole("textbox"), "test");
|
|
26
|
-
|
|
27
|
-
expect(searchImplementations).toHaveBeenCalled();
|
|
28
|
-
});
|
|
29
|
-
});
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
-
|
|
3
|
-
exports[`<RuleImplementationsSearch/> matches the latest snapshot 1`] = `
|
|
4
|
-
<div>
|
|
5
|
-
<div
|
|
6
|
-
class="ui action left icon input"
|
|
7
|
-
>
|
|
8
|
-
<input
|
|
9
|
-
placeholder="implementations.search.placeholder"
|
|
10
|
-
type="text"
|
|
11
|
-
value=""
|
|
12
|
-
/>
|
|
13
|
-
<i
|
|
14
|
-
aria-hidden="true"
|
|
15
|
-
class="search link icon"
|
|
16
|
-
/>
|
|
17
|
-
<div
|
|
18
|
-
aria-expanded="false"
|
|
19
|
-
class="ui button floating labeled scrolling dropdown icon"
|
|
20
|
-
role="listbox"
|
|
21
|
-
tabindex="0"
|
|
22
|
-
>
|
|
23
|
-
<div
|
|
24
|
-
aria-atomic="true"
|
|
25
|
-
aria-live="polite"
|
|
26
|
-
class="divider text"
|
|
27
|
-
role="alert"
|
|
28
|
-
>
|
|
29
|
-
Filters
|
|
30
|
-
</div>
|
|
31
|
-
<i
|
|
32
|
-
aria-hidden="true"
|
|
33
|
-
class="filter icon"
|
|
34
|
-
/>
|
|
35
|
-
<div
|
|
36
|
-
class="menu transition"
|
|
37
|
-
>
|
|
38
|
-
<div
|
|
39
|
-
class="item"
|
|
40
|
-
role="option"
|
|
41
|
-
>
|
|
42
|
-
<em>
|
|
43
|
-
(reset filters)
|
|
44
|
-
</em>
|
|
45
|
-
</div>
|
|
46
|
-
</div>
|
|
47
|
-
</div>
|
|
48
|
-
</div>
|
|
49
|
-
</div>
|
|
50
|
-
`;
|