datastake-daf 0.6.746 → 0.6.747

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 (34) hide show
  1. package/dist/hooks/index.js +2 -2
  2. package/dist/pages/index.js +2478 -176
  3. package/dist/services/index.js +23 -1
  4. package/package.json +1 -1
  5. package/src/@daf/hooks/useSources.js +1 -1
  6. package/src/@daf/pages/Summary/Minesite/components/LocationMap/index.js +61 -0
  7. package/src/@daf/pages/Summary/Minesite/components/MineSiteDetails/config.js +77 -0
  8. package/src/@daf/pages/Summary/Minesite/components/MineSiteDetails/index.js +47 -0
  9. package/src/@daf/pages/Summary/Minesite/components/StakeholderMapping/config.js +26 -0
  10. package/src/@daf/pages/Summary/Minesite/components/StakeholderMapping/helper.js +64 -0
  11. package/src/@daf/pages/Summary/Minesite/components/StakeholderMapping/index.js +56 -0
  12. package/src/@daf/pages/Summary/Minesite/index.jsx +162 -0
  13. package/src/@daf/pages/Summary/Operator/components/Governance/config.js +26 -0
  14. package/src/@daf/pages/Summary/Operator/components/Governance/helper.js +61 -0
  15. package/src/@daf/pages/Summary/Operator/components/Governance/index.js +55 -0
  16. package/src/@daf/pages/Summary/Operator/components/KeyInformation/config.js +84 -0
  17. package/src/@daf/pages/Summary/Operator/components/KeyInformation/index.js +46 -0
  18. package/src/@daf/pages/Summary/Operator/components/TradeRelationships/config.js +40 -0
  19. package/src/@daf/pages/Summary/Operator/components/TradeRelationships/helper.js +98 -0
  20. package/src/@daf/pages/Summary/Operator/components/TradeRelationships/hook.js +160 -0
  21. package/src/@daf/pages/Summary/Operator/components/TradeRelationships/index.js +83 -0
  22. package/src/@daf/pages/Summary/Operator/hook.js +176 -0
  23. package/src/@daf/pages/Summary/Operator/index.jsx +170 -0
  24. package/src/@daf/pages/Summary/components/InformationAvailability/components/Contributions/index.js +36 -0
  25. package/src/@daf/pages/Summary/components/InformationAvailability/components/InformationCompleteness/index.js +58 -0
  26. package/src/@daf/pages/Summary/components/InformationAvailability/index.js +42 -0
  27. package/src/@daf/pages/Summary/hook.js +188 -0
  28. package/src/@daf/services/OperatorService.js +16 -0
  29. package/src/@daf/services/SourceService.js +1 -1
  30. package/src/helpers/StringHelper.js +7 -0
  31. package/src/pages.js +2 -2
  32. package/dist/style/datastake/mapbox-gl.css +0 -330
  33. package/src/@daf/pages/Summary/minesite/index.js +0 -0
  34. package/src/@daf/pages/Summary/operator/index.jsx +0 -76
@@ -0,0 +1,55 @@
1
+ import React, { useMemo } from 'react'
2
+ import { useWidgetFetch } from '../../../../../hooks/useWidgetFetch.js';
3
+ import { getGovernanceData } from './helper.js';
4
+ import Widget from '../../../../../core/components/Dashboard/Widget/index.jsx';
5
+ import StakeholderMappings from '../../../../../core/components/Graphs/StakeholderMappings/index.jsx';
6
+
7
+ const Governance = ({
8
+ selectedPartners = {},
9
+ operatorData = {},
10
+ t = () => {},
11
+ id,
12
+ options = {},
13
+ goTo = () => {},
14
+
15
+ }) => {
16
+ const defaultFetchConfig = useMemo(() => {
17
+ return {
18
+ basepath: "analytics",
19
+ url: "/widgets/information-map-graph",
20
+ filters: {
21
+ datastakeId: id,
22
+ sources: selectedPartners?.partners || [],
23
+ coreSubject: "stakeholder"
24
+ },
25
+ defaultData: {},
26
+ stop: selectedPartners?.loading,
27
+ };
28
+ }, [selectedPartners]);
29
+
30
+ const { data, loading } = useWidgetFetch({config: defaultFetchConfig});
31
+
32
+ const graphData = useMemo(() => {
33
+ return getGovernanceData({data, operatorData, id, options, t, goTo, selectedPartners});
34
+ }, [data, operatorData, options, t]);
35
+
36
+ return (
37
+ <Widget
38
+ loading={loading}
39
+ title={t("Governance")}
40
+ className={"with-border-header no-p-body"}
41
+ >
42
+ <div style={{ height: 600 }}>
43
+ <StakeholderMappings
44
+ data={graphData}
45
+ maxZoom={1.1}
46
+ t={t}
47
+ isSelectable={true}
48
+ isAllOpenDefault={true}
49
+ />
50
+ </div>
51
+ </Widget>
52
+ )
53
+ }
54
+
55
+ export default Governance
@@ -0,0 +1,84 @@
1
+ import React from "react";
2
+ import { Tag, Tooltip } from "antd";
3
+ import CountryFlag from "../../../../../core/components/UI/CountryFlag/index.jsx";
4
+ import {findOptions } from "../../../../../../helpers/StringHelper.js";
5
+
6
+ export const getKeyIndicatorConfig = ({ t, data = {}, options = {} }) => [
7
+ {
8
+ label: t("Country"),
9
+ render: () => {
10
+ if (!data?.country) {
11
+ return "-";
12
+ }
13
+
14
+ const country = findOptions(data?.country, options?.countries);
15
+ const code = data?.country;
16
+
17
+ return (
18
+ <Tooltip title={country}>
19
+ <img
20
+ alt={code}
21
+ style={{ width: 24, borderRadius: 100, height: 24 }}
22
+ src={`https://flagcdn.com/w80/${code.toLowerCase()}.png`}
23
+ />
24
+ </Tooltip>
25
+ );
26
+ },
27
+ },
28
+ {
29
+ label: t("Supply Chain Position"),
30
+ render: () => {
31
+ const position = findOptions(data?.positionSupplyChain, options?.positionSupplyChainOptions);
32
+ return <div>{position|| "-"}</div>;
33
+ },
34
+ },
35
+ {
36
+ label: t("Legal Form"),
37
+ render: () => {
38
+ const subCategory = findOptions(data?.subCategory, options?.subCategoriesOptions);
39
+ return <div>{subCategory || "-"}</div>;
40
+ },
41
+ },
42
+ {
43
+ label: t("Products"),
44
+ render: () => {
45
+ if ((data?.products || []).length === 0) {
46
+ return "-";
47
+ }
48
+
49
+ return (
50
+ <div style={{ display: "flex", flexWrap: "wrap" }}>
51
+ {data?.products?.map((product) => {
52
+ return (
53
+ <Tag
54
+ color="processing"
55
+ style={{ color: "#1677FF", marginBottom: 8 }}
56
+ key={product}
57
+ >
58
+ {t(product)}
59
+ </Tag>
60
+ );
61
+ })}
62
+ </div>
63
+ );
64
+ },
65
+ },
66
+ {
67
+ label: t("Associated Mine Sites"),
68
+ render: () => {
69
+ return <div>{data?.associatedMineSites || 0}</div>;
70
+ },
71
+ },
72
+ {
73
+ label: t("Identified Suppliers"),
74
+ render: () => {
75
+ return <div>{data?.identifiedSuppliers || 0}</div>;
76
+ },
77
+ },
78
+ {
79
+ label: t("Identified Customers"),
80
+ render: () => {
81
+ return <div>{data?.identifiedCustomers || 0}</div>;
82
+ },
83
+ },
84
+ ];
@@ -0,0 +1,46 @@
1
+ import React from 'react'
2
+ import KeyIndicatorsWidget from '../../../../../core/components/Dashboard/Widget/KeyIndicators/index.jsx';
3
+ import { useMemo } from 'react';
4
+ import { useWidgetFetch } from '../../../../../hooks/useWidgetFetch.js';
5
+ import { getKeyIndicatorConfig } from './config.js';
6
+
7
+
8
+ const KeyInformation = ({options = {}, selectedPartners = {}, t = () => {}, id = {}, data = {}, loading = false}) => {
9
+ // const defaultFetchConfig = useMemo(() => {
10
+ // return {
11
+ // basepath: "analytics",
12
+ // url: '/widgets/key-informations',
13
+ // defaultData: [],
14
+ // stop: selectedPartners?.loading,
15
+ // filters: {
16
+ // datastakeId: id,
17
+ // sources: selectedPartners?.partners || [],
18
+ // },
19
+ // };
20
+ // }, [selectedPartners, id]);
21
+
22
+ // const { data, loading } = useWidgetFetch({config: defaultFetchConfig});
23
+
24
+ const config = useMemo(
25
+ () =>
26
+ getKeyIndicatorConfig({
27
+ t,
28
+ data,
29
+ options,
30
+ }),
31
+ [t, data, options],
32
+ );
33
+
34
+ return (
35
+ <KeyIndicatorsWidget
36
+ t={t}
37
+ config={config}
38
+ className="small-content"
39
+ loading={loading}
40
+ withTooltip
41
+ noMinWidth
42
+ />
43
+ )
44
+ }
45
+
46
+ export default KeyInformation
@@ -0,0 +1,40 @@
1
+ import React from "react";
2
+ import CustomIcon from "../../../../../core/components/Icon/CustomIcon.jsx";
3
+
4
+ export const topIconColor = "#6C737F";
5
+ export const iconColorStakeholder = "#08979C";
6
+ export const leftBackgroundColorStakeholder = "#B5F5EC";
7
+ export const iconColorLocation = "#C41D7F";
8
+ export const leftBackgroundColorLocation = "#FFD6E7";
9
+
10
+ export const topIcons = {
11
+ building: <CustomIcon name="Building" color={topIconColor} width={16} height={16} />,
12
+ factory: <CustomIcon name="Factory" color={topIconColor} width={16} height={16} />,
13
+ smelter: <CustomIcon name="Smelter" color={topIconColor} width={16} height={16} />,
14
+ internationalTrader: <CustomIcon name="Globe04" color={topIconColor} width={16} height={16} />,
15
+ exporter: <CustomIcon name="Truck01" color={topIconColor} width={16} height={16} />,
16
+ miningOperator: <CustomIcon name="MineOperators" color={topIconColor} width={16} height={16} />,
17
+ mineSite: <CustomIcon name="MineSite" color={topIconColor} width={16} height={16} />,
18
+ location: <CustomIcon name="PMESmallLogo" color={topIconColor} width={16} height={16} />,
19
+ inCountryTrader: <CustomIcon name="Handshake" color={topIconColor} width={16} height={16} />,
20
+ localTradingHouse: <CustomIcon name="Building" color={topIconColor} width={16} height={16} />,
21
+ mineralProcessor: <CustomIcon name="Building" color={topIconColor} width={16} height={16} />,
22
+ inCountryTransporter: <CustomIcon name="Truck01" color={topIconColor} width={16} height={16} />,
23
+ internationalTransporter: (
24
+ <CustomIcon name="Truck01" color={topIconColor} width={16} height={16} />
25
+ ),
26
+ };
27
+
28
+ export const leftIcons = {
29
+ stakeholder: (
30
+ <CustomIcon
31
+ name="DashboardStakeholder"
32
+ color={iconColorStakeholder}
33
+ width={16}
34
+ height={16}
35
+ />
36
+ ),
37
+ location: (
38
+ <CustomIcon name="DashboardLocations" color={iconColorLocation} width={16} height={16} />
39
+ ),
40
+ };
@@ -0,0 +1,98 @@
1
+ import { leftIcons, leftBackgroundColorLocation, leftBackgroundColorStakeholder, topIcons } from './config.js';
2
+ import { findOptions } from '../../../../../../helpers/StringHelper.js';
3
+
4
+ export const getFilterConfig = ({operatorData = {}, options = {}, filters = {}, t = () => {}}) => {
5
+ const productSet = new Set();
6
+ const allTradeMineralOptions = [
7
+ ...(operatorData?.suppliers || []),
8
+ ...(operatorData?.clients || []),
9
+ ...(operatorData?.locationSuppliers || []),
10
+ ].flatMap((trade) =>
11
+ (trade?.products || [])
12
+ .filter(
13
+ (product) => !!product?.typeOfProduct && !productSet.has(product.typeOfProduct),
14
+ )
15
+ .map((product) => {
16
+ productSet.add(product.typeOfProduct);
17
+
18
+ const label = options?.minerals?.find(
19
+ (mineral) => mineral.value === product.typeOfProduct,
20
+ )?.label;
21
+
22
+ return {
23
+ value: product.typeOfProduct,
24
+ label: label ?? product.typeOfProduct,
25
+ };
26
+ }),
27
+ );
28
+
29
+ const combinedMineralOptions = [...allTradeMineralOptions].filter((option, index, self) => {
30
+ return option && index === self.findIndex((o) => o.value === option.value);
31
+ });
32
+
33
+ const value = filters.products ? { value: filters.products } : {};
34
+ return [
35
+ {
36
+ label: t("Products"),
37
+ placeholder: t("Select"),
38
+ key: "products",
39
+ type: "select",
40
+ ...value,
41
+ options: combinedMineralOptions,
42
+ },
43
+ ];
44
+ }
45
+
46
+ export const getLeft = (data = {}, mapChildren = () => {}, supplierLocations = []) => {
47
+ if (data?.suppliers?.length > 0) {
48
+ return mapChildren(data.suppliers, data.datastakeId, "left").filter(
49
+ (d) => !!d,
50
+ );
51
+ }
52
+
53
+ const storeLocation = supplierLocations;
54
+ supplierLocations = [];
55
+
56
+ return storeLocation
57
+ .map((location) => {
58
+ return mapChildren([location], location.connect, "left");
59
+ })
60
+ .flat()
61
+ .filter((d) => !!d);
62
+ }
63
+
64
+ export const mapItem = (data, options, goTo, getRedirectLink) => {
65
+ const { positionSupplyChainOptions, locationCategories } = options || {};
66
+ return {
67
+ id: data.datastakeId || "-",
68
+ datastakeId: data.datastakeId || "-",
69
+ leftIcon: leftIcons[data.type === "mineSite" ? "location" : "stakeholder"],
70
+ name: data.name || "-",
71
+ subTitle: findOptions(data.type, [
72
+ ...(positionSupplyChainOptions || []),
73
+ ...(locationCategories || []),
74
+ ]),
75
+ leftBackground:
76
+ data.type === "mineSite"
77
+ ? leftBackgroundColorLocation
78
+ : leftBackgroundColorStakeholder,
79
+ topIcon: topIcons[data.type],
80
+ country: {
81
+ label: findOptions(data.country, options?.countries || []),
82
+ value: data.country,
83
+ },
84
+ totalSources: data.sources ?? 0,
85
+ volume: data?.volume || "",
86
+ onClick: function () {
87
+ if (data.type === "mineSite") {
88
+ return goTo(
89
+ getRedirectLink(`/app/summary/scl/${data.datastakeId}`),
90
+ );
91
+ }
92
+ return goTo(
93
+ getRedirectLink(`/app/summary/operators/${data.datastakeId}`),
94
+ );
95
+ },
96
+ }
97
+ }
98
+
@@ -0,0 +1,160 @@
1
+ import { useEffect, useState, useMemo } from "react";
2
+ import { useWidgetFetch } from "../../../../../hooks/useWidgetFetch.js";
3
+ import { leftIcons, leftBackgroundColorLocation, leftBackgroundColorStakeholder, topIcons } from './config.js';
4
+ import { findOptions } from '../../../../../../helpers/StringHelper.js';
5
+ import { getLeft, mapItem as _mapItem } from './helper.js';
6
+
7
+
8
+ export const useTradeRelationship = ({
9
+ id,
10
+ selectedPartners,
11
+ options,
12
+ goTo,
13
+ getRedirectLink,
14
+ filters,
15
+ }) => {
16
+ const { positionSupplyChainOptions, locationCategories } = options || {};
17
+ const [graphData, setGraphData] = useState({});
18
+ const [loading, setLoading] = useState(false);
19
+ const [fetchedProducts, setFetchedProducts] = useState(false);
20
+
21
+ const config = useMemo(() => ({
22
+ basepath: "analytics",
23
+ url: "/widgets/trade-connection-map",
24
+ filters: {
25
+ product: filters?.products,
26
+ sources: selectedPartners?.partners || [],
27
+ },
28
+ }), [id, filters?.products, selectedPartners?.partners]);
29
+
30
+ const { data } = useWidgetFetch({config: config});
31
+
32
+ const mapItem = (data) => {
33
+ return _mapItem(data, options, goTo, getRedirectLink);
34
+ }
35
+
36
+
37
+
38
+ useEffect(() => {
39
+ if (id && selectedPartners?.partners?.length > 0 && fetchedProducts) {
40
+ const _fetch = async () => {
41
+ setLoading(true);
42
+
43
+ try {
44
+ let supplierLocations = [];
45
+ const sources = {};
46
+ const dataSources = [];
47
+
48
+ const mapChildren = (children, parentId, type = "left") => {
49
+ return children?.map((child) => {
50
+ const childData = mapItem(child);
51
+
52
+ if (type === "left") {
53
+ supplierLocations.push(
54
+ ...(child?.locations || []).map((location) => {
55
+ return {
56
+ ...location,
57
+ type: "mineSite",
58
+ sources: child.sources || 1,
59
+ suppliers: [],
60
+ clients: [],
61
+ connect: child.datastakeId,
62
+ };
63
+ }),
64
+ );
65
+ }
66
+ const children =
67
+ type === "left" ? [...child.suppliers] : [...child.clients];
68
+
69
+ if (child.datastakeId === data.datastakeId) {
70
+ dataSources.push(parentId);
71
+ return null;
72
+ }
73
+
74
+ if (sources[child.datastakeId]) {
75
+ if (!sources[child.datastakeId].includes(parentId)) {
76
+ sources[child.datastakeId].push(parentId);
77
+ }
78
+ return null;
79
+ } else {
80
+ sources[child.datastakeId] = [parentId];
81
+ }
82
+
83
+ if (
84
+ type === "left" &&
85
+ children?.length === 0 &&
86
+ supplierLocations?.length > 0
87
+ ) {
88
+ const storeLocation = supplierLocations;
89
+ supplierLocations = [];
90
+
91
+ const children = storeLocation?.map((location) => {
92
+ return mapChildren([location], location.connect, "left");
93
+ });
94
+
95
+ return {
96
+ ...childData,
97
+ sources: sources[child.datastakeId] || [],
98
+ children: children.flat()?.filter((d) => !!d),
99
+ };
100
+ }
101
+
102
+ return {
103
+ ...childData,
104
+ sources: sources[child.datastakeId] || [],
105
+ children:
106
+ children.length > 0
107
+ ? mapChildren(children, child.datastakeId, type)?.filter(
108
+ (d) => !!d,
109
+ )
110
+ : [],
111
+ };
112
+ });
113
+ };
114
+
115
+ supplierLocations.push(
116
+ ...(data?.locations || []).map((location) => {
117
+ return {
118
+ ...location,
119
+ type: "mineSite",
120
+ suppliers: [],
121
+ clients: [],
122
+ connect: data?.datastakeId,
123
+ };
124
+ }),
125
+ );
126
+ const graphData = {
127
+ ...mapItem(data),
128
+ onClick: undefined,
129
+ sources: dataSources,
130
+ right: mapChildren(data.clients, data.datastakeId, "right")?.filter(
131
+ (d) => !!d,
132
+ ),
133
+ left: getLeft(data, mapChildren, supplierLocations),
134
+ };
135
+
136
+ console.log({graphData})
137
+
138
+ setGraphData(graphData);
139
+ } catch (err) {
140
+ setGraphData({});
141
+ console.log(err);
142
+ }
143
+
144
+ setLoading(false);
145
+ };
146
+
147
+ _fetch();
148
+ }
149
+ }, [filters?.products, id, selectedPartners, fetchedProducts]);
150
+
151
+ return {
152
+ graphData,
153
+ loading,
154
+ fetchedProducts,
155
+ setFetchedProducts,
156
+ setGraphData,
157
+ setLoading,
158
+ data,
159
+ }
160
+ }
@@ -0,0 +1,83 @@
1
+ import React, { useState, useMemo, useEffect } from 'react'
2
+ import { getFilterConfig } from './helper.js';
3
+ import { useTradeRelationship } from './hook.js';
4
+ import Widget from '../../../../../core/components/Dashboard/Widget/index.jsx';
5
+ import TradeRelationship from '../../../../../core/components/Graphs/TradeRelationship/index.jsx';
6
+
7
+ const TradeRelationships = ({
8
+ t = () => {},
9
+ goTo = () => {},
10
+ operatorData = {},
11
+ selectedPartners = {},
12
+ id,
13
+ options = {},
14
+ getRedirectLink = () => {},
15
+ }) => {
16
+ const [filters, setFilters] = useState({});
17
+
18
+ const onFilterChange = (filters) => {
19
+ setFilters((p) => ({ ...p, ...filters }));
20
+ };
21
+
22
+ const filterConfig = useMemo(() => {
23
+ return getFilterConfig({operatorData, options, filters, t});
24
+ }, [filters.products, t, options?.minerals, operatorData]);
25
+
26
+ const { graphData, loading, fetchedProducts, setFetchedProducts } = useTradeRelationship({
27
+ id,
28
+ selectedPartners,
29
+ options,
30
+ goTo,
31
+ getRedirectLink,
32
+ filters,
33
+ });
34
+
35
+ useEffect(() => {
36
+ const defaultProduct = filterConfig?.[0]?.options?.[0]?.value;
37
+
38
+ if (!filters.products && defaultProduct) {
39
+ setFilters((prev) => {
40
+ const data = { ...prev, products: defaultProduct };
41
+ return data;
42
+ });
43
+ }
44
+
45
+ if (!fetchedProducts) {
46
+ setFetchedProducts(true);
47
+ }
48
+ }, [filterConfig]);
49
+
50
+ return (
51
+ <Widget
52
+ title={t("Trade Relationships")}
53
+ className="flex flex-1 with-border-header no-p-body"
54
+ loading={loading}
55
+ >
56
+ <div className="flex flex-1 flex-column justify-content-center">
57
+ <div style={{ height: 600 }} className="flex flex-column">
58
+ <TradeRelationship
59
+ data={graphData}
60
+ goTo={goTo}
61
+ t={t}
62
+ getTotal={(c) => {
63
+ return c.totalSources || 0;
64
+ }}
65
+ renderTooltipItems={(data) => [
66
+ {
67
+ label: "Volume",
68
+ value: data?.volume || "--",
69
+ },
70
+ ]}
71
+ maxZoom={1.2}
72
+ minZoom={0.4}
73
+ tooltipTitle="Trade"
74
+ filtersConfig={filterConfig}
75
+ onFilterChange={onFilterChange}
76
+ />
77
+ </div>
78
+ </div>
79
+ </Widget>
80
+ )
81
+ }
82
+
83
+ export default TradeRelationships