datastake-daf 0.6.835 → 0.6.837
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/dist/components/index.js +2327 -2204
- package/dist/hooks/index.js +7 -8
- package/dist/pages/index.js +409 -192
- package/dist/services/index.js +7 -8
- package/package.json +1 -1
- package/src/@daf/core/components/Screens/Admin/AdminDashboard/components/UserStatistics/TopContributors/hook.js +3 -3
- package/src/@daf/core/components/Screens/Admin/AdminDashboard/components/UserStatistics/TopContributors/index.jsx +2 -2
- package/src/@daf/core/components/Screens/Admin/AdminDashboard/components/UserStatistics/index.jsx +2 -6
- package/src/@daf/core/components/Screens/Admin/AdminTables/AccountTable/index.jsx +0 -1
- package/src/@daf/{core/components/Screens → pages/Dashboards}/ConflictManagement/components/KeyIndicators/config.js +2 -3
- package/src/@daf/{core/components/Screens → pages/Dashboards}/ConflictManagement/components/KeyIndicators/index.js +2 -2
- package/src/@daf/{core/components/Screens → pages/Dashboards}/ConflictManagement/components/MineSite/index.js +3 -3
- package/src/@daf/pages/Dashboards/ConflictManagement/components/RisksWidget/components/IncidentsTime/config.js +206 -0
- package/src/@daf/pages/Dashboards/ConflictManagement/components/RisksWidget/components/IncidentsTime/hook.js +48 -0
- package/src/@daf/pages/Dashboards/ConflictManagement/components/RisksWidget/components/IncidentsTime/index.js +154 -0
- package/src/@daf/pages/Dashboards/ConflictManagement/components/RisksWidget/components/ProblemSolver/hook.js +83 -0
- package/src/@daf/{core/components/Screens → pages/Dashboards}/ConflictManagement/components/RisksWidget/components/ProblemSolver/index.js +14 -7
- package/src/@daf/pages/Dashboards/ConflictManagement/components/RisksWidget/components/TerritorialDistribution/config.js +10 -0
- package/src/@daf/{core/components/Screens → pages/Dashboards}/ConflictManagement/components/RisksWidget/components/TerritorialDistribution/index.js +18 -13
- package/src/@daf/{core/components/Screens → pages/Dashboards}/ConflictManagement/components/RisksWidget/index.js +1 -1
- package/src/@daf/{core/components/Screens → pages/Dashboards}/ConflictManagement/index.js +17 -19
- package/src/@daf/services/DashboardService.js +8 -8
- package/src/pages.js +1 -1
- package/build/favicon.ico +0 -0
- package/build/logo192.png +0 -0
- package/build/logo512.png +0 -0
- package/build/manifest.json +0 -25
- package/build/robots.txt +0 -3
- package/src/@daf/core/components/Screens/ConflictManagement/components/RisksWidget/components/IncidentsTime/hook.js +0 -32
- package/src/@daf/core/components/Screens/ConflictManagement/components/RisksWidget/components/IncidentsTime/index.js +0 -73
- package/src/@daf/core/components/Screens/ConflictManagement/components/RisksWidget/components/ProblemSolver/hook.js +0 -86
- package/src/@daf/core/components/Screens/ConflictManagement/components/RisksWidget/components/TerritorialDistribution/config.js +0 -34
- /package/src/@daf/{core/components/Screens → pages/Dashboards}/ConflictManagement/components/MineSite/helper.js +0 -0
- /package/src/@daf/{core/components/Screens → pages/Dashboards}/ConflictManagement/components/RisksWidget/config.js +0 -0
package/dist/services/index.js
CHANGED
|
@@ -1516,14 +1516,13 @@ class DashboardService extends BaseService {
|
|
|
1516
1516
|
isUserManager: true
|
|
1517
1517
|
});
|
|
1518
1518
|
}
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
// }
|
|
1519
|
+
getWidgetConflictManagement(url, params, basepath = "dashboard/conflict-management") {
|
|
1520
|
+
return this.apiGet({
|
|
1521
|
+
url: `/${basepath}${url}`,
|
|
1522
|
+
params,
|
|
1523
|
+
isApp: true
|
|
1524
|
+
});
|
|
1525
|
+
}
|
|
1527
1526
|
}
|
|
1528
1527
|
var DashboardService$1 = createLazyService(DashboardService);
|
|
1529
1528
|
|
package/package.json
CHANGED
|
@@ -8,7 +8,7 @@ import AdminService from "../../../../../../../../services/AdminService";
|
|
|
8
8
|
|
|
9
9
|
const { useToken } = theme;
|
|
10
10
|
|
|
11
|
-
export default function useTopContributors({ container,
|
|
11
|
+
export default function useTopContributors({ container, t }) {
|
|
12
12
|
const [mainGraph, setMainGraph] = useState(null);
|
|
13
13
|
const [data, setData] = useState([]);
|
|
14
14
|
const [loading, setLoading] = useState(false);
|
|
@@ -18,7 +18,7 @@ export default function useTopContributors({ container, params, t }) {
|
|
|
18
18
|
const fetchTopContributors = async () => {
|
|
19
19
|
try {
|
|
20
20
|
setLoading(true);
|
|
21
|
-
const response = await AdminService.getTopContributors({
|
|
21
|
+
const response = await AdminService.getTopContributors({ });
|
|
22
22
|
const transformedData = (response?.data || []).map(item => ({
|
|
23
23
|
label: item.name,
|
|
24
24
|
Score: item.value
|
|
@@ -33,7 +33,7 @@ export default function useTopContributors({ container, params, t }) {
|
|
|
33
33
|
};
|
|
34
34
|
|
|
35
35
|
fetchTopContributors();
|
|
36
|
-
}, [
|
|
36
|
+
}, []);
|
|
37
37
|
useEffect(() => {
|
|
38
38
|
if (container.current) {
|
|
39
39
|
if (mainGraph) {
|
|
@@ -4,10 +4,10 @@ import useTopContributors from "./hook.js";
|
|
|
4
4
|
|
|
5
5
|
import Style from "../style.js";
|
|
6
6
|
|
|
7
|
-
export default function TopContributors({
|
|
7
|
+
export default function TopContributors({ t }) {
|
|
8
8
|
const container = useRef(null);
|
|
9
9
|
|
|
10
|
-
const { loading } = useTopContributors({ container,
|
|
10
|
+
const { loading } = useTopContributors({ container, t });
|
|
11
11
|
return (
|
|
12
12
|
<Widget
|
|
13
13
|
title={t(`admin::top-contributors`)}
|
package/src/@daf/core/components/Screens/Admin/AdminDashboard/components/UserStatistics/index.jsx
CHANGED
|
@@ -10,13 +10,9 @@ export default function UserStatistics({
|
|
|
10
10
|
data,
|
|
11
11
|
t,
|
|
12
12
|
translationKeys,
|
|
13
|
+
|
|
13
14
|
}) {
|
|
14
|
-
|
|
15
|
-
// console.log("UserStatistics:loadingUserGrowth", loadingUserGrowth);
|
|
16
|
-
// console.log("UserStatistics:data", data);
|
|
17
|
-
// console.log("UserStatistics:userActivityData", data?.userActivityData);
|
|
18
|
-
// console.log("UserStatistics:topContributorsData", data?.topContributorsData);
|
|
19
|
-
// console.log("UserStatistics:userGrowthData", data?.userGrowthData);
|
|
15
|
+
|
|
20
16
|
|
|
21
17
|
|
|
22
18
|
return (
|
|
@@ -18,7 +18,6 @@ import {
|
|
|
18
18
|
|
|
19
19
|
import CombineAccountModal from "../../AdminModals/CombineAccount/index.jsx";
|
|
20
20
|
|
|
21
|
-
// import NewAccount from "../../../Admin/AdminModals/NewAccount/index.jsx";
|
|
22
21
|
import CustomIcon from "../../../../Icon/CustomIcon.jsx";
|
|
23
22
|
import AddAccountModal from "../../AdminModals/AddAccount/index.jsx";
|
|
24
23
|
export default function AccountTable({
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import CustomIcon from "../../../../../components/Icon/CustomIcon.jsx";
|
|
3
|
-
|
|
2
|
+
import CustomIcon from "../../../../../core/components/Icon/CustomIcon.jsx";
|
|
4
3
|
const renderNumber = (number, locale = 'en') => {
|
|
5
4
|
return new Intl.NumberFormat(locale).format(number);
|
|
6
5
|
}
|
|
@@ -33,7 +32,7 @@ export const getRowConfig = ({ t, data = {}, goTo, getRedirectLink, theme = {} }
|
|
|
33
32
|
<div className="flex-1">{t("Reported Incidents")}</div>
|
|
34
33
|
<div
|
|
35
34
|
className="cursor-pointer"
|
|
36
|
-
onClick={() => goTo(getRedirectLink("/app/
|
|
35
|
+
onClick={() => goTo(getRedirectLink("/app/incidents"))}
|
|
37
36
|
>
|
|
38
37
|
<CustomIcon
|
|
39
38
|
name="LinkNewTab"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useMemo } from "react";
|
|
2
|
-
import KeyIndicatorsWidget from "
|
|
2
|
+
import KeyIndicatorsWidget from "../../../../../core/components/Dashboard/Widget/KeyIndicators/index.jsx";
|
|
3
3
|
import { getRowConfig } from "./config.js";
|
|
4
|
-
import {useWidgetFetch} from "
|
|
4
|
+
import {useWidgetFetch} from "../../../../../hooks/useWidgetFetch.js";
|
|
5
5
|
|
|
6
6
|
export const defaultFetchConfig = {
|
|
7
7
|
url: "/informations",
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import React, { useEffect, useMemo, useState } from "react";
|
|
2
2
|
// import { useSelector } from "react-redux";
|
|
3
|
-
import MineSiteMap from "
|
|
4
|
-
import Widget from "
|
|
3
|
+
import MineSiteMap from "../../../../../core/components/Dashboard/Map/index.jsx";
|
|
4
|
+
import Widget from "../../../../../core/components/Dashboard/Widget/index.jsx";
|
|
5
5
|
import { areaColors } from "./helper.js";
|
|
6
|
-
import {useWidgetFetch} from "
|
|
6
|
+
import {useWidgetFetch} from "../../../../../hooks/useWidgetFetch.js";
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
const TERRITORY_MAP = "territory";
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { useMemo, useCallback } from "react";
|
|
2
|
+
import dayjs from "dayjs";
|
|
3
|
+
import isoWeek from "dayjs/plugin/isoWeek";
|
|
4
|
+
dayjs.extend(isoWeek);
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
export function useTimelineBase({ language, selectedRange }) {
|
|
9
|
+
const locale = useMemo(
|
|
10
|
+
() => (language === "sp" ? "es" : language || "en"),
|
|
11
|
+
[language]
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
const baseMonths = useMemo(() => {
|
|
17
|
+
if (selectedRange === "12") {
|
|
18
|
+
const y = dayjs().year();
|
|
19
|
+
const arr = [];
|
|
20
|
+
for (let i = 0; i < 12; i++) {
|
|
21
|
+
const d = dayjs().year(y).month(i);
|
|
22
|
+
arr.push({
|
|
23
|
+
key: d.format("YYYY-MM"),
|
|
24
|
+
label: d.locale(locale).format("MMM YYYY"),
|
|
25
|
+
date: d.toISOString(),
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
return arr;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (selectedRange === "3") {
|
|
32
|
+
const end = dayjs().endOf("month");
|
|
33
|
+
const start = end.subtract(2, "month").startOf("month");
|
|
34
|
+
const diff = end.diff(start, "month");
|
|
35
|
+
const arr = [];
|
|
36
|
+
for (let i = 0; i <= diff; i++) {
|
|
37
|
+
const d = start.add(i, "month");
|
|
38
|
+
arr.push({
|
|
39
|
+
key: d.format("YYYY-MM"),
|
|
40
|
+
label: d.locale(locale).format("MMM YYYY"),
|
|
41
|
+
date: d.toISOString(),
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
return arr;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return [];
|
|
48
|
+
}, [locale, selectedRange]);
|
|
49
|
+
|
|
50
|
+
const baseWeeks = useMemo(() => {
|
|
51
|
+
if (selectedRange !== "3") return [];
|
|
52
|
+
const end = dayjs().endOf("week");
|
|
53
|
+
const start = end.subtract(12, "week");
|
|
54
|
+
const diff = end.diff(start, "week");
|
|
55
|
+
const arr = [];
|
|
56
|
+
for (let i = 0; i <= diff; i++) {
|
|
57
|
+
const d = start.add(i, "week");
|
|
58
|
+
arr.push({
|
|
59
|
+
key: d.format("GGGG-[W]WW"),
|
|
60
|
+
label: d.format("[W]WW"),
|
|
61
|
+
date: d.toISOString(),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
return arr;
|
|
65
|
+
}, [selectedRange]);
|
|
66
|
+
|
|
67
|
+
const severityOrder = ["minor", "moderate", "major"];
|
|
68
|
+
|
|
69
|
+
const mergeWithData = useCallback(
|
|
70
|
+
(backendData = []) => {
|
|
71
|
+
let events = [];
|
|
72
|
+
|
|
73
|
+
if (Array.isArray(backendData)) {
|
|
74
|
+
backendData.forEach((entry) => {
|
|
75
|
+
if (!entry) return;
|
|
76
|
+
if (typeof entry === "object" && !Array.isArray(entry)) {
|
|
77
|
+
Object.values(entry).forEach((arr) => {
|
|
78
|
+
if (Array.isArray(arr)) events.push(...arr);
|
|
79
|
+
});
|
|
80
|
+
} else if (Array.isArray(entry)) {
|
|
81
|
+
events.push(...entry);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
} else if (backendData && typeof backendData === "object") {
|
|
85
|
+
Object.values(backendData).forEach((arr) => {
|
|
86
|
+
if (Array.isArray(arr)) events.push(...arr);
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (selectedRange === "12") {
|
|
91
|
+
const monthBuckets = baseMonths.reduce((acc, m) => {
|
|
92
|
+
acc[m.key] = [];
|
|
93
|
+
return acc;
|
|
94
|
+
}, {});
|
|
95
|
+
|
|
96
|
+
events.forEach((ev) => {
|
|
97
|
+
const d = dayjs(ev.date);
|
|
98
|
+
const key = d.format("YYYY-MM");
|
|
99
|
+
if (monthBuckets[key]) monthBuckets[key].push(ev);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
const res = [];
|
|
103
|
+
baseMonths.forEach((m) => {
|
|
104
|
+
const arr = monthBuckets[m.key];
|
|
105
|
+
if (!arr.length) {
|
|
106
|
+
res.push({
|
|
107
|
+
label: m.label,
|
|
108
|
+
key: m.key,
|
|
109
|
+
severity: "placeholder",
|
|
110
|
+
category: "placeholder",
|
|
111
|
+
value: 1,
|
|
112
|
+
isPlaceholder: true,
|
|
113
|
+
});
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
arr
|
|
117
|
+
.sort(
|
|
118
|
+
(a, b) =>
|
|
119
|
+
severityOrder.indexOf(a.severity) -
|
|
120
|
+
severityOrder.indexOf(b.severity)
|
|
121
|
+
)
|
|
122
|
+
.forEach((ev, idx) => {
|
|
123
|
+
const source = Array.isArray(ev.source)
|
|
124
|
+
? ev.source.join(", ")
|
|
125
|
+
: ev.source;
|
|
126
|
+
res.push({
|
|
127
|
+
...ev,
|
|
128
|
+
source,
|
|
129
|
+
label: m.label,
|
|
130
|
+
key: m.key,
|
|
131
|
+
indexInGroup: idx + 1,
|
|
132
|
+
severity: ev.severity || "undetermined",
|
|
133
|
+
category: ev.severity || "undetermined",
|
|
134
|
+
value: 1,
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
return res;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (selectedRange === "3") {
|
|
143
|
+
const weekBuckets = baseWeeks.reduce((acc, w) => {
|
|
144
|
+
acc[w.key] = [];
|
|
145
|
+
return acc;
|
|
146
|
+
}, {});
|
|
147
|
+
|
|
148
|
+
events.forEach((ev) => {
|
|
149
|
+
const d = dayjs(ev.date);
|
|
150
|
+
const key = d.format("GGGG-[W]WW");
|
|
151
|
+
if (weekBuckets[key]) weekBuckets[key].push(ev);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
const res = [];
|
|
155
|
+
baseWeeks.forEach((w) => {
|
|
156
|
+
const arr = weekBuckets[w.key];
|
|
157
|
+
if (!arr.length) {
|
|
158
|
+
res.push({
|
|
159
|
+
label: w.label,
|
|
160
|
+
key: w.key,
|
|
161
|
+
severity: "placeholder",
|
|
162
|
+
category: "placeholder",
|
|
163
|
+
value: 1,
|
|
164
|
+
isPlaceholder: true,
|
|
165
|
+
});
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
arr
|
|
169
|
+
.sort(
|
|
170
|
+
(a, b) =>
|
|
171
|
+
severityOrder.indexOf(a.severity) -
|
|
172
|
+
severityOrder.indexOf(b.severity)
|
|
173
|
+
)
|
|
174
|
+
.forEach((ev, idx) => {
|
|
175
|
+
const source = Array.isArray(ev.source)
|
|
176
|
+
? ev.source.join(", ")
|
|
177
|
+
: ev.source;
|
|
178
|
+
res.push({
|
|
179
|
+
...ev,
|
|
180
|
+
source,
|
|
181
|
+
label: w.label,
|
|
182
|
+
key: w.key,
|
|
183
|
+
indexInGroup: idx + 1,
|
|
184
|
+
severity: ev.severity || "undetermined",
|
|
185
|
+
category: ev.severity || "undetermined",
|
|
186
|
+
value: 1,
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
return res;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return [];
|
|
195
|
+
},
|
|
196
|
+
[selectedRange, baseMonths, baseWeeks]
|
|
197
|
+
);
|
|
198
|
+
|
|
199
|
+
return {
|
|
200
|
+
baseMonths,
|
|
201
|
+
baseWeeks,
|
|
202
|
+
mergeWithData,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export default useTimelineBase;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { useMemo, useState } from "react";
|
|
2
|
+
import useTimelineBase from "./config.js";
|
|
3
|
+
|
|
4
|
+
export default function useIncidentsTimeline({
|
|
5
|
+
t,
|
|
6
|
+
language,
|
|
7
|
+
severityOptions = [],
|
|
8
|
+
selectedRange = "12",
|
|
9
|
+
}) {
|
|
10
|
+
const [filters, setFilters] = useState({ severity: "all" });
|
|
11
|
+
|
|
12
|
+
const { baseMonths, baseWeeks, mergeWithData } = useTimelineBase({ language, selectedRange });
|
|
13
|
+
|
|
14
|
+
const filtersConfig = useMemo(
|
|
15
|
+
() => ({
|
|
16
|
+
language,
|
|
17
|
+
filtersConfig: {
|
|
18
|
+
severity: {
|
|
19
|
+
type: "select",
|
|
20
|
+
label: "",
|
|
21
|
+
placeholder: (tFn) => tFn(""),
|
|
22
|
+
style: { flex: 1 },
|
|
23
|
+
labelStyle: { flex: 1 },
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
onApply: (val) => setFilters(val),
|
|
27
|
+
options: {
|
|
28
|
+
severity: [
|
|
29
|
+
{ value: "all", label: t("All") },
|
|
30
|
+
...(severityOptions || []),
|
|
31
|
+
],
|
|
32
|
+
},
|
|
33
|
+
selectedFilters: filters,
|
|
34
|
+
type: "small",
|
|
35
|
+
t,
|
|
36
|
+
}),
|
|
37
|
+
[t, language, filters, severityOptions]
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
return {
|
|
41
|
+
filters,
|
|
42
|
+
filtersConfig,
|
|
43
|
+
setFilters,
|
|
44
|
+
baseMonths,
|
|
45
|
+
baseWeeks,
|
|
46
|
+
mergeWithData
|
|
47
|
+
};
|
|
48
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { useMemo, useCallback } from "react";
|
|
2
|
+
import Widget from "../../../../../../../core/components/Dashboard/Widget/index.jsx";
|
|
3
|
+
import PropTypes from "prop-types";
|
|
4
|
+
import useIncidentsTimeline from "./hook.js";
|
|
5
|
+
import { useWidgetFetch } from "../../../../../../../hooks/useWidgetFetch.js";
|
|
6
|
+
import DashboardService from "../../../../../../../services/DashboardService.js";
|
|
7
|
+
import { renderDateFormatted } from "../../../../../../../../helpers/Forms.js";
|
|
8
|
+
import StackChart from "../../../../../../../core/components/Charts/StackChart/index.jsx";
|
|
9
|
+
|
|
10
|
+
export default function IncidentsTimeline({
|
|
11
|
+
selectedRange,
|
|
12
|
+
selectedPartners = {},
|
|
13
|
+
t,
|
|
14
|
+
language,
|
|
15
|
+
goTo,
|
|
16
|
+
user,
|
|
17
|
+
options,
|
|
18
|
+
}) {
|
|
19
|
+
const {
|
|
20
|
+
filters,
|
|
21
|
+
filtersConfig,
|
|
22
|
+
mergeWithData,
|
|
23
|
+
baseMonths,
|
|
24
|
+
baseWeeks,
|
|
25
|
+
} = useIncidentsTimeline({
|
|
26
|
+
t,
|
|
27
|
+
language,
|
|
28
|
+
severityOptions: options?.severityOptions || [],
|
|
29
|
+
selectedRange,
|
|
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
|
+
|
|
72
|
+
const { data, loading } = useWidgetFetch({
|
|
73
|
+
config: defaultFetchConfig,
|
|
74
|
+
getData: getIncidentsTimelineData,
|
|
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
|
+
|
|
89
|
+
const chartData = useMemo(() => mergeWithData(data), [data, mergeWithData]);
|
|
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
|
+
|
|
96
|
+
const getTooltipContent = useCallback(
|
|
97
|
+
({ item }) => {
|
|
98
|
+
if (!item) return { title: "", items: [] };
|
|
99
|
+
|
|
100
|
+
return {
|
|
101
|
+
title: item.name || item.label || t("Undetermined"),
|
|
102
|
+
subTitle: renderDateFormatted(item.date, "DD MMM YYYY"),
|
|
103
|
+
link: true,
|
|
104
|
+
onClickLink: () => {
|
|
105
|
+
goTo(
|
|
106
|
+
`/app/view/incidents/${item.datastakeId}/identification${getSourceParam(
|
|
107
|
+
item?.sourceId
|
|
108
|
+
)}`
|
|
109
|
+
);
|
|
110
|
+
},
|
|
111
|
+
items: [
|
|
112
|
+
{ label: t("nashiriki::Source"), value: item?.source || "--" },
|
|
113
|
+
item.severity
|
|
114
|
+
? { label: t("Severity"), value: renderSeverity(item.severity) }
|
|
115
|
+
: null,
|
|
116
|
+
].filter(Boolean),
|
|
117
|
+
};
|
|
118
|
+
},
|
|
119
|
+
[t, goTo, getSourceParam, renderSeverity]
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
return (
|
|
123
|
+
<Widget
|
|
124
|
+
loading={loading}
|
|
125
|
+
filtersConfig={filtersConfig}
|
|
126
|
+
title={t("nashiriki::Incidents Timeline")}
|
|
127
|
+
className="with-border-header"
|
|
128
|
+
>
|
|
129
|
+
<div className="mb-4 flex-1 flex flex-column justify-content-center">
|
|
130
|
+
<StackChart
|
|
131
|
+
data={chartData}
|
|
132
|
+
xFieldKey="label"
|
|
133
|
+
categories={categories}
|
|
134
|
+
seriesField="severity"
|
|
135
|
+
colors={severityColors}
|
|
136
|
+
doConstraints={false}
|
|
137
|
+
renderTooltip={getTooltipContent}
|
|
138
|
+
/>
|
|
139
|
+
</div>
|
|
140
|
+
</Widget>
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
IncidentsTimeline.propTypes = {
|
|
145
|
+
selectedRange: PropTypes.string,
|
|
146
|
+
selectedPartners: PropTypes.object,
|
|
147
|
+
t: PropTypes.func.isRequired,
|
|
148
|
+
language: PropTypes.string,
|
|
149
|
+
goTo: PropTypes.func.isRequired,
|
|
150
|
+
user: PropTypes.object,
|
|
151
|
+
options: PropTypes.shape({
|
|
152
|
+
severityOptions: PropTypes.array,
|
|
153
|
+
}),
|
|
154
|
+
};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { useEffect, useMemo, useState } from "react";
|
|
2
|
+
import DashboardService from "../../../../../../../services/DashboardService.js";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
export default function useProblemSolvers({ t = () => {} } = {}) {
|
|
6
|
+
const [filters, setFilters] = useState({
|
|
7
|
+
administrativeLevel1: "all",
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
const [filterOptions, setFilterOptions] = useState([]);
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
async function fetchOptions() {
|
|
15
|
+
try {
|
|
16
|
+
const { data } = await DashboardService.getWidgetConflictManagement(
|
|
17
|
+
"/problem-solvers",
|
|
18
|
+
{},
|
|
19
|
+
"dashboard/conflict-management"
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
const all = Object.keys(data);
|
|
23
|
+
|
|
24
|
+
const options = all
|
|
25
|
+
.map((key) => {
|
|
26
|
+
const actions = data[key].actions;
|
|
27
|
+
|
|
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);
|
|
43
|
+
|
|
44
|
+
setFilterOptions(options);
|
|
45
|
+
} catch (err) {
|
|
46
|
+
console.log(err);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
fetchOptions();
|
|
51
|
+
}, []);
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
const filtersConfig = useMemo(
|
|
55
|
+
() => ({
|
|
56
|
+
filtersConfig: {
|
|
57
|
+
administrativeLevel1: {
|
|
58
|
+
type: "select",
|
|
59
|
+
label: "",
|
|
60
|
+
placeholder: t("Select"),
|
|
61
|
+
style: { flex: 1 },
|
|
62
|
+
labelStyle: { flex: 1 },
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
onApply: (val) => setFilters(val),
|
|
66
|
+
options: {
|
|
67
|
+
administrativeLevel1: [
|
|
68
|
+
{ label: t("All"), value: "all" },
|
|
69
|
+
...filterOptions,
|
|
70
|
+
],
|
|
71
|
+
},
|
|
72
|
+
selectedFilters: filters,
|
|
73
|
+
type: "small",
|
|
74
|
+
t,
|
|
75
|
+
}),
|
|
76
|
+
[t, filters, filterOptions]
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
filters,
|
|
81
|
+
filtersConfig,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
import React, { useMemo, useCallback } from 'react'
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
-
import { renderTooltipJsx } from '
|
|
4
|
-
import Widget from '
|
|
5
|
-
import Chart from '
|
|
6
|
-
import {useWidgetFetch} from '
|
|
3
|
+
import { renderTooltipJsx } from '../../../../../../../utils/tooltip.js';
|
|
4
|
+
import Widget from '../../../../../../../core/components/Dashboard/Widget/index.jsx';
|
|
5
|
+
import Chart from '../../../../../../../core/components/Charts/PieChart/chart.jsx';
|
|
6
|
+
import {useWidgetFetch} from '../../../../../../../hooks/useWidgetFetch.js';
|
|
7
|
+
import DashboardService from '../../../../../../../services/DashboardService.js';
|
|
7
8
|
import useProblemSolvers from './hook.js';
|
|
8
9
|
|
|
9
10
|
const distributionColors = ["#3061A8", "#6698E4", "#A6C3EF", "#D6E3F8", "#E6EEFB"];
|
|
10
11
|
|
|
11
12
|
function ProblemSolvers({ selectedPartners = {}, loading: parentLoading = false, t=()=>{}, theme = {}, selectedRange ,goTo = () => {}, getRedirectLink = () => {}}) {
|
|
12
|
-
const { filters, filtersConfig } = useProblemSolvers();
|
|
13
|
+
const { filters, filtersConfig } = useProblemSolvers({ t });
|
|
13
14
|
|
|
14
15
|
const defaultFetchConfig = useMemo(
|
|
15
16
|
() => ({
|
|
16
|
-
basepath: "conflict-management",
|
|
17
17
|
url: "/problem-solvers",
|
|
18
|
+
basepath: "dashboard/conflict-management",
|
|
18
19
|
filters: {
|
|
19
20
|
...filters,
|
|
20
21
|
period: selectedRange,
|
|
@@ -26,8 +27,14 @@ function ProblemSolvers({ selectedPartners = {}, loading: parentLoading = false,
|
|
|
26
27
|
[filters, selectedRange, selectedPartners],
|
|
27
28
|
);
|
|
28
29
|
|
|
30
|
+
const getData = useCallback(({ url, filters, basepath }) => {
|
|
31
|
+
return DashboardService.getWidgetConflictManagement(url, filters, basepath);
|
|
32
|
+
}, []);
|
|
29
33
|
|
|
30
|
-
const { data, loading } = useWidgetFetch({
|
|
34
|
+
const { data, loading } = useWidgetFetch({
|
|
35
|
+
config: defaultFetchConfig,
|
|
36
|
+
getData
|
|
37
|
+
});
|
|
31
38
|
|
|
32
39
|
const pieData = useMemo(() => {
|
|
33
40
|
if (!data || Array.isArray(data)) return [];
|