datastake-daf 0.6.746 → 0.6.748

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 (48) hide show
  1. package/dist/components/index.js +769 -461
  2. package/dist/hooks/index.js +2 -2
  3. package/dist/layouts/index.js +497 -440
  4. package/dist/pages/index.js +3414 -683
  5. package/dist/services/index.js +23 -1
  6. package/dist/utils/index.js +497 -440
  7. package/package.json +1 -1
  8. package/src/@daf/core/components/Dashboard/Widget/ActivityIndicators/ActivityIndicators.stories.js +252 -0
  9. package/src/@daf/core/components/Dashboard/Widget/ActivityIndicators/config.js +76 -0
  10. package/src/@daf/core/components/Dashboard/Widget/ActivityIndicators/index.jsx +184 -0
  11. package/src/@daf/core/components/Dashboard/Widget/ActivityIndicators/style.js +119 -0
  12. package/src/@daf/core/components/Icon/configs/Aid.js +10 -0
  13. package/src/@daf/core/components/Icon/configs/Bear.js +8 -0
  14. package/src/@daf/core/components/Icon/configs/Minus.js +10 -0
  15. package/src/@daf/core/components/Icon/configs/Security.js +12 -0
  16. package/src/@daf/core/components/Icon/configs/index.js +8 -0
  17. package/src/@daf/hooks/useSources.js +1 -1
  18. package/src/@daf/pages/Summary/Activities/Restoration/helper.js +86 -2
  19. package/src/@daf/pages/Summary/Activities/Restoration/index.jsx +20 -19
  20. package/src/@daf/pages/Summary/Minesite/components/LocationMap/index.js +61 -0
  21. package/src/@daf/pages/Summary/Minesite/components/MineSiteDetails/config.js +77 -0
  22. package/src/@daf/pages/Summary/Minesite/components/MineSiteDetails/index.js +47 -0
  23. package/src/@daf/pages/Summary/Minesite/components/StakeholderMapping/config.js +26 -0
  24. package/src/@daf/pages/Summary/Minesite/components/StakeholderMapping/helper.js +64 -0
  25. package/src/@daf/pages/Summary/Minesite/components/StakeholderMapping/index.js +56 -0
  26. package/src/@daf/pages/Summary/Minesite/index.jsx +162 -0
  27. package/src/@daf/pages/Summary/Operator/components/Governance/config.js +26 -0
  28. package/src/@daf/pages/Summary/Operator/components/Governance/helper.js +61 -0
  29. package/src/@daf/pages/Summary/Operator/components/Governance/index.js +55 -0
  30. package/src/@daf/pages/Summary/Operator/components/KeyInformation/config.js +84 -0
  31. package/src/@daf/pages/Summary/Operator/components/KeyInformation/index.js +46 -0
  32. package/src/@daf/pages/Summary/Operator/components/TradeRelationships/config.js +40 -0
  33. package/src/@daf/pages/Summary/Operator/components/TradeRelationships/helper.js +98 -0
  34. package/src/@daf/pages/Summary/Operator/components/TradeRelationships/hook.js +160 -0
  35. package/src/@daf/pages/Summary/Operator/components/TradeRelationships/index.js +83 -0
  36. package/src/@daf/pages/Summary/Operator/hook.js +176 -0
  37. package/src/@daf/pages/Summary/Operator/index.jsx +170 -0
  38. package/src/@daf/pages/Summary/components/InformationAvailability/components/Contributions/index.js +36 -0
  39. package/src/@daf/pages/Summary/components/InformationAvailability/components/InformationCompleteness/index.js +58 -0
  40. package/src/@daf/pages/Summary/components/InformationAvailability/index.js +42 -0
  41. package/src/@daf/pages/Summary/hook.js +188 -0
  42. package/src/@daf/services/OperatorService.js +16 -0
  43. package/src/@daf/services/SourceService.js +1 -1
  44. package/src/helpers/StringHelper.js +7 -0
  45. package/src/index.js +1 -0
  46. package/src/pages.js +2 -2
  47. package/src/@daf/pages/Summary/minesite/index.js +0 -0
  48. package/src/@daf/pages/Summary/operator/index.jsx +0 -76
@@ -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
@@ -0,0 +1,176 @@
1
+ import { useState, useMemo, useCallback, useEffect } from "react"
2
+ import { debounce } from "lodash";
3
+ import { StorageManager } from "../../../../helpers/StorageManager.js";
4
+
5
+ export const useSummary = ({
6
+ getOne,
7
+ getMultiple,
8
+ id,
9
+ hasSelect = false,
10
+ storageKey,
11
+ data,
12
+ isPdf,
13
+ params,
14
+ partners,
15
+ selectedPartners,
16
+ user,
17
+ t,
18
+ theme = {},
19
+ service
20
+ }) => {
21
+ const [search, setSearch] = useState("");
22
+ const [debouncedSearch, setDebouncedSearch] = useState("");
23
+ const [hasInitialized, setHasInitialized] = useState(false);
24
+ const [singleItemData, setSingleItemData] = useState();
25
+ const [loading, setLoading] = useState(false);
26
+ const [_partners, _setPartners] = useState();
27
+
28
+ const [selectedItem, setSelectedItem] = useState(undefined);
29
+
30
+ const dataOptions = useMemo(() => {
31
+ const mappedData = data?.map((item) => ({
32
+ label: item?.name,
33
+ value: item?.datastakeId
34
+ })) || [];
35
+
36
+ const storedData = StorageManager.get(storageKey);
37
+ if (storedData) {
38
+ try {
39
+ const parsedStoredData = JSON.parse(storedData);
40
+ const existsInData = mappedData?.find(item => item.value === parsedStoredData.value);
41
+
42
+ if (!existsInData) {
43
+ return [...mappedData, parsedStoredData];
44
+ }
45
+ } catch (error) {
46
+ console.log('Error parsing stored data:', error);
47
+ }
48
+ }
49
+
50
+ return mappedData;
51
+ }, [data, hasSelect, storageKey])
52
+
53
+ useEffect(() => {
54
+ if (hasSelect && dataOptions && dataOptions.length > 0 && !debouncedSearch && !hasInitialized) {
55
+ let selectedValue;
56
+
57
+ if (isPdf) {
58
+ selectedValue = id;
59
+ } else {
60
+ const storedData = StorageManager.get(storageKey);
61
+ if (storedData) {
62
+ try {
63
+ const parsedData = JSON.parse(storedData);
64
+ const existsInOptions = dataOptions?.find((item) => item?.value === parsedData?.value);
65
+ selectedValue = existsInOptions ? parsedData?.value : (Array.isArray(dataOptions) ? dataOptions[0]?.value : undefined);
66
+ } catch (error) {
67
+ console.log('Error parsing stored data:', error);
68
+ selectedValue = Array.isArray(dataOptions) ? dataOptions[0]?.value : undefined;
69
+ }
70
+ } else {
71
+ selectedValue = Array.isArray(dataOptions) ? dataOptions[0]?.value : undefined;
72
+ }
73
+ }
74
+
75
+ setSelectedItem(selectedValue);
76
+ setHasInitialized(true);
77
+ }
78
+ }, [hasSelect, storageKey, isPdf, id, debouncedSearch, hasInitialized, dataOptions]);
79
+
80
+ useEffect(() => {
81
+ if (selectedItem) {
82
+ const selectedData = data?.find((item) => item?.datastakeId === selectedItem);
83
+ if(selectedData) {
84
+ const saved = {
85
+ label: selectedData.name,
86
+ value: selectedData.datastakeId,
87
+ }
88
+ StorageManager.set(storageKey, JSON.stringify(saved));
89
+ }
90
+ }
91
+ }, [selectedItem, storageKey]);
92
+
93
+ const debouncedSetSearch = useMemo(
94
+ () => debounce((value) => setDebouncedSearch(value), 300),
95
+ []
96
+ );
97
+
98
+ const onSearch = useCallback((value) => {
99
+ setSearch(value);
100
+ debouncedSetSearch(value);
101
+ }, [debouncedSetSearch]);
102
+
103
+
104
+ useEffect(() => {
105
+ setDebouncedSearch("");
106
+ }, [selectedItem]);
107
+
108
+ const filters = useMemo(() => {
109
+ return {
110
+ pagination: { size: 20, page: 1 },
111
+ ...(debouncedSearch
112
+ ? { search: { qs: debouncedSearch, fields: ["name","datastakeId","orgShortName"] } }
113
+ : {}),
114
+ };
115
+ }, [debouncedSearch]);
116
+
117
+ useEffect(() => {
118
+ if (_partners !== undefined) {
119
+ if ((params?.id !== null || (isPdf && id !== null)) && !hasSelect) {
120
+ getOne(params?.id || id, { sources: _partners });
121
+ }
122
+ }
123
+ if (hasSelect && !params?.id) {
124
+ getMultiple(filters);
125
+ }
126
+ }, [params?.id, hasSelect, getOne, getMultiple, _partners, isPdf, id, filters]);
127
+
128
+ useEffect(() => {
129
+ if (selectedItem && _partners !== undefined) {
130
+ const fetchSingleItem = async () => {
131
+ setLoading(true);
132
+ try {
133
+ const { data } = await service.getOne(selectedItem, { sources: _partners });
134
+ setSingleItemData(data);
135
+ } catch (error) {
136
+ console.log(error);
137
+ } finally {
138
+ setLoading(false);
139
+ }
140
+ };
141
+ fetchSingleItem();
142
+ }
143
+ }, [selectedItem, service, _partners]);
144
+
145
+ useEffect(() => {
146
+ _setPartners(selectedPartners?.partners);
147
+ }, [selectedPartners]);
148
+
149
+ const sourceOptions = useMemo(() => {
150
+ return partners?.map((partner) => {
151
+ const isOwnData = partner.id === user?.company?.id;
152
+
153
+ return {
154
+ label: isOwnData ? t("Own Data") : partner.nickName,
155
+ value: partner.id,
156
+ avatar: isOwnData ? <span>OWN</span> : undefined,
157
+ background: isOwnData ? theme.colorPrimary7 : undefined,
158
+ color: isOwnData ? "white" : undefined,
159
+ };
160
+ });
161
+ }, [partners, user]);
162
+
163
+ return {
164
+ selectedItem,
165
+ setSelectedItem,
166
+ dataOptions,
167
+ search,
168
+ debouncedSearch,
169
+ onSearch,
170
+ setSearch,
171
+ setDebouncedSearch,
172
+ sourceOptions,
173
+ singleItemData,
174
+ loading,
175
+ }
176
+ }
@@ -0,0 +1,170 @@
1
+ import React from 'react'
2
+ import DashboardLayout from '../../../core/components/Dashboard/DashboardLayout/index.jsx'
3
+ import { Select, Spin } from 'antd'
4
+ import { useSummary } from '../hook.js'
5
+ import Header from '../../../core/components/Header/index.jsx'
6
+ import Multiselect from '../../../core/components/Select/MultiSelect/index.jsx'
7
+ import KeyInformation from './components/KeyInformation/index.js'
8
+ import InformationAvailability from '../components/InformationAvailability/index.js'
9
+ import TradeRelationships from './components/TradeRelationships/index.js'
10
+ import Governance from './components/Governance/index.js'
11
+
12
+ const OperatorSummary = ({
13
+ hasSelect = false,
14
+ loading = false,
15
+ getSingleData = () => {},
16
+ getMultipleData = () => {},
17
+ data = [],
18
+ id = '',
19
+ storageKey = '',
20
+ isPdf = false,
21
+ params = {},
22
+ partners = [],
23
+ selectedPartners = {},
24
+ user = {},
25
+ t = () => {},
26
+ theme = {},
27
+ service,
28
+ options = {},
29
+ goTo = () => {},
30
+ getRedirectLink = () => {},
31
+ goBack = () => {},
32
+ onIdChange = () => {}
33
+ }) => {
34
+ const {
35
+ selectedItem,
36
+ setSelectedItem,
37
+ dataOptions,
38
+ search,
39
+ debouncedSearch,
40
+ onSearch,
41
+ setSearch,
42
+ setDebouncedSearch,
43
+ sourceOptions,
44
+ setSelectedPartners,
45
+ singleItemData,
46
+ loading: loadingData,
47
+ } = useSummary({
48
+ getOne: getSingleData,
49
+ getMultiple: getMultipleData,
50
+ id,
51
+ hasSelect,
52
+ storageKey,
53
+ data,
54
+ isPdf: false,
55
+ params,
56
+ partners,
57
+ selectedPartners,
58
+ user,
59
+ t,
60
+ theme,
61
+ service,
62
+ onIdChange,
63
+ });
64
+
65
+ return (
66
+ <DashboardLayout
67
+ header={
68
+ <Header
69
+ title={t('Operator Summary')}
70
+ className="with-border-header h-w-btn-header no-px-body"
71
+ goBackTo={!hasSelect && goBack}
72
+ addedHeaderFirst
73
+ actionButtons={[
74
+ {
75
+ tooltip: t("Details"),
76
+ icon: "FileEdit",
77
+ onClick: () => {
78
+ goTo(getRedirectLink(`/app/view/operators/${params?.id ? params?.id : selectedItem}`));
79
+ },
80
+ },
81
+ {
82
+ tooltip: t("Find Data"),
83
+ icon: "Search",
84
+ onClick: () => {},
85
+ disabled: true,
86
+ },
87
+ ]}
88
+ addedHeader={
89
+ <div className="flex flex-row gap-4" style={{ marginRight: 8 }}>
90
+ <Multiselect
91
+ options={[...sourceOptions]}
92
+ isAvatarGroup
93
+ selectionType="checkbox"
94
+ key={partners?.length}
95
+ canUnselectLast={false}
96
+ onChange={(selected) => {
97
+ setSelectedPartners((prev) => ({
98
+ ...prev,
99
+ partners: selected,
100
+ loading: false,
101
+ }));
102
+ }}
103
+ dropDownWidth={200}
104
+ defaultSelected={(partners || []).map((p) => p.id) || []}
105
+ />
106
+ </div>
107
+ }
108
+ />
109
+ }
110
+ >
111
+ {hasSelect && (
112
+ <section>
113
+ <Select
114
+ showSearch
115
+ debounceTimeout={300}
116
+ onSearch={onSearch}
117
+ isSingle
118
+ style={{ height: "40px", width: "100%" }}
119
+ value={selectedItem}
120
+ onChange={setSelectedItem}
121
+ options={dataOptions}
122
+ filterOption={false}
123
+ loading={loading}
124
+ notFoundContent={loading ? <Spin size="small" /> : null}
125
+ />
126
+ </section>
127
+ )}
128
+ <KeyInformation
129
+ options={options}
130
+ selectedPartners={selectedPartners}
131
+ t={t}
132
+ id={params?.id || selectedItem}
133
+ data={hasSelect ? singleItemData : data}
134
+ loading={loading}
135
+ />
136
+ <section>
137
+ <InformationAvailability
138
+ selectedPartners={selectedPartners}
139
+ t={t}
140
+ id={params?.id || selectedItem}
141
+ />
142
+ </section>
143
+ <section>
144
+ <TradeRelationships
145
+ selectedPartners={selectedPartners}
146
+ t={t}
147
+ id={params?.id || selectedItem}
148
+ options={options}
149
+ goTo={goTo}
150
+ getRedirectLink={getRedirectLink}
151
+ operatorData={hasSelect ? singleItemData : data}
152
+ />
153
+ </section>
154
+ <section>
155
+ <Governance
156
+ selectedPartners={selectedPartners}
157
+ t={t}
158
+ id={params?.id || selectedItem}
159
+ options={options}
160
+ goTo={goTo}
161
+ getRedirectLink={getRedirectLink}
162
+ operatorData={hasSelect ? singleItemData : data}
163
+ />
164
+ </section>
165
+
166
+ </DashboardLayout>
167
+ )
168
+ }
169
+
170
+ export default OperatorSummary
@@ -0,0 +1,36 @@
1
+ import React from 'react'
2
+ import Widget from '../../../../../../core/components/Dashboard/Widget/index.jsx';
3
+ import BarChart from '../../../../../../core/components/Charts/BarChart/index.jsx';
4
+
5
+ const Contributions = ({
6
+ data = {},
7
+ loading = false,
8
+ t = () => {},
9
+ }) => {
10
+ return (
11
+ <Widget
12
+ title={t("Contributions")}
13
+ className="with-border-header h-w-btn-header"
14
+ loading={loading}
15
+ >
16
+ <BarChart
17
+ data={data?.stakeholders || []}
18
+ xFieldKey="completedDatapoints"
19
+ yFieldKey="author"
20
+ renderTooltipContent={(title, item) => {
21
+ return {
22
+ title: title,
23
+ items: [
24
+ {
25
+ label: t("Datapoints"),
26
+ value: item?.[0]?.data?.completedDatapoints || 0,
27
+ },
28
+ ],
29
+ };
30
+ }}
31
+ />
32
+ </Widget>
33
+ )
34
+ }
35
+
36
+ export default Contributions
@@ -0,0 +1,58 @@
1
+ import React, { useMemo } from 'react'
2
+ import Widget from '../../../../../../core/components/Dashboard/Widget/index.jsx';
3
+ import RadialBarChart from '../../../../../../core/components/Charts/RadialBarChart/index.jsx';
4
+
5
+ const InformationCompleteness = ({
6
+ data = {},
7
+ loading = false,
8
+ t = () => {},
9
+ }) => {
10
+
11
+ const graphData = useMemo(() => {
12
+ const keys = {
13
+ ownDataCompletion: data?.ownDataCompletion || 0,
14
+ consolidatedCompletion: data?.consolidatedCompletion || 0,
15
+ };
16
+
17
+ const _data = Object.keys(keys).map((key) => {
18
+ const item = keys[key];
19
+
20
+ if (!Array.isArray(item)) {
21
+ return {
22
+ label: key?.includes("own") ? t("Own Data") : t("Consolidated"),
23
+ value: item,
24
+ };
25
+ }
26
+ });
27
+
28
+ return _data.filter((item) => item !== undefined);
29
+ }, [data]);
30
+
31
+ return (
32
+ <Widget
33
+ title={t("Information Completeness")}
34
+ loading={loading}
35
+ className="with-border-header h-w-btn-header"
36
+ >
37
+ <RadialBarChart
38
+ data={graphData}
39
+ renderTooltipContent={(title, item) => {
40
+ const value =
41
+ item?.[0]?.data?.value > 100 ? 100 : item?.[0]?.data?.value || 0;
42
+
43
+ return {
44
+ title: title,
45
+ items: [
46
+ {
47
+ label: t("Completion"),
48
+ value: `${value}%`,
49
+ },
50
+ ],
51
+ };
52
+ }}
53
+ />
54
+ </Widget>
55
+ )
56
+ }
57
+
58
+ export default InformationCompleteness