datastake-daf 0.6.846 → 0.6.847
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/build/favicon.ico +0 -0
- package/build/logo192.png +0 -0
- package/build/logo512.png +0 -0
- package/build/manifest.json +25 -0
- package/build/robots.txt +3 -0
- package/dist/components/index.js +58 -16
- package/dist/hooks/index.js +10 -12
- package/dist/pages/index.js +4543 -4120
- package/dist/style/datastake/mapbox-gl.css +330 -0
- package/dist/utils/index.js +1 -9
- package/package.json +1 -1
- package/src/@daf/core/components/Screens/Admin/AdminModals/NewUser/index.jsx +1 -1
- package/src/@daf/core/components/Screens/Admin/AdminTables/AccountTable/helper.js +77 -59
- package/src/@daf/core/components/Screens/Admin/AdminViews/index.jsx +8 -1
- package/src/@daf/hooks/useSources.js +4 -6
- package/src/@daf/hooks/useWidgetFetch.js +40 -34
- package/src/@daf/pages/Dashboards/ConflictManagement/components/RisksWidget/components/IncidentsTime/config.js +0 -3
- package/src/@daf/pages/Dashboards/ConflictManagement/components/RisksWidget/components/IncidentsTime/hook.js +4 -69
- package/src/@daf/pages/Dashboards/ConflictManagement/components/RisksWidget/components/IncidentsTime/index.js +92 -29
- package/src/@daf/pages/Dashboards/ConflictManagement/components/RisksWidget/components/ProblemSolver/hook.js +34 -59
- package/src/@daf/pages/Dashboards/ConflictManagement/components/RisksWidget/components/ProblemSolver/index.js +69 -36
- package/src/@daf/pages/Dashboards/ConflictManagement/components/RisksWidget/components/TerritorialDistribution/index.js +75 -50
- package/src/@daf/pages/Dashboards/ConflictManagement/index.js +11 -11
- package/src/@daf/pages/Dashboards/SupplyChain/components/ChartsContainer/components/GenderDistribution/index.js +51 -46
- package/src/@daf/pages/Dashboards/SupplyChain/components/ChartsContainer/components/Identification/hook.js +20 -20
- package/src/@daf/pages/Dashboards/SupplyChain/components/ChartsContainer/components/Identification/index.js +2 -26
- package/src/@daf/pages/Dashboards/SupplyChain/index.jsx +1 -0
- package/src/@daf/pages/Dashboards/UserDashboard/components/DataChainOfCustody/index.jsx +1 -2
- package/src/@daf/pages/Dashboards/UserDashboard/index.jsx +0 -1
- package/src/@daf/pages/Dashboards/helper.js +20 -25
- package/src/@daf/utils/timeFilterUtils.js +250 -233
- package/src/constants/locales/fr/translation.js +0 -9
- package/src/constants/locales/sp/translation.js +0 -1
- package/src/@daf/pages/Dashboards/ConflictManagement/components/RisksWidget/components/TerritorialDistribution/hook.js +0 -56
|
@@ -1,74 +1,15 @@
|
|
|
1
|
-
import { useMemo, useState
|
|
1
|
+
import { useMemo, useState } from "react";
|
|
2
2
|
import useTimelineBase from "./config.js";
|
|
3
|
-
|
|
3
|
+
|
|
4
4
|
export default function useIncidentsTimeline({
|
|
5
5
|
t,
|
|
6
6
|
language,
|
|
7
7
|
severityOptions = [],
|
|
8
8
|
selectedRange = "12",
|
|
9
|
-
selectedPartners = {},
|
|
10
|
-
user,
|
|
11
9
|
}) {
|
|
12
10
|
const [filters, setFilters] = useState({ severity: "all" });
|
|
13
|
-
const { baseMonths, baseWeeks, mergeWithData } = useTimelineBase({ language, selectedRange });
|
|
14
|
-
|
|
15
|
-
const getSourceParam = useCallback(
|
|
16
|
-
(sourceId) => {
|
|
17
|
-
if (user?.company?.id !== sourceId) return `?sourceId=${sourceId}`;
|
|
18
|
-
return "";
|
|
19
|
-
},
|
|
20
|
-
[user?.company?.id]
|
|
21
|
-
);
|
|
22
|
-
const severityColors = useMemo(
|
|
23
|
-
() => ({
|
|
24
|
-
major: "#cf1322",
|
|
25
|
-
minor: "#fadb14",
|
|
26
|
-
moderate: "#fa8c16",
|
|
27
|
-
undetermined: "#999999",
|
|
28
|
-
placeholder: "transparent",
|
|
29
|
-
}),
|
|
30
|
-
[]
|
|
31
|
-
);
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const renderSeverity = (val) => {
|
|
35
|
-
if (val === "major")
|
|
36
|
-
return <span style={{ color: severityColors.major }}>{t("Major")}</span>;
|
|
37
|
-
if (val === "minor")
|
|
38
|
-
return <span style={{ color: severityColors.minor }}>{t("Minor")}</span>;
|
|
39
|
-
if (val === "moderate")
|
|
40
|
-
return (
|
|
41
|
-
<span style={{ color: severityColors.moderate }}>{t("Moderate")}</span>
|
|
42
|
-
);
|
|
43
|
-
return <span>{t("Undetermined")}</span>;
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const categories = useMemo(() => {
|
|
47
|
-
if (selectedRange === "12") return baseMonths.map((m) => m.label);
|
|
48
|
-
return baseWeeks.map((w) => w.label);
|
|
49
|
-
}, [selectedRange, baseMonths, baseWeeks]);
|
|
50
|
-
|
|
51
|
-
const defaultFetchConfig = useMemo(
|
|
52
|
-
() => ({
|
|
53
|
-
url: `/incidents-timeline`,
|
|
54
|
-
filters: {
|
|
55
|
-
...filters,
|
|
56
|
-
severity: filters.severity ? filters.severity : "all",
|
|
57
|
-
period: selectedRange,
|
|
58
|
-
sources: selectedPartners?.partners || [],
|
|
59
|
-
},
|
|
60
|
-
defaultData: [],
|
|
61
|
-
stop: selectedPartners?.loading,
|
|
62
|
-
}),
|
|
63
|
-
[filters, selectedRange, selectedPartners]
|
|
64
|
-
);
|
|
65
|
-
|
|
66
|
-
const getIncidentsTimelineData = useCallback(
|
|
67
|
-
({ url, filters }) =>
|
|
68
|
-
DashboardService.getWidgetConflictManagement(url, filters),
|
|
69
|
-
[]
|
|
70
|
-
);
|
|
71
11
|
|
|
12
|
+
const { baseMonths, baseWeeks, mergeWithData } = useTimelineBase({ language, selectedRange });
|
|
72
13
|
|
|
73
14
|
const filtersConfig = useMemo(
|
|
74
15
|
() => ({
|
|
@@ -102,12 +43,6 @@ export default function useIncidentsTimeline({
|
|
|
102
43
|
setFilters,
|
|
103
44
|
baseMonths,
|
|
104
45
|
baseWeeks,
|
|
105
|
-
mergeWithData
|
|
106
|
-
defaultFetchConfig,
|
|
107
|
-
getSourceParam,
|
|
108
|
-
getIncidentsTimelineData,
|
|
109
|
-
severityColors,
|
|
110
|
-
renderSeverity,
|
|
111
|
-
categories,
|
|
46
|
+
mergeWithData
|
|
112
47
|
};
|
|
113
48
|
}
|
|
@@ -1,26 +1,27 @@
|
|
|
1
|
-
import { useMemo } from "react";
|
|
1
|
+
import { useMemo, useCallback } from "react";
|
|
2
2
|
import Widget from "../../../../../../../core/components/Dashboard/Widget/index.jsx";
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
4
|
import useIncidentsTimeline from "./hook.js";
|
|
5
5
|
import { useWidgetFetch } from "../../../../../../../hooks/useWidgetFetch.js";
|
|
6
|
+
import DashboardService from "../../../../../../../services/DashboardService.js";
|
|
6
7
|
import { renderDateFormatted } from "../../../../../../../../helpers/Forms.js";
|
|
7
8
|
import StackChart from "../../../../../../../core/components/Charts/StackChart/index.jsx";
|
|
9
|
+
|
|
8
10
|
export default function IncidentsTimeline({
|
|
9
11
|
selectedRange,
|
|
12
|
+
selectedPartners = {},
|
|
10
13
|
t,
|
|
11
14
|
language,
|
|
12
15
|
goTo,
|
|
16
|
+
user,
|
|
13
17
|
options,
|
|
14
18
|
}) {
|
|
15
19
|
const {
|
|
20
|
+
filters,
|
|
16
21
|
filtersConfig,
|
|
17
|
-
defaultFetchConfig,
|
|
18
|
-
getSourceParam,
|
|
19
|
-
getIncidentsTimelineData,
|
|
20
22
|
mergeWithData,
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
categories,
|
|
23
|
+
baseMonths,
|
|
24
|
+
baseWeeks,
|
|
24
25
|
} = useIncidentsTimeline({
|
|
25
26
|
t,
|
|
26
27
|
language,
|
|
@@ -28,13 +29,96 @@ export default function IncidentsTimeline({
|
|
|
28
29
|
selectedRange,
|
|
29
30
|
});
|
|
30
31
|
|
|
32
|
+
const getSourceParam = useCallback(
|
|
33
|
+
(sourceId) => {
|
|
34
|
+
if (user?.company?.id !== sourceId) return `?sourceId=${sourceId}`;
|
|
35
|
+
return "";
|
|
36
|
+
},
|
|
37
|
+
[user?.company?.id]
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
const severityColors = useMemo(
|
|
41
|
+
() => ({
|
|
42
|
+
major: "#cf1322",
|
|
43
|
+
minor: "#fadb14",
|
|
44
|
+
moderate: "#fa8c16",
|
|
45
|
+
undetermined: "#999999",
|
|
46
|
+
placeholder: "transparent",
|
|
47
|
+
}),
|
|
48
|
+
[]
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
const defaultFetchConfig = useMemo(
|
|
52
|
+
() => ({
|
|
53
|
+
url: `/incidents-timeline`,
|
|
54
|
+
filters: {
|
|
55
|
+
...filters,
|
|
56
|
+
severity: filters.severity ? filters.severity : "all",
|
|
57
|
+
period: selectedRange,
|
|
58
|
+
sources: selectedPartners?.partners || [],
|
|
59
|
+
},
|
|
60
|
+
defaultData: [],
|
|
61
|
+
stop: selectedPartners?.loading,
|
|
62
|
+
}),
|
|
63
|
+
[filters, selectedRange, selectedPartners]
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
const getIncidentsTimelineData = useCallback(
|
|
67
|
+
({ url, filters }) =>
|
|
68
|
+
DashboardService.getWidgetConflictManagement(url, filters),
|
|
69
|
+
[]
|
|
70
|
+
);
|
|
71
|
+
|
|
31
72
|
const { data, loading } = useWidgetFetch({
|
|
32
73
|
config: defaultFetchConfig,
|
|
33
74
|
getData: getIncidentsTimelineData,
|
|
34
75
|
});
|
|
76
|
+
|
|
77
|
+
const renderSeverity = (val) => {
|
|
78
|
+
if (val === "major")
|
|
79
|
+
return <span style={{ color: severityColors.major }}>{t("Major")}</span>;
|
|
80
|
+
if (val === "minor")
|
|
81
|
+
return <span style={{ color: severityColors.minor }}>{t("Minor")}</span>;
|
|
82
|
+
if (val === "moderate")
|
|
83
|
+
return (
|
|
84
|
+
<span style={{ color: severityColors.moderate }}>{t("Moderate")}</span>
|
|
85
|
+
);
|
|
86
|
+
return <span>{t("Undetermined")}</span>;
|
|
87
|
+
};
|
|
88
|
+
|
|
35
89
|
const chartData = useMemo(() => mergeWithData(data), [data, mergeWithData]);
|
|
36
90
|
|
|
91
|
+
const categories = useMemo(() => {
|
|
92
|
+
if (selectedRange === "12") return baseMonths.map((m) => m.label);
|
|
93
|
+
return baseWeeks.map((w) => w.label);
|
|
94
|
+
}, [selectedRange, baseMonths, baseWeeks]);
|
|
95
|
+
console.log({filtersConfig})
|
|
37
96
|
|
|
97
|
+
const getTooltipContent = useCallback(
|
|
98
|
+
({ item }) => {
|
|
99
|
+
if (!item) return { title: "", items: [] };
|
|
100
|
+
|
|
101
|
+
return {
|
|
102
|
+
title: item.name || item.label || t("Undetermined"),
|
|
103
|
+
subTitle: renderDateFormatted(item.date, "DD MMM YYYY"),
|
|
104
|
+
link: true,
|
|
105
|
+
onClickLink: () => {
|
|
106
|
+
goTo(
|
|
107
|
+
`/app/view/incidents/${item.datastakeId}/identification${getSourceParam(
|
|
108
|
+
item?.sourceId
|
|
109
|
+
)}`
|
|
110
|
+
);
|
|
111
|
+
},
|
|
112
|
+
items: [
|
|
113
|
+
{ label: t("nashiriki::Source"), value: item?.source || "--" },
|
|
114
|
+
item.severity
|
|
115
|
+
? { label: t("Severity"), value: renderSeverity(item.severity) }
|
|
116
|
+
: null,
|
|
117
|
+
].filter(Boolean),
|
|
118
|
+
};
|
|
119
|
+
},
|
|
120
|
+
[t, goTo, getSourceParam, renderSeverity]
|
|
121
|
+
);
|
|
38
122
|
|
|
39
123
|
return (
|
|
40
124
|
<Widget
|
|
@@ -51,28 +135,7 @@ export default function IncidentsTimeline({
|
|
|
51
135
|
seriesField="severity"
|
|
52
136
|
colors={severityColors}
|
|
53
137
|
doConstraints={false}
|
|
54
|
-
renderTooltip={
|
|
55
|
-
if (!item) return { title: "", items: [] };
|
|
56
|
-
|
|
57
|
-
return {
|
|
58
|
-
title: item.name || item.label || t("Undetermined"),
|
|
59
|
-
subTitle: renderDateFormatted(item.date, "DD MMM YYYY"),
|
|
60
|
-
link: true,
|
|
61
|
-
onClickLink: () => {
|
|
62
|
-
goTo(
|
|
63
|
-
`/app/view/incidents/${item.datastakeId}/identification${getSourceParam(
|
|
64
|
-
item?.sourceId
|
|
65
|
-
)}`
|
|
66
|
-
);
|
|
67
|
-
},
|
|
68
|
-
items: [
|
|
69
|
-
{ label: t("nashiriki::Source"), value: item?.source || "--" },
|
|
70
|
-
item.severity
|
|
71
|
-
? { label: t("Severity"), value: renderSeverity(item.severity) }
|
|
72
|
-
: null,
|
|
73
|
-
].filter(Boolean),
|
|
74
|
-
};
|
|
75
|
-
}}
|
|
138
|
+
renderTooltip={getTooltipContent}
|
|
76
139
|
/>
|
|
77
140
|
</div>
|
|
78
141
|
</Widget>
|
|
@@ -1,77 +1,55 @@
|
|
|
1
1
|
import { useEffect, useMemo, useState } from "react";
|
|
2
2
|
import DashboardService from "../../../../../../../services/DashboardService.js";
|
|
3
|
-
import { useWidgetFetch } from "../../../../../../../hooks/useWidgetFetch.js";
|
|
4
3
|
|
|
5
|
-
const distributionColors = ["#3061A8", "#6698E4", "#A6C3EF", "#D6E3F8", "#E6EEFB"];
|
|
6
4
|
|
|
7
|
-
export default function useProblemSolvers({ t = () => {}
|
|
5
|
+
export default function useProblemSolvers({ t = () => {} } = {}) {
|
|
8
6
|
const [filters, setFilters] = useState({
|
|
9
7
|
administrativeLevel1: "all",
|
|
10
8
|
});
|
|
11
9
|
|
|
12
10
|
const [filterOptions, setFilterOptions] = useState([]);
|
|
13
11
|
|
|
14
|
-
const defaultFetchConfig = useMemo(
|
|
15
|
-
() => ({
|
|
16
|
-
url: "/problem-solvers",
|
|
17
|
-
basepath: "dashboard/conflict-management",
|
|
18
|
-
filters: {
|
|
19
|
-
...filters,
|
|
20
|
-
period: selectedRange,
|
|
21
|
-
sources: selectedPartners?.partners || [],
|
|
22
|
-
},
|
|
23
|
-
stop: selectedPartners?.loading,
|
|
24
|
-
}),
|
|
25
|
-
[filters, selectedRange, selectedPartners],
|
|
26
|
-
);
|
|
27
|
-
|
|
28
|
-
const { data, loading } = useWidgetFetch({ config: defaultFetchConfig });
|
|
29
12
|
|
|
30
13
|
useEffect(() => {
|
|
31
|
-
|
|
14
|
+
async function fetchOptions() {
|
|
15
|
+
try {
|
|
16
|
+
const { data } = await DashboardService.getWidgetConflictManagement(
|
|
17
|
+
"/problem-solvers",
|
|
18
|
+
{},
|
|
19
|
+
"dashboard/conflict-management"
|
|
20
|
+
);
|
|
32
21
|
|
|
33
|
-
|
|
34
|
-
const actions = data[key].actions;
|
|
22
|
+
const all = Object.keys(data);
|
|
35
23
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
action?.location?.linking?.SCL?.[administrativeLevel1]?.name;
|
|
40
|
-
return {
|
|
41
|
-
label: name,
|
|
42
|
-
value: administrativeLevel1,
|
|
43
|
-
};
|
|
44
|
-
});
|
|
45
|
-
}).filter((item) => item !== undefined);
|
|
24
|
+
const options = all
|
|
25
|
+
.map((key) => {
|
|
26
|
+
const actions = data[key].actions;
|
|
46
27
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
28
|
+
return actions.map((action) => {
|
|
29
|
+
if (action.location === undefined) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const administrativeLevel1 = action?.location?.administrativeLevel1;
|
|
33
|
+
const name =
|
|
34
|
+
action?.location?.linking?.SCL?.[administrativeLevel1]?.name;
|
|
35
|
+
return {
|
|
36
|
+
label: name,
|
|
37
|
+
value: administrativeLevel1,
|
|
38
|
+
};
|
|
39
|
+
});
|
|
40
|
+
})
|
|
41
|
+
.flat()
|
|
42
|
+
.filter((item) => item !== undefined);
|
|
54
43
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
44
|
+
setFilterOptions(options);
|
|
45
|
+
} catch (err) {
|
|
46
|
+
console.log(err);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
59
49
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
.map((key, index) => {
|
|
63
|
-
const item = data[key];
|
|
64
|
-
return {
|
|
65
|
-
value: item?.actions?.length,
|
|
66
|
-
label: item?.implementerData?.name,
|
|
67
|
-
implementerData: item?.implementerData,
|
|
68
|
-
color: distributionColors[index % distributionColors.length],
|
|
69
|
-
percent: totalActions ? (item?.actions?.length / totalActions) : 0,
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
}, [data]);
|
|
50
|
+
fetchOptions();
|
|
51
|
+
}, []);
|
|
73
52
|
|
|
74
|
-
const isEmpty = !pieData.length;
|
|
75
53
|
|
|
76
54
|
const filtersConfig = useMemo(
|
|
77
55
|
() => ({
|
|
@@ -101,8 +79,5 @@ export default function useProblemSolvers({ t = () => {}, selectedRange, selecte
|
|
|
101
79
|
return {
|
|
102
80
|
filters,
|
|
103
81
|
filtersConfig,
|
|
104
|
-
pieData,
|
|
105
|
-
loading,
|
|
106
|
-
isEmpty,
|
|
107
82
|
};
|
|
108
83
|
}
|
|
@@ -3,28 +3,77 @@ import PropTypes from 'prop-types';
|
|
|
3
3
|
import { renderTooltipJsx } from '../../../../../../../utils/tooltip.js';
|
|
4
4
|
import Widget from '../../../../../../../core/components/Dashboard/Widget/index.jsx';
|
|
5
5
|
import Chart from '../../../../../../../core/components/Charts/PieChart/chart.jsx';
|
|
6
|
+
import {useWidgetFetch} from '../../../../../../../hooks/useWidgetFetch.js';
|
|
7
|
+
import DashboardService from '../../../../../../../services/DashboardService.js';
|
|
6
8
|
import useProblemSolvers from './hook.js';
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
10
|
+
const distributionColors = ["#3061A8", "#6698E4", "#A6C3EF", "#D6E3F8", "#E6EEFB"];
|
|
11
|
+
|
|
12
|
+
function ProblemSolvers({ selectedPartners = {}, loading: parentLoading = false, t=()=>{}, theme = {}, selectedRange ,goTo = () => {}, getRedirectLink = () => {}}) {
|
|
13
|
+
const { filters, filtersConfig } = useProblemSolvers({ t });
|
|
14
|
+
|
|
15
|
+
const defaultFetchConfig = useMemo(
|
|
16
|
+
() => ({
|
|
17
|
+
url: "/problem-solvers",
|
|
18
|
+
basepath: "dashboard/conflict-management",
|
|
19
|
+
filters: {
|
|
20
|
+
...filters,
|
|
21
|
+
period: selectedRange,
|
|
22
|
+
sources: selectedPartners?.partners || [],
|
|
23
|
+
},
|
|
24
|
+
defaultData: [],
|
|
25
|
+
stop: selectedPartners?.loading,
|
|
26
|
+
}),
|
|
27
|
+
[filters, selectedRange, selectedPartners],
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
const getData = useCallback(({ url, filters, basepath }) => {
|
|
31
|
+
return DashboardService.getWidgetConflictManagement(url, filters, basepath);
|
|
32
|
+
}, []);
|
|
33
|
+
|
|
34
|
+
const { data, loading } = useWidgetFetch({
|
|
35
|
+
config: defaultFetchConfig,
|
|
36
|
+
getData
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
const pieData = useMemo(() => {
|
|
40
|
+
if (!data || Array.isArray(data)) return [];
|
|
41
|
+
const all = Object.keys(data);
|
|
42
|
+
const totalActions = all.reduce((acc, key) => acc + (data[key]?.actions?.length || 0), 0);
|
|
43
|
+
|
|
44
|
+
return all
|
|
45
|
+
.sort((a, b) => (data[b]?.actions?.length || 0) - (data[a]?.actions?.length || 0))
|
|
46
|
+
.map((key, index) => {
|
|
47
|
+
const item = data[key];
|
|
48
|
+
return {
|
|
49
|
+
value: item?.actions?.length,
|
|
50
|
+
label: item?.implementerData?.name,
|
|
51
|
+
implementerData: item?.implementerData,
|
|
52
|
+
color: distributionColors[index % distributionColors.length],
|
|
53
|
+
percent: totalActions ? (item?.actions?.length / totalActions) : 0,
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}, [data]);
|
|
57
|
+
|
|
58
|
+
const isEmpty = !pieData.length;
|
|
59
|
+
|
|
60
|
+
const getTooltipChildren = useCallback((items) => {
|
|
61
|
+
const item = Array.isArray(items) ? items[0] : items;
|
|
62
|
+
|
|
63
|
+
return renderTooltipJsx({
|
|
64
|
+
title: item?.label || t("Undetermined"),
|
|
65
|
+
link: true,
|
|
66
|
+
onClickLink: () => {
|
|
67
|
+
goTo("/app/corrective-actions");
|
|
68
|
+
},
|
|
69
|
+
items: [
|
|
70
|
+
{
|
|
71
|
+
label: t("Number of actions"),
|
|
72
|
+
value: item?.value,
|
|
73
|
+
},
|
|
74
|
+
],
|
|
27
75
|
});
|
|
76
|
+
}, [t, goTo]);
|
|
28
77
|
|
|
29
78
|
return (
|
|
30
79
|
<Widget
|
|
@@ -42,23 +91,7 @@ function ProblemSolvers({
|
|
|
42
91
|
isPie
|
|
43
92
|
t={t}
|
|
44
93
|
isEmpty={isEmpty}
|
|
45
|
-
getTooltipChildren={
|
|
46
|
-
const item = Array.isArray(items) ? items[0] : items;
|
|
47
|
-
|
|
48
|
-
return renderTooltipJsx({
|
|
49
|
-
title: item?.label || t("Undetermined"),
|
|
50
|
-
link: true,
|
|
51
|
-
onClickLink: () => {
|
|
52
|
-
goTo("/app/corrective-actions");
|
|
53
|
-
},
|
|
54
|
-
items: [
|
|
55
|
-
{
|
|
56
|
-
label: t("Number of actions"),
|
|
57
|
-
value: item?.value,
|
|
58
|
-
},
|
|
59
|
-
],
|
|
60
|
-
});
|
|
61
|
-
}}
|
|
94
|
+
getTooltipChildren={getTooltipChildren}
|
|
62
95
|
/>
|
|
63
96
|
</Widget>
|
|
64
97
|
);
|
|
@@ -3,37 +3,88 @@ import PropTypes from 'prop-types';
|
|
|
3
3
|
import { renderTooltipJsx } from '../../../../../../../utils/tooltip.js';
|
|
4
4
|
import Widget from '../../../../../../../core/components/Dashboard/Widget/index.jsx';
|
|
5
5
|
import Chart from '../../../../../../../core/components/Charts/PieChart/chart.jsx';
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
6
|
+
import {useWidgetFetch} from '../../../../../../../hooks/useWidgetFetch.js';
|
|
7
|
+
import DashboardService from '../../../../../../../services/DashboardService.js';
|
|
8
|
+
import { getColors } from './config.js';
|
|
8
9
|
|
|
9
|
-
function TerritorialDistribution({
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
selectedRange,
|
|
25
|
-
|
|
26
|
-
|
|
10
|
+
function TerritorialDistribution({ selectedPartners = {}, loading: parentLoading = false, t = (s) => s, theme = {}, category = "conflict", selectedRange ,goTo = () => {}, getRedirectLink = () => {}}) {
|
|
11
|
+
const colors = getColors(theme);
|
|
12
|
+
|
|
13
|
+
const defaultFetchConfig = useMemo(
|
|
14
|
+
() => ({
|
|
15
|
+
url: "/territorial-distribution",
|
|
16
|
+
basepath: "dashboard/conflict-management",
|
|
17
|
+
filters: {
|
|
18
|
+
category,
|
|
19
|
+
period: selectedRange,
|
|
20
|
+
sources: selectedPartners?.partners || [],
|
|
21
|
+
},
|
|
22
|
+
defaultData: {},
|
|
23
|
+
stop: selectedPartners?.loading,
|
|
24
|
+
}),
|
|
25
|
+
[category, selectedRange, selectedPartners],
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
const getData = useCallback(({ url, filters, basepath }) => {
|
|
29
|
+
return DashboardService.getWidgetConflictManagement(url, filters, basepath);
|
|
30
|
+
}, []);
|
|
31
|
+
|
|
32
|
+
const { data, loading } = useWidgetFetch({
|
|
33
|
+
config: defaultFetchConfig,
|
|
34
|
+
getData
|
|
27
35
|
});
|
|
28
36
|
|
|
37
|
+
const pieData = useMemo(() => {
|
|
38
|
+
if (!data || Array.isArray(data)) return [];
|
|
39
|
+
const all = Object.keys(data);
|
|
40
|
+
const totalEvents = all.reduce((acc, key) => acc + (data[key]?.events?.length || 0), 0);
|
|
41
|
+
|
|
42
|
+
return all
|
|
43
|
+
.sort((a, b) => (data[b]?.events?.length || 0) - (data[a]?.events?.length || 0))
|
|
44
|
+
.map((key, index) => {
|
|
45
|
+
const item = data[key];
|
|
46
|
+
return {
|
|
47
|
+
value: item?.events?.length,
|
|
48
|
+
label: item?.locationData?.name,
|
|
49
|
+
locationData: item?.locationData,
|
|
50
|
+
color: colors[index % colors.length],
|
|
51
|
+
percent: totalEvents ? (item?.events?.length / totalEvents) : 0,
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}, [data, colors]);
|
|
55
|
+
|
|
56
|
+
const isEmpty = !pieData.length;
|
|
57
|
+
|
|
58
|
+
const getTooltipChildren = useCallback((items) => {
|
|
59
|
+
const item = Array.isArray(items) ? items[0] : items;
|
|
60
|
+
|
|
61
|
+
return renderTooltipJsx({
|
|
62
|
+
title: item?.label || t("Undetermined"),
|
|
63
|
+
link: true,
|
|
64
|
+
onClickLink: () => {
|
|
65
|
+
if (item?.label) {
|
|
66
|
+
goTo(
|
|
67
|
+
`/app/incidents?administrativeLevel1=${item?.locationData?.administrativeLevel1}&administrativeLevel2=${item?.locationData?.administrativeLevel2}&country=${item?.locationData?.country}`,
|
|
68
|
+
);
|
|
69
|
+
} else {
|
|
70
|
+
goTo("/app/incident");
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
items: [
|
|
74
|
+
{
|
|
75
|
+
label: t("Number of incidents"),
|
|
76
|
+
value: item?.value,
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
});
|
|
80
|
+
}, [t, goTo]);
|
|
81
|
+
|
|
29
82
|
return (
|
|
30
83
|
<Widget
|
|
31
84
|
loading={loading || parentLoading}
|
|
32
85
|
title={t("Territorial Distribution")}
|
|
33
|
-
|
|
34
|
-
className="with-border-header h-w-btn-header"
|
|
86
|
+
className="with-border-header"
|
|
35
87
|
>
|
|
36
|
-
|
|
37
88
|
<Chart
|
|
38
89
|
mouseXOffset={10}
|
|
39
90
|
mouseYOffset={10}
|
|
@@ -43,34 +94,8 @@ function TerritorialDistribution({
|
|
|
43
94
|
isPie
|
|
44
95
|
t={t}
|
|
45
96
|
isEmpty={isEmpty}
|
|
46
|
-
getTooltipChildren={
|
|
47
|
-
const item = Array.isArray(items) ? items[0] : items;
|
|
48
|
-
|
|
49
|
-
return renderTooltipJsx({
|
|
50
|
-
title: item?.label || t("Undetermined"),
|
|
51
|
-
link: true,
|
|
52
|
-
onClickLink: () => {
|
|
53
|
-
if (item?.label) {
|
|
54
|
-
const queryString = buildQueryString({
|
|
55
|
-
administrativeLevel1: item?.locationData?.administrativeLevel1,
|
|
56
|
-
administrativeLevel2: item?.locationData?.administrativeLevel2,
|
|
57
|
-
country: item?.locationData?.country,
|
|
58
|
-
});
|
|
59
|
-
goTo(`/app/incidents${queryString}`);
|
|
60
|
-
} else {
|
|
61
|
-
goTo("/app/incidents");
|
|
62
|
-
}
|
|
63
|
-
},
|
|
64
|
-
items: [
|
|
65
|
-
{
|
|
66
|
-
label: t("Number of incidents"),
|
|
67
|
-
value: item?.value,
|
|
68
|
-
},
|
|
69
|
-
],
|
|
70
|
-
});
|
|
71
|
-
}}
|
|
97
|
+
getTooltipChildren={getTooltipChildren}
|
|
72
98
|
/>
|
|
73
|
-
|
|
74
99
|
</Widget>
|
|
75
100
|
);
|
|
76
101
|
}
|