datastake-daf 0.6.699 → 0.6.701
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 +448 -428
- package/dist/hooks/index.js +631 -0
- package/dist/layouts/index.js +448 -428
- package/dist/pages/index.js +12767 -0
- package/dist/services/index.js +60 -0
- package/dist/style/datastake/datastake.css +15 -3
- package/dist/utils/index.js +448 -428
- package/package.json +1 -1
- package/rollup.config.js +20 -0
- package/src/@daf/core/components/Icon/configs/Onboarding.js +12 -0
- package/src/@daf/core/components/Icon/configs/index.js +2 -0
- package/src/@daf/hooks/useSources.js +29 -0
- package/src/@daf/hooks/useWidgetFetch.js +44 -0
- package/src/@daf/pages/dashboards/SupplyChain/components/ChartsContainer/components/GenderDistribution/config.js +17 -0
- package/src/@daf/pages/dashboards/SupplyChain/components/ChartsContainer/components/GenderDistribution/index.js +128 -0
- package/src/@daf/pages/dashboards/SupplyChain/components/ChartsContainer/components/Identification/hook.js +79 -0
- package/src/@daf/pages/dashboards/SupplyChain/components/ChartsContainer/components/Identification/index.js +64 -0
- package/src/@daf/pages/dashboards/SupplyChain/components/ChartsContainer/components/Locations/config.js +9 -0
- package/src/@daf/pages/dashboards/SupplyChain/components/ChartsContainer/components/Locations/index.js +103 -0
- package/src/@daf/pages/dashboards/SupplyChain/components/ChartsContainer/index.js +82 -0
- package/src/@daf/pages/dashboards/SupplyChain/components/KeyIndicators/config.js +88 -0
- package/src/@daf/pages/dashboards/SupplyChain/components/KeyIndicators/index.js +54 -0
- package/src/@daf/pages/dashboards/SupplyChain/components/SupplyChainMap/index.js +70 -0
- package/src/@daf/pages/dashboards/SupplyChain/components/TradeRelationships/index.js +48 -0
- package/src/@daf/pages/dashboards/SupplyChain/config.js +216 -0
- package/src/@daf/pages/dashboards/SupplyChain/index.jsx +96 -0
- package/src/@daf/services/DashboardService.js +14 -0
- package/src/@daf/services/SourceService.js +36 -0
- package/src/hooks.js +3 -2
- package/src/pages.js +1 -0
- package/src/services.js +3 -1
- package/src/styles/datastake/datastake.css +15 -3
package/package.json
CHANGED
package/rollup.config.js
CHANGED
|
@@ -119,6 +119,26 @@ export default [
|
|
|
119
119
|
}),
|
|
120
120
|
],
|
|
121
121
|
},
|
|
122
|
+
{
|
|
123
|
+
input: "src/pages.js",
|
|
124
|
+
output: [
|
|
125
|
+
{
|
|
126
|
+
file: "dist/pages/index.js",
|
|
127
|
+
format: "cjs",
|
|
128
|
+
},
|
|
129
|
+
],
|
|
130
|
+
external,
|
|
131
|
+
plugins: [
|
|
132
|
+
nodePolyfills(),
|
|
133
|
+
resolve({ browser: true }),
|
|
134
|
+
babel({ exclude: "node_modules/**", babelrc: true }),
|
|
135
|
+
peerDep(),
|
|
136
|
+
commonjs({
|
|
137
|
+
include: /node_modules/,
|
|
138
|
+
requireReturnsDefault: "auto",
|
|
139
|
+
}),
|
|
140
|
+
],
|
|
141
|
+
},
|
|
122
142
|
{
|
|
123
143
|
input: "src/layouts.js",
|
|
124
144
|
output: [
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const config = {
|
|
2
|
+
viewBox: '0 0 19 19',
|
|
3
|
+
children: (
|
|
4
|
+
<>
|
|
5
|
+
<path d="M9.08333 17.4167C13.6857 17.4167 17.4167 13.6857 17.4167 9.08333C17.4167 4.48096 13.6857 0.75 9.08333 0.75C4.48096 0.75 0.75 4.48096 0.75 9.08333C0.75 13.6857 4.48096 17.4167 9.08333 17.4167Z" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
|
|
6
|
+
<path d="M7 6.55444C7 6.15671 7 5.95784 7.08312 5.84681C7.15555 5.75006 7.26643 5.68953 7.38698 5.68092C7.52532 5.67104 7.6926 5.77858 8.02717 5.99366L11.961 8.52255C12.2513 8.70918 12.3965 8.8025 12.4466 8.92116C12.4904 9.02484 12.4904 9.14183 12.4466 9.24551C12.3965 9.36417 12.2513 9.45748 11.961 9.64412L8.02717 12.173C7.6926 12.3881 7.52532 12.4956 7.38698 12.4857C7.26643 12.4771 7.15555 12.4166 7.08312 12.3199C7 12.2088 7 12.01 7 11.6122V6.55444Z" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
|
|
7
|
+
</>
|
|
8
|
+
)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default config;
|
|
12
|
+
|
|
@@ -212,9 +212,11 @@ import MagicWand from "./MagicWant";
|
|
|
212
212
|
import Straatos from "./Straatos";
|
|
213
213
|
import ArcGis from "./ArcGis";
|
|
214
214
|
import AppAdmin from "./AppAdmin";
|
|
215
|
+
import Onboarding from "./Onboarding";
|
|
215
216
|
|
|
216
217
|
const config = {
|
|
217
218
|
AppAdmin,
|
|
219
|
+
Onboarding,
|
|
218
220
|
Right,
|
|
219
221
|
ApplicationForm,
|
|
220
222
|
Alert,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useEffect, useState } from "react";
|
|
2
|
+
import SourceService from "../services/SourceService.js";
|
|
2
3
|
|
|
3
4
|
export default function useSource({ user = {}, t = () => {}, getData = () => {}, id }) {
|
|
4
5
|
const [loading, setLoading] = useState(true);
|
|
@@ -78,3 +79,31 @@ export default function useSource({ user = {}, t = () => {}, getData = () => {},
|
|
|
78
79
|
onSelectPartnersChange: handleSelectedPartnersChange,
|
|
79
80
|
};
|
|
80
81
|
}
|
|
82
|
+
|
|
83
|
+
export const useSources = ({type, id, user, t = () => {}}) => {
|
|
84
|
+
function getData(params) {
|
|
85
|
+
if(id) {
|
|
86
|
+
return SourceService.getSources({type, id});
|
|
87
|
+
} else {
|
|
88
|
+
return SourceService.get(null, params);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const { onSelectPartnersChange, partners, selectedPartners, setSelectedPartners } = useSource({
|
|
93
|
+
user,
|
|
94
|
+
t,
|
|
95
|
+
getData: getData,
|
|
96
|
+
id,
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
const informationSources = partners?.length > 0 ? partners?.length - 1 : 0;
|
|
100
|
+
|
|
101
|
+
return {
|
|
102
|
+
partners,
|
|
103
|
+
selectedPartners,
|
|
104
|
+
setSelectedPartners,
|
|
105
|
+
user,
|
|
106
|
+
informationSources: informationSources,
|
|
107
|
+
onSelectPartnersChange,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { useState, useEffect } from "react";
|
|
2
|
+
import DashboardService from "../services/DashboardService.js";
|
|
3
|
+
|
|
4
|
+
// config: {
|
|
5
|
+
// stop: boolean,
|
|
6
|
+
// defaultData: object,
|
|
7
|
+
// filters: object
|
|
8
|
+
// url: string
|
|
9
|
+
// basePath: string,
|
|
10
|
+
// }
|
|
11
|
+
|
|
12
|
+
export const useWidgetFetch = ({config, getData = DashboardService.getWidget, onFetch = () => {}}) => {
|
|
13
|
+
const { stop, defaultData, ...rest} = config;
|
|
14
|
+
const [ data, setData ] = useState(defaultData || {});
|
|
15
|
+
const [ loading, setLoading ] = useState(false);
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
const fetchData = async () => {
|
|
19
|
+
// if (stop) {
|
|
20
|
+
// return;
|
|
21
|
+
// }
|
|
22
|
+
|
|
23
|
+
setLoading(true);
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
const { data } = await getData(rest);
|
|
27
|
+
setData(data || defaultData);
|
|
28
|
+
onFetch()
|
|
29
|
+
} catch (err) {
|
|
30
|
+
console.log(err);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
setLoading(false);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
fetchData();
|
|
38
|
+
}, []);
|
|
39
|
+
|
|
40
|
+
return {
|
|
41
|
+
data,
|
|
42
|
+
loading,
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
|
|
2
|
+
export const config = [
|
|
3
|
+
{ key: "male", label: "Male", color: "#4683DE" },
|
|
4
|
+
{ key: "female", label: "Female", color: "#A6C3EF" },
|
|
5
|
+
{ key: "other", label: "Other", color: "#B6CEF2" },
|
|
6
|
+
];
|
|
7
|
+
|
|
8
|
+
export const getRoleColors = (theme) => {
|
|
9
|
+
return [
|
|
10
|
+
theme.colorPrimary4,
|
|
11
|
+
theme.colorPrimary6,
|
|
12
|
+
theme.colorPrimary7,
|
|
13
|
+
theme.colorPrimary8,
|
|
14
|
+
theme.colorPrimary9,
|
|
15
|
+
theme.colorPrimary10,
|
|
16
|
+
]
|
|
17
|
+
};
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import React, { useMemo, useCallback } from 'react'
|
|
2
|
+
import { getRoleColors, config } from './config';
|
|
3
|
+
import PropTypes from 'prop-types';
|
|
4
|
+
import { renderTooltipJsx } from '../../../../../../../utils/tooltip.js';
|
|
5
|
+
import Widget from '../../../../../../../core/components/Dashboard/Widget/index.jsx';
|
|
6
|
+
import Chart from '../../../../../../../core/components/Charts/PieChart/chart.jsx';
|
|
7
|
+
|
|
8
|
+
function GenderDistribution({
|
|
9
|
+
selectedSources = {},
|
|
10
|
+
isTradeActions = false,
|
|
11
|
+
loading = false,
|
|
12
|
+
data = [],
|
|
13
|
+
t = () => {},
|
|
14
|
+
theme = {},
|
|
15
|
+
options = {},
|
|
16
|
+
}) {
|
|
17
|
+
const roleColors = getRoleColors(theme);
|
|
18
|
+
|
|
19
|
+
const pieData = useMemo(() => {
|
|
20
|
+
const total = Object.values(data).reduce((all, val) => all + (val || 0), 0);
|
|
21
|
+
|
|
22
|
+
if (isTradeActions) {
|
|
23
|
+
return Object.keys(data).map((key, index) => {
|
|
24
|
+
return {
|
|
25
|
+
percent: (data[key] || 0) / total,
|
|
26
|
+
color: roleColors[index % roleColors.length],
|
|
27
|
+
key: key,
|
|
28
|
+
};
|
|
29
|
+
});
|
|
30
|
+
} else {
|
|
31
|
+
return config.map((conf) => ({
|
|
32
|
+
percent: (data[conf.key] || 0) / total,
|
|
33
|
+
color: conf.color,
|
|
34
|
+
key: conf.key,
|
|
35
|
+
}));
|
|
36
|
+
}
|
|
37
|
+
}, [data, isTradeActions]);
|
|
38
|
+
|
|
39
|
+
const isEmpty = useMemo(() => Object.keys(data).filter((k) => !!data[k]).length === 0, [data]);
|
|
40
|
+
|
|
41
|
+
const getTooltipChildren = useCallback(
|
|
42
|
+
(item) => {
|
|
43
|
+
if (isTradeActions) {
|
|
44
|
+
if (isEmpty) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return renderTooltipJsx({
|
|
49
|
+
title: t("Role"),
|
|
50
|
+
items: [
|
|
51
|
+
{
|
|
52
|
+
label:
|
|
53
|
+
options?.optionPositionSupplyChain.find((o) => {
|
|
54
|
+
return o.value === item.key;
|
|
55
|
+
}).label || item.key,
|
|
56
|
+
value: data[item.key] || 0,
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
});
|
|
60
|
+
} else {
|
|
61
|
+
if (isEmpty) {
|
|
62
|
+
return renderTooltipJsx({
|
|
63
|
+
title: t("Gender"),
|
|
64
|
+
items: config.map((conf) => ({
|
|
65
|
+
label: t(conf.label),
|
|
66
|
+
value: 0,
|
|
67
|
+
})),
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const _config = config.find((c) => c.key === item.key);
|
|
72
|
+
|
|
73
|
+
if (_config) {
|
|
74
|
+
return renderTooltipJsx({
|
|
75
|
+
title: t("Gender"),
|
|
76
|
+
items: [
|
|
77
|
+
{
|
|
78
|
+
label: t(_config.label),
|
|
79
|
+
value: `${Math.round(item.percent * 100)}%`,
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
[t, data, isTradeActions],
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
return (
|
|
92
|
+
<Widget
|
|
93
|
+
loading={loading}
|
|
94
|
+
title={<div>{isTradeActions ? t("Role") : t("Workforce")}</div>}
|
|
95
|
+
className="with-border-header h-w-btn-header "
|
|
96
|
+
>
|
|
97
|
+
<div
|
|
98
|
+
style={{
|
|
99
|
+
marginTop: "auto",
|
|
100
|
+
marginBottom: "auto",
|
|
101
|
+
}}
|
|
102
|
+
>
|
|
103
|
+
<Chart
|
|
104
|
+
mouseXOffset={10}
|
|
105
|
+
mouseYOffset={10}
|
|
106
|
+
changeOpacityOnHover={false}
|
|
107
|
+
data={pieData}
|
|
108
|
+
doConstraints={false}
|
|
109
|
+
isPie
|
|
110
|
+
t={t}
|
|
111
|
+
isEmpty={isEmpty}
|
|
112
|
+
getTooltipChildren={getTooltipChildren}
|
|
113
|
+
/>
|
|
114
|
+
</div>
|
|
115
|
+
</Widget>
|
|
116
|
+
)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
GenderDistribution.propTypes = {
|
|
120
|
+
selectedSources: PropTypes.object,
|
|
121
|
+
isTradeActions: PropTypes.bool,
|
|
122
|
+
loading: PropTypes.bool,
|
|
123
|
+
data: PropTypes.array,
|
|
124
|
+
t: PropTypes.func,
|
|
125
|
+
theme: PropTypes.object,
|
|
126
|
+
options: PropTypes.object,
|
|
127
|
+
}
|
|
128
|
+
export default GenderDistribution
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { useEffect, useState, useMemo } from "react";
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
export function useIdentification({ data = undefined, theme = {}, options = {} }) {
|
|
5
|
+
const colors = [
|
|
6
|
+
theme.colorPrimary10,
|
|
7
|
+
theme.colorPrimary9,
|
|
8
|
+
theme.colorPrimary8,
|
|
9
|
+
theme.colorPrimary7,
|
|
10
|
+
theme.colorPrimary5,
|
|
11
|
+
theme.colorPrimary6,
|
|
12
|
+
theme.colorPrimary4,
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
const [graphData, setGraphData] = useState([]);
|
|
16
|
+
const [allSeenProducts, setAllSeenProducts] = useState([]);
|
|
17
|
+
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
const allSeenProducts = new Set();
|
|
20
|
+
|
|
21
|
+
Object.keys(data).forEach((date) => {
|
|
22
|
+
const item = data[date];
|
|
23
|
+
Object.keys(item).forEach((product) => {
|
|
24
|
+
allSeenProducts.add(product);
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const allProductsArray = Array.from(allSeenProducts);
|
|
29
|
+
setAllSeenProducts(allProductsArray);
|
|
30
|
+
|
|
31
|
+
const _data = Object.keys(data)
|
|
32
|
+
.map((date) => {
|
|
33
|
+
const item = data[date];
|
|
34
|
+
|
|
35
|
+
return allProductsArray.map((product) => {
|
|
36
|
+
return {
|
|
37
|
+
date: date,
|
|
38
|
+
typeOfProduct: product,
|
|
39
|
+
value: item[product] || 0,
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
})
|
|
43
|
+
.flat();
|
|
44
|
+
|
|
45
|
+
setGraphData(_data);
|
|
46
|
+
}, [JSON.stringify(data)]);
|
|
47
|
+
|
|
48
|
+
const chartConfig = useMemo(() => {
|
|
49
|
+
return {
|
|
50
|
+
data: graphData,
|
|
51
|
+
xFieldKey: "date",
|
|
52
|
+
yFieldKey: "value",
|
|
53
|
+
seriesField: "typeOfProduct",
|
|
54
|
+
color: allSeenProducts.map((_, index) => colors[index % colors.length]),
|
|
55
|
+
renderTooltipContent: (title, items) => {
|
|
56
|
+
if (Array.isArray(items) && items[0]) {
|
|
57
|
+
const title = items[0].title;
|
|
58
|
+
const values = graphData.filter((d) => d.date === title);
|
|
59
|
+
return {
|
|
60
|
+
title: "Products",
|
|
61
|
+
items: values.map((val) => ({
|
|
62
|
+
label:
|
|
63
|
+
options.minerals.find(
|
|
64
|
+
(mineral) => mineral.value === val.typeOfProduct,
|
|
65
|
+
)?.label || val.typeOfProduct,
|
|
66
|
+
color: colors[
|
|
67
|
+
allSeenProducts.indexOf(val.typeOfProduct) % colors.length
|
|
68
|
+
],
|
|
69
|
+
value: val.value.toLocaleString(),
|
|
70
|
+
})),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
return { title: "", items: [] };
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
}, [graphData, allSeenProducts, options.minerals]);
|
|
77
|
+
|
|
78
|
+
return chartConfig;
|
|
79
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import React, { useMemo } from 'react'
|
|
2
|
+
import Widget from '../../../../../../../core/components/Dashboard/Widget/index.jsx';
|
|
3
|
+
import LineChart from '../../../../../../../core/components/Charts/LineChart/index.jsx';
|
|
4
|
+
import { Select } from 'antd';
|
|
5
|
+
import { useIdentification } from './hook';
|
|
6
|
+
import PropTypes from 'prop-types';
|
|
7
|
+
|
|
8
|
+
function Identification({
|
|
9
|
+
selectedSources = {},
|
|
10
|
+
isTradeActions = false,
|
|
11
|
+
loading = false,
|
|
12
|
+
data = [],
|
|
13
|
+
onChangeRange = () => {},
|
|
14
|
+
selectedRange = 'monthly',
|
|
15
|
+
t = () => {},
|
|
16
|
+
theme = {},
|
|
17
|
+
options = {}
|
|
18
|
+
}) {
|
|
19
|
+
const selectOptions = useMemo(
|
|
20
|
+
() => [
|
|
21
|
+
{ label: t("Daily"), value: "daily" },
|
|
22
|
+
{ label: t("Weekly"), value: "weekly" },
|
|
23
|
+
{ label: t("Monthly"), value: "monthly" },
|
|
24
|
+
],
|
|
25
|
+
[t],
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
const chartConfig = useIdentification({ data, theme, options });
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<Widget
|
|
32
|
+
loading={loading}
|
|
33
|
+
title={t("Identification")}
|
|
34
|
+
className="with-border-header"
|
|
35
|
+
addedHeader={
|
|
36
|
+
<>
|
|
37
|
+
<div className="flex-1" />
|
|
38
|
+
<Select
|
|
39
|
+
value={selectedRange}
|
|
40
|
+
style={{ width: 100 }}
|
|
41
|
+
onChange={onChangeRange}
|
|
42
|
+
options={selectOptions}
|
|
43
|
+
popupMatchSelectWidth={120}
|
|
44
|
+
/>
|
|
45
|
+
</>
|
|
46
|
+
}
|
|
47
|
+
>
|
|
48
|
+
<LineChart {...chartConfig} height="400px" t={t} />
|
|
49
|
+
</Widget>
|
|
50
|
+
)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
Identification.propTypes = {
|
|
54
|
+
selectedSources: PropTypes.object,
|
|
55
|
+
isTradeActions: PropTypes.bool,
|
|
56
|
+
loading: PropTypes.bool,
|
|
57
|
+
data: PropTypes.array,
|
|
58
|
+
onChangeRange: PropTypes.func,
|
|
59
|
+
selectedRange: PropTypes.string,
|
|
60
|
+
t: PropTypes.func,
|
|
61
|
+
theme: PropTypes.object,
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export default Identification
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import React, { useMemo, useCallback } from 'react'
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { renderTooltipJsx } from '../../../../../../../utils/tooltip.js';
|
|
4
|
+
import { findOptions } from '../../../../../../../../helpers/StringHelper.js';
|
|
5
|
+
import Widget from '../../../../../../../core/components/Dashboard/Widget/index.jsx';
|
|
6
|
+
import Chart from '../../../../../../../core/components/Charts/PieChart/chart.jsx';
|
|
7
|
+
import { getColors } from './config';
|
|
8
|
+
|
|
9
|
+
function Locations({selectedSources = {}, data = [], loading = false, t = () => {}, options = {}, theme = {}}) {
|
|
10
|
+
const { countries = [] } = options;
|
|
11
|
+
const colors = getColors(theme);
|
|
12
|
+
|
|
13
|
+
const pieData = useMemo(() => {
|
|
14
|
+
// eslint-disable-next-line no-shadow-restricted-names
|
|
15
|
+
const { undefined, ...rest } = data;
|
|
16
|
+
const total = Object.values(rest).reduce((all, val) => all + (val || 0), 0);
|
|
17
|
+
|
|
18
|
+
return Object.keys(rest).map((key, index) => {
|
|
19
|
+
const color = colors[index % colors.length];
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
value: rest[key] || 0,
|
|
23
|
+
percent: (rest[key] || 0) / total,
|
|
24
|
+
color: color,
|
|
25
|
+
label: findOptions(key, countries),
|
|
26
|
+
key: key,
|
|
27
|
+
};
|
|
28
|
+
});
|
|
29
|
+
}, [data, countries]);
|
|
30
|
+
|
|
31
|
+
const isEmpty = useMemo(
|
|
32
|
+
() => Object.keys(data).filter((k) => !!data[k]).length === 0,
|
|
33
|
+
[data],
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
const getTooltipChildren = useCallback(
|
|
37
|
+
(item) => {
|
|
38
|
+
if (isEmpty) {
|
|
39
|
+
if (!Object.keys(data).length) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return renderTooltipJsx({
|
|
44
|
+
title: t("Location"),
|
|
45
|
+
items: Object.keys(data).map((k) => ({
|
|
46
|
+
label: findOptions(k, countries),
|
|
47
|
+
value: 0,
|
|
48
|
+
})),
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return renderTooltipJsx({
|
|
53
|
+
title: t("Location"),
|
|
54
|
+
items: [
|
|
55
|
+
{
|
|
56
|
+
color: item.color,
|
|
57
|
+
label: t(item.label),
|
|
58
|
+
value: `${item.value || 0}`,
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
});
|
|
62
|
+
},
|
|
63
|
+
[t, isEmpty, countries],
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
<Widget
|
|
69
|
+
loading={loading}
|
|
70
|
+
title={<div>{t("Location")}</div>}
|
|
71
|
+
className="with-border-header h-w-btn-header"
|
|
72
|
+
>
|
|
73
|
+
<div
|
|
74
|
+
style={{
|
|
75
|
+
marginTop: "auto",
|
|
76
|
+
marginBottom: "auto",
|
|
77
|
+
}}
|
|
78
|
+
>
|
|
79
|
+
<Chart
|
|
80
|
+
mouseXOffset={10}
|
|
81
|
+
mouseYOffset={10}
|
|
82
|
+
changeOpacityOnHover={false}
|
|
83
|
+
data={pieData}
|
|
84
|
+
doConstraints={false}
|
|
85
|
+
isPie
|
|
86
|
+
t={t}
|
|
87
|
+
isEmpty={isEmpty}
|
|
88
|
+
getTooltipChildren={getTooltipChildren}
|
|
89
|
+
/>
|
|
90
|
+
</div>
|
|
91
|
+
</Widget>
|
|
92
|
+
)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
Locations.propTypes = {
|
|
96
|
+
selectedSources: PropTypes.object,
|
|
97
|
+
data: PropTypes.array,
|
|
98
|
+
loading: PropTypes.bool,
|
|
99
|
+
t: PropTypes.func,
|
|
100
|
+
options: PropTypes.object,
|
|
101
|
+
theme: PropTypes.object,
|
|
102
|
+
}
|
|
103
|
+
export default Locations
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import React, { useState, useMemo } from 'react'
|
|
2
|
+
import { useWidgetFetch } from '../../../../../hooks/useWidgetFetch.js';
|
|
3
|
+
import Widget from '../../../../../core/components/Dashboard/Widget/index.jsx';
|
|
4
|
+
import Identification from './components/Identification';
|
|
5
|
+
import Locations from './components/Locations';
|
|
6
|
+
import PropTypes from 'prop-types';
|
|
7
|
+
import GenderDistribution from './components/GenderDistribution';
|
|
8
|
+
|
|
9
|
+
function ChartsContainer({selectedSources = {}, isTradeActions = false, t = () => {}, theme = {}, options = {}}) {
|
|
10
|
+
const [selectedRange, setSelectedRange] = useState("monthly");
|
|
11
|
+
const [previousRange, setPreviousRange] = useState("monthly");
|
|
12
|
+
|
|
13
|
+
function handleRangeChange(range) {
|
|
14
|
+
setPreviousRange(selectedRange);
|
|
15
|
+
setSelectedRange(range);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const defaultConfig = useMemo(
|
|
19
|
+
() => ({
|
|
20
|
+
basepath: "analytics",
|
|
21
|
+
url: isTradeActions ? "/widgets/supply-chain-trade-actors" : "/widgets/supply-chain-mines",
|
|
22
|
+
filters: {
|
|
23
|
+
sources: selectedSources?.partners || [],
|
|
24
|
+
range: selectedRange,
|
|
25
|
+
},
|
|
26
|
+
stop: selectedSources?.loading,
|
|
27
|
+
defaultData: [],
|
|
28
|
+
}),
|
|
29
|
+
[isTradeActions, selectedSources, selectedRange],
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
const { loading, data } = useWidgetFetch({config: defaultConfig, onFetch: () => setPreviousRange(selectedRange)});
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<Widget
|
|
36
|
+
title={isTradeActions ? t("Trade Actors") : t("Mining Sites")}
|
|
37
|
+
className="with-border-header"
|
|
38
|
+
loading={loading}
|
|
39
|
+
>
|
|
40
|
+
<section>
|
|
41
|
+
<Identification
|
|
42
|
+
data={data?.identification}
|
|
43
|
+
t={t}
|
|
44
|
+
theme={theme}
|
|
45
|
+
selectedSources={selectedSources}
|
|
46
|
+
isTradeActions={isTradeActions}
|
|
47
|
+
loading={loading}
|
|
48
|
+
onChangeRange={handleRangeChange}
|
|
49
|
+
selectedRange={selectedRange}
|
|
50
|
+
options={options}
|
|
51
|
+
/>
|
|
52
|
+
<Locations
|
|
53
|
+
data={data?.locations}
|
|
54
|
+
t={t}
|
|
55
|
+
theme={theme}
|
|
56
|
+
selectedSources={selectedSources}
|
|
57
|
+
loading={loading}
|
|
58
|
+
options={options}
|
|
59
|
+
/>
|
|
60
|
+
<GenderDistribution
|
|
61
|
+
selectedSources={selectedSources}
|
|
62
|
+
isTradeActions={isTradeActions}
|
|
63
|
+
loading={loading && previousRange === selectedRange}
|
|
64
|
+
data={isTradeActions ? data.role : data.workforce}
|
|
65
|
+
t={t}
|
|
66
|
+
theme={theme}
|
|
67
|
+
options={options}
|
|
68
|
+
/>
|
|
69
|
+
</section>
|
|
70
|
+
</Widget>
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export default ChartsContainer
|
|
75
|
+
|
|
76
|
+
ChartsContainer.propTypes = {
|
|
77
|
+
selectedSources: PropTypes.object,
|
|
78
|
+
isTradeActions: PropTypes.bool,
|
|
79
|
+
t: PropTypes.func,
|
|
80
|
+
theme: PropTypes.object,
|
|
81
|
+
options: PropTypes.object,
|
|
82
|
+
}
|