@truedat/dq 4.40.7 → 4.40.8

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.
Files changed (42) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/package.json +5 -5
  3. package/src/api.js +2 -0
  4. package/src/components/ExecutionDetails.js +65 -40
  5. package/src/components/ImplementationResultBar.js +1 -1
  6. package/src/components/NewRemediation.js +62 -0
  7. package/src/components/RemediationCrumbs.js +76 -0
  8. package/src/components/RemediationForm.js +129 -0
  9. package/src/components/RemediationPlan.js +161 -0
  10. package/src/components/RuleImplementation.js +1 -1
  11. package/src/components/RuleImplementationResults.js +2 -1
  12. package/src/components/RuleResultRow.js +4 -1
  13. package/src/components/RuleRoutes.js +324 -296
  14. package/src/components/__tests__/ExecutionDetails.spec.js +17 -5
  15. package/src/components/__tests__/RemediationForm.spec.js +68 -0
  16. package/src/components/__tests__/RemediationPlan.spec.js +106 -0
  17. package/src/components/__tests__/__snapshots__/ExecutionDetails.spec.js.snap +104 -0
  18. package/src/components/__tests__/__snapshots__/RemediationForm.spec.js.snap +19 -0
  19. package/src/components/__tests__/__snapshots__/RemediationPlan.spec.js.snap +3 -0
  20. package/src/messages/en.js +7 -0
  21. package/src/messages/es.js +7 -0
  22. package/src/reducers/__tests__/remediation.spec.js +83 -0
  23. package/src/reducers/__tests__/remediationActions.spec.js +46 -0
  24. package/src/reducers/__tests__/remediationLoading.spec.js +50 -0
  25. package/src/reducers/dqMessage.js +8 -2
  26. package/src/reducers/index.js +6 -0
  27. package/src/reducers/remediation.js +35 -0
  28. package/src/reducers/remediationActions.js +19 -0
  29. package/src/reducers/remediationLoading.js +29 -0
  30. package/src/routines.js +6 -0
  31. package/src/sagas/__tests__/createRemediation.spec.js +83 -0
  32. package/src/sagas/__tests__/deleteRemediation.spec.js +82 -0
  33. package/src/sagas/__tests__/fetchRemediation.spec.js +78 -0
  34. package/src/sagas/__tests__/fetchRuleImplementation.spec.js +1 -1
  35. package/src/sagas/__tests__/updateRemediation.spec.js +81 -0
  36. package/src/sagas/createRemediation.js +31 -0
  37. package/src/sagas/deleteRemediation.js +29 -0
  38. package/src/sagas/fetchRemediation.js +30 -0
  39. package/src/sagas/index.js +12 -0
  40. package/src/sagas/updateRemediation.js +29 -0
  41. package/src/styles/executionDetails.less +3 -0
  42. package/src/styles/remediationPlan.less +8 -0
@@ -0,0 +1,35 @@
1
+ import _ from "lodash/fp";
2
+ import {
3
+ fetchRemediation,
4
+ clearRemediation,
5
+ createRemediation,
6
+ updateRemediation,
7
+ deleteRemediation,
8
+ } from "../routines";
9
+
10
+ const initialState = {};
11
+
12
+ const remediation = (state = initialState, { type, payload }) => {
13
+ switch (type) {
14
+ case deleteRemediation.SUCCESS:
15
+ return initialState;
16
+ case clearRemediation.TRIGGER:
17
+ return initialState;
18
+ case fetchRemediation.TRIGGER:
19
+ return initialState;
20
+ case fetchRemediation.SUCCESS:
21
+ return _.prop("data")(payload);
22
+ case fetchRemediation.FAILURE:
23
+ return _.prop("status")(payload) === 404
24
+ ? state
25
+ : _.prop("data")(payload);
26
+ case createRemediation.SUCCESS:
27
+ return _.prop("data")(payload);
28
+ case updateRemediation.SUCCESS:
29
+ return _.prop("data")(payload);
30
+ default:
31
+ return state;
32
+ }
33
+ };
34
+
35
+ export { remediation };
@@ -0,0 +1,19 @@
1
+ import _ from "lodash/fp";
2
+ import { clearRemediation, fetchRemediation } from "../routines";
3
+
4
+ const initialState = {};
5
+
6
+ const remediationActions = (state = initialState, { type, payload }) => {
7
+ switch (type) {
8
+ case fetchRemediation.SUCCESS:
9
+ return _.pathOr(initialState, "_actions")(payload);
10
+ case clearRemediation.TRIGGER:
11
+ return initialState;
12
+ case fetchRemediation.TRIGGER:
13
+ return initialState;
14
+ default:
15
+ return state;
16
+ }
17
+ };
18
+
19
+ export { remediationActions };
@@ -0,0 +1,29 @@
1
+ import {
2
+ clearRemediation,
3
+ createRemediation,
4
+ fetchRemediation,
5
+ updateRemediation,
6
+ } from "../routines";
7
+
8
+ const remediationLoading = (state = true, { type }) => {
9
+ switch (type) {
10
+ case createRemediation.TRIGGER:
11
+ return true;
12
+ case createRemediation.FULFILL:
13
+ return false;
14
+ case updateRemediation.TRIGGER:
15
+ return true;
16
+ case updateRemediation.FULFILL:
17
+ return false;
18
+ case fetchRemediation.TRIGGER:
19
+ return true;
20
+ case fetchRemediation.FULFILL:
21
+ return false;
22
+ case clearRemediation.TRIGGER:
23
+ return true;
24
+ default:
25
+ return state;
26
+ }
27
+ };
28
+
29
+ export { remediationLoading };
package/src/routines.js CHANGED
@@ -6,6 +6,11 @@ export const clearRule = createRoutine("CLEAR_RULE");
6
6
  export const fetchRule = createRoutine("FETCH_RULE");
7
7
  export const updateRule = createRoutine("UPDATE_RULE");
8
8
 
9
+ export const createRemediation = createRoutine("CREATE_REMEDIATION");
10
+ export const updateRemediation = createRoutine("UPDATE_REMEDIATION");
11
+ export const clearRemediation = createRoutine("CLEAR_REMEDIATION");
12
+ export const deleteRemediation = createRoutine("DELETE_REMEDIATION");
13
+
9
14
  export const clearRuleImplementations = createRoutine(
10
15
  "CLEAR_RULE_IMPLEMENTATIONS"
11
16
  );
@@ -90,3 +95,4 @@ export const uploadResults = createRoutine("UPLOAD_RESULTS");
90
95
  export const createExecutionGroup = createRoutine("CREATE_EXECUTION_GROUP");
91
96
  export const fetchExecutionGroup = createRoutine("FETCH_EXECUTION_GROUP");
92
97
  export const clearExecutionGroup = createRoutine("CLEAR_EXECUTION_GROUP");
98
+ export const fetchRemediation = createRoutine("FETCH_REMEDIATION");
@@ -0,0 +1,83 @@
1
+ import { testSaga } from "redux-saga-test-plan";
2
+ import { apiJsonPost, JSON_OPTS } from "@truedat/core/services/api";
3
+ import { compile } from "path-to-regexp";
4
+ import {
5
+ createRemediationRequestSaga,
6
+ createRemediationSaga,
7
+ } from "../createRemediation";
8
+ import { createRemediation, fetchRuleImplementation } from "../../routines";
9
+ import { API_REMEDIATION_PLAN } from "../../api";
10
+
11
+ describe("sagas: createRemediationRequestSaga", () => {
12
+ it("should invoke createRemediationSaga on createRemediation.TRIGGER", () => {
13
+ expect(() => {
14
+ testSaga(createRemediationRequestSaga)
15
+ .next()
16
+ .takeLatest(createRemediation.TRIGGER, createRemediationSaga)
17
+ .finish()
18
+ .isDone();
19
+ }).not.toThrow();
20
+ });
21
+
22
+ it("should throw exception if an unhandled action is received", () => {
23
+ expect(() => {
24
+ testSaga(createRemediationRequestSaga)
25
+ .next()
26
+ .takeLatest("FOO", createRemediationSaga);
27
+ }).toThrow();
28
+ });
29
+ });
30
+
31
+ describe("sagas: createRemediationSaga", () => {
32
+ const implementationId = 1;
33
+ const ruleResultId = 1;
34
+ const remediation = {
35
+ id: 1,
36
+ df_name: "remediation_template",
37
+ df_content: { text: "some_text" },
38
+ };
39
+ const payload = {
40
+ remediation,
41
+ implementation_id: implementationId,
42
+ rule_result_id: ruleResultId,
43
+ };
44
+ const url = compile(API_REMEDIATION_PLAN)({ rule_result_id: ruleResultId });
45
+ const requestData = { remediation };
46
+
47
+ it("should put a success action when a response is returned", () => {
48
+ expect(() => {
49
+ testSaga(createRemediationSaga, { payload })
50
+ .next()
51
+ .put(createRemediation.request(remediation))
52
+ .next()
53
+ .call(apiJsonPost, url, requestData, JSON_OPTS)
54
+ .next({ data: remediation })
55
+ .put(createRemediation.success({ ...payload, ...remediation }))
56
+ .next()
57
+ .put(fetchRuleImplementation.trigger({ id: implementationId }))
58
+ .next()
59
+ .put(createRemediation.fulfill())
60
+ .next()
61
+ .isDone();
62
+ }).not.toThrow();
63
+ });
64
+
65
+ it("should put a failure action when the call returns an error", () => {
66
+ const message = "Request failed";
67
+ const error = { message };
68
+
69
+ expect(() => {
70
+ testSaga(createRemediationSaga, { payload })
71
+ .next()
72
+ .put(createRemediation.request(remediation))
73
+ .next()
74
+ .call(apiJsonPost, url, requestData, JSON_OPTS)
75
+ .throw(error)
76
+ .put(createRemediation.failure(message))
77
+ .next()
78
+ .put(createRemediation.fulfill())
79
+ .next()
80
+ .isDone();
81
+ }).not.toThrow();
82
+ });
83
+ });
@@ -0,0 +1,82 @@
1
+ import { testSaga } from "redux-saga-test-plan";
2
+ import { apiJsonDelete, JSON_OPTS } from "@truedat/core/services/api";
3
+ import { compile } from "path-to-regexp";
4
+ import {
5
+ deleteRemediationRequestSaga,
6
+ deleteRemediationSaga,
7
+ } from "../deleteRemediation";
8
+ import { deleteRemediation, fetchRuleImplementation } from "../../routines";
9
+ import { API_REMEDIATION_PLAN } from "../../api";
10
+
11
+ describe("sagas: deleteRemediationRequestSaga", () => {
12
+ it("should invoke deleteRemediationSaga on deleteRemediation.TRIGGER", () => {
13
+ expect(() => {
14
+ testSaga(deleteRemediationRequestSaga)
15
+ .next()
16
+ .takeLatest(deleteRemediation.TRIGGER, deleteRemediationSaga)
17
+ .finish()
18
+ .isDone();
19
+ }).not.toThrow();
20
+ });
21
+
22
+ it("should throw exception if an unhandled action is received", () => {
23
+ expect(() => {
24
+ testSaga(deleteRemediationRequestSaga)
25
+ .next()
26
+ .takeLatest("FOO", deleteRemediationSaga);
27
+ }).toThrow();
28
+ });
29
+ });
30
+
31
+ describe("sagas: deleteRemediationSaga", () => {
32
+ const ruleResultId = 1;
33
+ const implementationId = 1;
34
+ const remediation = {
35
+ id: 1,
36
+ df_name: "remediation_template",
37
+ df_content: { text: "some_text" },
38
+ };
39
+ const payload = {
40
+ remediation,
41
+ implementation_id: implementationId,
42
+ rule_result_id: ruleResultId,
43
+ };
44
+ const url = compile(API_REMEDIATION_PLAN)({ rule_result_id: ruleResultId });
45
+
46
+ it("should put a success action when a response is returned", () => {
47
+ expect(() => {
48
+ testSaga(deleteRemediationSaga, { payload })
49
+ .next()
50
+ .put(deleteRemediation.request(remediation))
51
+ .next()
52
+ .call(apiJsonDelete, url, JSON_OPTS)
53
+ .next({ data: remediation })
54
+ .put(deleteRemediation.success({ ...payload, ...remediation }))
55
+ .next()
56
+ .put(fetchRuleImplementation.trigger({ id: implementationId }))
57
+ .next()
58
+ .put(deleteRemediation.fulfill())
59
+ .next()
60
+ .isDone();
61
+ }).not.toThrow();
62
+ });
63
+
64
+ it("should put a failure action when the call returns an error", () => {
65
+ const message = "Request failed";
66
+ const error = { message };
67
+
68
+ expect(() => {
69
+ testSaga(deleteRemediationSaga, { payload })
70
+ .next()
71
+ .put(deleteRemediation.request(remediation))
72
+ .next()
73
+ .call(apiJsonDelete, url, JSON_OPTS)
74
+ .throw(error)
75
+ .put(deleteRemediation.failure(message))
76
+ .next()
77
+ .put(deleteRemediation.fulfill())
78
+ .next()
79
+ .isDone();
80
+ }).not.toThrow();
81
+ });
82
+ });
@@ -0,0 +1,78 @@
1
+ import { compile } from "path-to-regexp";
2
+ import { testSaga } from "redux-saga-test-plan";
3
+ import { apiJson, JSON_OPTS } from "@truedat/core/services/api";
4
+ import {
5
+ fetchRemediationRequestSaga,
6
+ fetchRemediationSaga,
7
+ } from "../fetchRemediation";
8
+ import { fetchRemediation } from "../../routines";
9
+ import { API_REMEDIATION_PLAN } from "../../api";
10
+
11
+ describe("sagas: fetchRemediationRequestSaga", () => {
12
+ it("should invoke fetchRemediationSaga on trigger", () => {
13
+ expect(() => {
14
+ testSaga(fetchRemediationRequestSaga)
15
+ .next()
16
+ .takeLatest(fetchRemediation.TRIGGER, fetchRemediationSaga)
17
+ .finish()
18
+ .isDone();
19
+ }).not.toThrow();
20
+ });
21
+
22
+ it("should throw exception if an unhandled action is received", () => {
23
+ expect(() => {
24
+ testSaga(fetchRemediationRequestSaga)
25
+ .next()
26
+ .takeLatest("FOO", fetchRemediationSaga);
27
+ }).toThrow();
28
+ });
29
+ });
30
+
31
+ describe("sagas: fetchRemediaitonSaga", () => {
32
+ it("should put a success action when a response is returned", () => {
33
+ const ruleResultId = 1;
34
+ const url = compile(API_REMEDIATION_PLAN)({ rule_result_id: ruleResultId });
35
+ const payload = { rule_result_id: ruleResultId };
36
+ const data = {
37
+ id: 1,
38
+ df_name: "remediation_template",
39
+ df_content: { text: "some_text" },
40
+ };
41
+
42
+ expect(() => {
43
+ testSaga(fetchRemediationSaga, { payload })
44
+ .next()
45
+ .put(fetchRemediation.request())
46
+ .next()
47
+ .call(apiJson, url, JSON_OPTS)
48
+ .next({ data })
49
+ .put(fetchRemediation.success(data))
50
+ .next()
51
+ .put(fetchRemediation.fulfill())
52
+ .next()
53
+ .isDone();
54
+ }).not.toThrow();
55
+ });
56
+
57
+ it("should put a failure action when the call returns an error", () => {
58
+ const message = "Request failed";
59
+ const error = { message };
60
+ const ruleResultId = 1;
61
+ const url = compile(API_REMEDIATION_PLAN)({ rule_result_id: ruleResultId });
62
+ const payload = { rule_result_id: ruleResultId };
63
+
64
+ expect(() => {
65
+ testSaga(fetchRemediationSaga, { payload })
66
+ .next()
67
+ .put(fetchRemediation.request())
68
+ .next()
69
+ .call(apiJson, url, JSON_OPTS)
70
+ .throw(error)
71
+ .put(fetchRemediation.failure(message))
72
+ .next()
73
+ .put(fetchRemediation.fulfill())
74
+ .next()
75
+ .isDone();
76
+ }).not.toThrow();
77
+ });
78
+ });
@@ -3,7 +3,7 @@ import { testSaga } from "redux-saga-test-plan";
3
3
  import { apiJson, JSON_OPTS } from "@truedat/core/services/api";
4
4
  import {
5
5
  fetchRuleImplementationRequestSaga,
6
- fetchRuleImplementationSaga
6
+ fetchRuleImplementationSaga,
7
7
  } from "../fetchRuleImplementation";
8
8
  import { fetchRuleImplementation } from "../../routines";
9
9
  import { API_RULE_IMPLEMENTATION } from "../../api";
@@ -0,0 +1,81 @@
1
+ import { testSaga } from "redux-saga-test-plan";
2
+ import { apiJsonPut, JSON_OPTS } from "@truedat/core/services/api";
3
+ import { compile } from "path-to-regexp";
4
+ import {
5
+ updateRemediationRequestSaga,
6
+ updateRemediationSaga,
7
+ } from "../updateRemediation";
8
+ import { updateRemediation } from "../../routines";
9
+ import { API_REMEDIATION_PLAN } from "../../api";
10
+
11
+ describe("sagas: updateRemediationRequestSaga", () => {
12
+ it("should invoke updateRemediationSaga on updateRemediation.TRIGGER", () => {
13
+ expect(() => {
14
+ testSaga(updateRemediationRequestSaga)
15
+ .next()
16
+ .takeLatest(updateRemediation.TRIGGER, updateRemediationSaga)
17
+ .finish()
18
+ .isDone();
19
+ }).not.toThrow();
20
+ });
21
+
22
+ it("should throw exception if an unhandled action is received", () => {
23
+ expect(() => {
24
+ testSaga(updateRemediationRequestSaga)
25
+ .next()
26
+ .takeLatest("FOO", updateRemediationSaga);
27
+ }).toThrow();
28
+ });
29
+ });
30
+
31
+ describe("sagas: updateRemediationSaga", () => {
32
+ const implementationId = 1;
33
+ const ruleResultId = 1;
34
+ const remediation = {
35
+ id: 1,
36
+ df_name: "remediation_template",
37
+ df_content: { text: "some_text" },
38
+ };
39
+ const payload = {
40
+ remediation,
41
+ implementation_id: implementationId,
42
+ rule_result_id: ruleResultId,
43
+ };
44
+ const url = compile(API_REMEDIATION_PLAN)({ rule_result_id: ruleResultId });
45
+ const requestData = { remediation };
46
+
47
+ it("should put a success action when a response is returned", () => {
48
+ expect(() => {
49
+ testSaga(updateRemediationSaga, { payload })
50
+ .next()
51
+ .put(updateRemediation.request(remediation))
52
+ .next()
53
+ .call(apiJsonPut, url, requestData, JSON_OPTS)
54
+ .next({ data: remediation })
55
+ .put(updateRemediation.success({ ...payload, ...remediation }))
56
+ .next()
57
+ .put(updateRemediation.fulfill())
58
+ .next()
59
+ .isDone();
60
+ }).not.toThrow();
61
+ });
62
+
63
+ it("should put a failure action when the call returns an error", () => {
64
+ const message = "Request failed";
65
+ const error = { message };
66
+
67
+ expect(() => {
68
+ testSaga(updateRemediationSaga, { payload })
69
+ .next()
70
+ .put(updateRemediation.request(remediation))
71
+ .next()
72
+ .call(apiJsonPut, url, requestData, JSON_OPTS)
73
+ .throw(error)
74
+ .put(updateRemediation.failure(message))
75
+ .next()
76
+ .put(updateRemediation.fulfill())
77
+ .next()
78
+ .isDone();
79
+ }).not.toThrow();
80
+ });
81
+ });
@@ -0,0 +1,31 @@
1
+ import { call, put, takeLatest } from "redux-saga/effects";
2
+ import { apiJsonPost, JSON_OPTS } from "@truedat/core/services/api";
3
+ import { compile } from "path-to-regexp";
4
+ import { createRemediation, fetchRuleImplementation } from "../routines";
5
+ import { API_REMEDIATION_PLAN } from "../api";
6
+
7
+ export function* createRemediationSaga({ payload }) {
8
+ const { remediation, implementation_id, rule_result_id } = payload;
9
+ try {
10
+ const requestData = { remediation };
11
+ const url = compile(API_REMEDIATION_PLAN)({ rule_result_id });
12
+ yield put(createRemediation.request(remediation));
13
+ const { data } = yield call(apiJsonPost, url, requestData, JSON_OPTS);
14
+ yield put(createRemediation.success({ ...payload, ...data }));
15
+ // Reload rule implementation so that it shows updated remediation icon
16
+ yield put(fetchRuleImplementation({ id: implementation_id }));
17
+ } catch (error) {
18
+ if (error.response) {
19
+ const { status, data } = error.response;
20
+ yield put(createRemediation.failure({ status, data }));
21
+ } else {
22
+ yield put(createRemediation.failure(error.message));
23
+ }
24
+ } finally {
25
+ yield put(createRemediation.fulfill());
26
+ }
27
+ }
28
+
29
+ export function* createRemediationRequestSaga() {
30
+ yield takeLatest(createRemediation.TRIGGER, createRemediationSaga);
31
+ }
@@ -0,0 +1,29 @@
1
+ import { call, put, takeLatest } from "redux-saga/effects";
2
+ import { apiJsonDelete, JSON_OPTS } from "@truedat/core/services/api";
3
+ import { compile } from "path-to-regexp";
4
+ import { deleteRemediation, fetchRuleImplementation } from "../routines";
5
+ import { API_REMEDIATION_PLAN } from "../api";
6
+
7
+ export function* deleteRemediationSaga({ payload }) {
8
+ try {
9
+ const { remediation, implementation_id, rule_result_id } = payload;
10
+ const url = compile(API_REMEDIATION_PLAN)({ rule_result_id });
11
+ yield put(deleteRemediation.request(remediation));
12
+ const { data } = yield call(apiJsonDelete, url, JSON_OPTS);
13
+ yield put(deleteRemediation.success({ ...payload, ...data }));
14
+ yield put(fetchRuleImplementation({ id: implementation_id }));
15
+ } catch (error) {
16
+ if (error.response) {
17
+ const { status, data } = error.response;
18
+ yield put(deleteRemediation.failure({ status, data }));
19
+ } else {
20
+ yield put(deleteRemediation.failure(error.message));
21
+ }
22
+ } finally {
23
+ yield put(deleteRemediation.fulfill());
24
+ }
25
+ }
26
+
27
+ export function* deleteRemediationRequestSaga() {
28
+ yield takeLatest(deleteRemediation.TRIGGER, deleteRemediationSaga);
29
+ }
@@ -0,0 +1,30 @@
1
+ import { compile } from "path-to-regexp";
2
+ import { call, put, takeLatest } from "redux-saga/effects";
3
+ import { apiJson, JSON_OPTS } from "@truedat/core/services/api";
4
+ import { fetchRemediation } from "../routines";
5
+ import { API_REMEDIATION_PLAN } from "../api";
6
+
7
+ export function* fetchRemediationSaga({ payload }) {
8
+ try {
9
+ const { rule_result_id } = payload;
10
+ const url = compile(API_REMEDIATION_PLAN)({
11
+ rule_result_id,
12
+ });
13
+ yield put(fetchRemediation.request());
14
+ const { data } = yield call(apiJson, url, JSON_OPTS);
15
+ yield put(fetchRemediation.success(data));
16
+ } catch (error) {
17
+ if (error.response) {
18
+ const { status, data } = error.response;
19
+ yield put(fetchRemediation.failure({ status, data }));
20
+ } else {
21
+ yield put(fetchRemediation.failure(error.message));
22
+ }
23
+ } finally {
24
+ yield put(fetchRemediation.fulfill());
25
+ }
26
+ }
27
+
28
+ export function* fetchRemediationRequestSaga() {
29
+ yield takeLatest(fetchRemediation.TRIGGER, fetchRemediationSaga);
30
+ }
@@ -1,12 +1,15 @@
1
1
  import { createExecutionGroupRequestSaga } from "./createExecutionGroup";
2
2
  import { createRuleImplementationRequestSaga } from "./createRuleImplementation";
3
+ import { createRemediationRequestSaga } from "./createRemediation";
3
4
  import { createRuleRequestSaga } from "./createRule";
4
5
  import { setRuleImplementationStatusRequestSaga } from "./setRuleImplementationStatus";
6
+ import { deleteRemediationRequestSaga } from "./deleteRemediation";
5
7
  import { deleteRuleRequestSaga } from "./deleteRule";
6
8
  import { deleteRuleResultRequestSaga } from "./deleteRuleResult";
7
9
  import { downloadRuleImplementationsRequestSaga } from "./downloadRuleImplementations";
8
10
  import { fetchConceptRulesRequestSaga } from "./fetchConceptRules";
9
11
  import { fetchExecutionGroupRequestSaga } from "./fetchExecutionGroup";
12
+ import { fetchRemediationRequestSaga } from "./fetchRemediation";
10
13
  import { fetchRuleFiltersRequestSaga } from "./fetchRuleFilters";
11
14
  import { fetchRuleImplementationFiltersRequestSaga } from "./fetchRuleImplementationFilters";
12
15
  import { fetchRuleImplementationRequestSaga } from "./fetchRuleImplementation";
@@ -14,6 +17,7 @@ import { fetchRuleImplementationsRequestSaga } from "./fetchRuleImplementations"
14
17
  import { fetchRuleRequestSaga } from "./fetchRule";
15
18
  import { fetchRulesRequestSaga } from "./fetchRules";
16
19
  import { searchRuleImplementationsRequestSaga } from "./searchRuleImplementations";
20
+ import { updateRemediationRequestSaga } from "./updateRemediation";
17
21
  import { uploadImplementationsRequestsSaga } from "./uploadImplementations";
18
22
  import { uploadRulesRequestsSaga } from "./uploadRules";
19
23
  import { updateRuleImplementationRequestSaga } from "./updateRuleImplementation";
@@ -22,14 +26,17 @@ import { uploadResultsRequestSaga } from "./uploadResults";
22
26
 
23
27
  export {
24
28
  createExecutionGroupRequestSaga,
29
+ createRemediationRequestSaga,
25
30
  createRuleImplementationRequestSaga,
26
31
  createRuleRequestSaga,
27
32
  setRuleImplementationStatusRequestSaga,
33
+ deleteRemediationRequestSaga,
28
34
  deleteRuleRequestSaga,
29
35
  deleteRuleResultRequestSaga,
30
36
  downloadRuleImplementationsRequestSaga,
31
37
  fetchConceptRulesRequestSaga,
32
38
  fetchExecutionGroupRequestSaga,
39
+ fetchRemediationRequestSaga,
33
40
  fetchRuleFiltersRequestSaga,
34
41
  fetchRuleImplementationFiltersRequestSaga,
35
42
  fetchRuleImplementationRequestSaga,
@@ -37,6 +44,7 @@ export {
37
44
  fetchRuleRequestSaga,
38
45
  fetchRulesRequestSaga,
39
46
  searchRuleImplementationsRequestSaga,
47
+ updateRemediationRequestSaga,
40
48
  uploadRulesRequestsSaga,
41
49
  uploadImplementationsRequestsSaga,
42
50
  updateRuleImplementationRequestSaga,
@@ -46,14 +54,17 @@ export {
46
54
 
47
55
  export default [
48
56
  createExecutionGroupRequestSaga(),
57
+ createRemediationRequestSaga(),
49
58
  createRuleImplementationRequestSaga(),
50
59
  createRuleRequestSaga(),
51
60
  setRuleImplementationStatusRequestSaga(),
61
+ deleteRemediationRequestSaga(),
52
62
  deleteRuleRequestSaga(),
53
63
  deleteRuleResultRequestSaga(),
54
64
  downloadRuleImplementationsRequestSaga(),
55
65
  fetchConceptRulesRequestSaga(),
56
66
  fetchExecutionGroupRequestSaga(),
67
+ fetchRemediationRequestSaga(),
57
68
  fetchRuleFiltersRequestSaga(),
58
69
  fetchRuleImplementationFiltersRequestSaga(),
59
70
  fetchRuleImplementationRequestSaga(),
@@ -61,6 +72,7 @@ export default [
61
72
  fetchRuleRequestSaga(),
62
73
  fetchRulesRequestSaga(),
63
74
  searchRuleImplementationsRequestSaga(),
75
+ updateRemediationRequestSaga(),
64
76
  uploadRulesRequestsSaga(),
65
77
  uploadImplementationsRequestsSaga(),
66
78
  updateRuleImplementationRequestSaga(),
@@ -0,0 +1,29 @@
1
+ import { call, put, takeLatest } from "redux-saga/effects";
2
+ import { apiJsonPut, JSON_OPTS } from "@truedat/core/services/api";
3
+ import { compile } from "path-to-regexp";
4
+ import { updateRemediation } from "../routines";
5
+ import { API_REMEDIATION_PLAN } from "../api";
6
+
7
+ export function* updateRemediationSaga({ payload }) {
8
+ try {
9
+ const { remediation, rule_result_id } = payload;
10
+ const requestData = { remediation };
11
+ const url = compile(API_REMEDIATION_PLAN)({ rule_result_id });
12
+ yield put(updateRemediation.request(remediation));
13
+ const { data } = yield call(apiJsonPut, url, requestData, JSON_OPTS);
14
+ yield put(updateRemediation.success({ ...payload, ...data }));
15
+ } catch (error) {
16
+ if (error.response) {
17
+ const { status, data } = error.response;
18
+ yield put(updateRemediation.failure({ status, data }));
19
+ } else {
20
+ yield put(updateRemediation.failure(error.message));
21
+ }
22
+ } finally {
23
+ yield put(updateRemediation.fulfill());
24
+ }
25
+ }
26
+
27
+ export function* updateRemediationRequestSaga() {
28
+ yield takeLatest(updateRemediation.TRIGGER, updateRemediationSaga);
29
+ }
@@ -0,0 +1,3 @@
1
+ .ui.segment.execution-details-remediation {
2
+ margin-top: 1rem;
3
+ }
@@ -0,0 +1,8 @@
1
+ .ui.button.button-edit-remediation {
2
+ float: right;
3
+ margin-left: 5px;
4
+ }
5
+
6
+ .ui.actions.remediation {
7
+ float: right;
8
+ }