datastake-daf 0.6.844 → 0.6.846

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 (29) hide show
  1. package/dist/components/index.js +28 -67
  2. package/dist/hooks/index.js +12 -22
  3. package/dist/pages/index.js +4132 -4551
  4. package/dist/utils/index.js +9 -1
  5. package/package.json +1 -1
  6. package/src/@daf/core/components/EditForm/helper.js +14 -6
  7. package/src/@daf/core/components/Screens/Admin/AdminModals/NewUser/index.jsx +1 -1
  8. package/src/@daf/core/components/Screens/Admin/AdminTables/AccountTable/helper.js +59 -77
  9. package/src/@daf/core/components/Screens/Admin/AdminViews/index.jsx +1 -8
  10. package/src/@daf/hooks/useSources.js +6 -4
  11. package/src/@daf/hooks/useWidgetFetch.js +3 -14
  12. package/src/@daf/pages/Dashboards/ConflictManagement/components/RisksWidget/components/IncidentsTime/config.js +3 -0
  13. package/src/@daf/pages/Dashboards/ConflictManagement/components/RisksWidget/components/IncidentsTime/hook.js +69 -4
  14. package/src/@daf/pages/Dashboards/ConflictManagement/components/RisksWidget/components/IncidentsTime/index.js +29 -92
  15. package/src/@daf/pages/Dashboards/ConflictManagement/components/RisksWidget/components/ProblemSolver/hook.js +59 -34
  16. package/src/@daf/pages/Dashboards/ConflictManagement/components/RisksWidget/components/ProblemSolver/index.js +36 -69
  17. package/src/@daf/pages/Dashboards/ConflictManagement/components/RisksWidget/components/TerritorialDistribution/hook.js +56 -0
  18. package/src/@daf/pages/Dashboards/ConflictManagement/components/RisksWidget/components/TerritorialDistribution/index.js +50 -75
  19. package/src/@daf/pages/Dashboards/ConflictManagement/index.js +11 -11
  20. package/src/@daf/pages/Dashboards/SupplyChain/components/ChartsContainer/components/GenderDistribution/index.js +46 -51
  21. package/src/@daf/pages/Dashboards/SupplyChain/components/ChartsContainer/components/Identification/hook.js +20 -20
  22. package/src/@daf/pages/Dashboards/SupplyChain/components/ChartsContainer/components/Identification/index.js +26 -2
  23. package/src/@daf/pages/Dashboards/SupplyChain/index.jsx +0 -1
  24. package/src/@daf/pages/Dashboards/UserDashboard/components/DataChainOfCustody/index.jsx +2 -1
  25. package/src/@daf/pages/Dashboards/UserDashboard/components/MineSites/config.js +10 -1
  26. package/src/@daf/pages/Dashboards/UserDashboard/index.jsx +1 -0
  27. package/src/@daf/pages/Dashboards/helper.js +25 -20
  28. package/src/constants/locales/fr/translation.js +9 -0
  29. package/src/constants/locales/sp/translation.js +1 -0
@@ -9386,6 +9386,9 @@ const fr = {
9386
9386
  "under-development": "Under development",
9387
9387
  "under-development-description": "Our team is actively building this feature. It will be available in an upcoming release.",
9388
9388
  "Confirm new subject": "Confirmer nouveau sujet",
9389
+ "registration": "Enregistrement",
9390
+ "scrutiny": "Contrôle",
9391
+ "Organisation Policies": "Politiques Organisationnelles",
9389
9392
  affirmations: {
9390
9393
  "subject-created-successfully": "Sujet créé avec succès.",
9391
9394
  "information-saved-successfully": "Information sauvegardée avec succès.",
@@ -11157,7 +11160,12 @@ const fr = {
11157
11160
  "date-added": "Date de Création",
11158
11161
  "last-active": "Dernière Activité",
11159
11162
  "key-indicators": "Indicateurs Clés"
11160
- }
11163
+ },
11164
+ "Armed Groups": "Groupes Armés",
11165
+ "Identified Armed Groups": "Groupes Armés Identifiés",
11166
+ "Reported Incidents": "Incidents Signalés",
11167
+ "Conflict Map": "Carte des Conflits",
11168
+ "Conflict Management": "Gestion des Conflits"
11161
11169
  };
11162
11170
 
11163
11171
  const sp = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "datastake-daf",
3
- "version": "0.6.844",
3
+ "version": "0.6.846",
4
4
  "dependencies": {
5
5
  "@ant-design/icons": "^5.2.5",
6
6
  "@antv/g2": "^5.1.1",
@@ -778,10 +778,15 @@ export const inputTypeComponent = {
778
778
  }
779
779
  return {
780
780
  label: o.label,
781
- items: opts.filter((op) => op.group === o.value),
781
+ items: opts.filter((op) => op?.filters?.[0]?.value.includes(o.value)),
782
782
  };
783
783
  });
784
- const notGrouped = opts.filter((op) => !gKeys.includes(op.group));
784
+ const notGrouped = opts.filter((op) => {
785
+ const filterValue = op?.filters?.[0]?.value;
786
+ if (!filterValue) return true;
787
+
788
+ return !gKeys.some(key => filterValue.includes(key));
789
+ });
785
790
  if (notGrouped.length) {
786
791
  groupOptions.unshift(...notGrouped);
787
792
  }
@@ -975,18 +980,21 @@ export const inputTypeComponent = {
975
980
  }
976
981
  return {
977
982
  label: o.label,
978
- items: opts.filter((op) => op.group === o.value),
983
+ items: opts.filter((op) => op?.filters?.[0]?.value.includes(o.value)),
979
984
  };
980
985
  });
981
- const notGrouped = opts.filter((op) => !gKeys.includes(op.group));
986
+ const notGrouped = opts.filter((op) => {
987
+ const filterValue = op?.filters?.[0]?.value;
988
+ if (!filterValue) return true;
989
+
990
+ return !gKeys.some(key => filterValue.includes(key));
991
+ });
982
992
  if (notGrouped.length) {
983
993
  groupOptions.unshift(...notGrouped);
984
994
  }
985
995
  opts = groupOptions;
986
996
  }
987
997
 
988
- console.log({maxWidth, staticWidth, fullWidth});
989
-
990
998
  return (
991
999
  <Select
992
1000
  size="medium"
@@ -62,7 +62,7 @@ export default function NewUser({
62
62
  const localUserData = {
63
63
  ...apiPayload,
64
64
  status: 'pending',
65
- id: apiPayload.email, // Add a unique ID for the table key
65
+ id: apiPayload.email,
66
66
  // apps: {
67
67
  // [module]: {
68
68
  // role: val.role,
@@ -1,6 +1,5 @@
1
- import React from "react";
2
1
  import moment from "moment";
3
- import { Tag, Tooltip, Checkbox } from "antd";
2
+ import { Tag, Tooltip } from "antd";
4
3
  import { findOptions } from "../../../../../../../helpers/StringHelper.js";
5
4
  import CustomIcon from "../../../../Icon/CustomIcon.jsx";
6
5
  import MoreMenu from "../../../../Table/MoreMenu/index.jsx";
@@ -32,57 +31,35 @@ export const getColumns = ({
32
31
  onResendInvitation = () => {},
33
32
  onCanelVerification = () => {},
34
33
  setAddAccountVisible = () => {},
35
- setSelectedAccounts = () => {},
36
- selectedAccounts = [],
34
+
37
35
  }) => {
38
36
  const cols = [
39
- {
40
- title: "",
41
- dataIndex: "select",
42
- key: "select",
43
- width: 50,
44
- active: true,
45
- pending: true,
46
- suspended: true,
47
- show: true,
48
- render: (v, all) => {
49
- if (all.empty) {
50
- return <div className="daf-default-cell" />;
51
- }
52
- return (
53
- <Checkbox
54
- onChange={() =>
55
- setSelectedAccounts((prev) => {
56
- const isSelected = prev.some((p) => p.userId === all.userId);
57
- if (isSelected) {
58
- return prev.filter((p) => p.userId !== all.userId);
59
- }
60
- return [...prev, all];
61
- })
62
- }
63
- checked={selectedAccounts.some((p) => p.userId === all.userId)}
64
- disabled={selectedAccounts.length >= 3 && !selectedAccounts.some((p) => p.userId === all.userId)}
65
- />
66
- );
67
- },
68
- },
37
+
69
38
  {
70
39
  title: t("ID"),
71
- dataIndex: "userId",
72
40
  key: "userId",
41
+ ellipsis: true,
42
+ width: 160,
73
43
  active: true,
74
44
  pending: true,
75
45
  suspended: true,
76
- ellipsis: true,
77
- width: 160,
78
- render: (v, all) => {
79
- if (all.empty) {
80
- return <div className="daf-default-cell" />;
81
- }
82
-
83
- return <div className="daf-default-cell">{v || "--"}</div>;
46
+ render: (_, all) => {
47
+ if (all.empty) {
48
+ return <div className="daf-default-cell" />;
49
+ }
50
+
51
+ const id =
52
+ all.status === "pending"
53
+ ? all.users?.[0]?.userId ??
54
+ all.invitedUser?.userId ??
55
+ all.datastakeId ??
56
+ "--"
57
+ : all.userId ?? "--";
58
+
59
+ return <div className="daf-default-cell">{id}</div>;
84
60
  },
85
- },
61
+ },
62
+
86
63
  {
87
64
  title: t("Name"),
88
65
  dataIndex: "name",
@@ -94,25 +71,28 @@ export const getColumns = ({
94
71
  suspended: true,
95
72
  },
96
73
  {
97
- title: t("type"),
98
- dataIndex: "apps",
99
- key: "apps",
100
- render: (apps, all) => {
101
- if (all.empty) {
102
- return <div className="daf-default-cell" />;
103
- }
104
-
105
- const sbg = all?.interface ? all : (apps || []).find((a) => a.app === module);
106
-
107
- return renderTypeTag({
108
- value: sbg?.interface,
109
- label: findOptions(sbg?.interface, selectOptions.type),
110
- });
74
+ title: t("Type"),
75
+ key: "type",
76
+ render: (_, all) => {
77
+ if (all.empty) {
78
+ return <div className="daf-default-cell" />;
79
+ }
80
+
81
+ const typeValue =
82
+ all.status === "pending"
83
+ ? all.type ?? all.otherData?.interface
84
+ : all.apps?.[0]?.interface;
85
+
86
+ return renderTypeTag({
87
+ value: typeValue,
88
+ label: findOptions(typeValue, selectOptions.type),
89
+ });
111
90
  },
112
91
  active: true,
113
92
  pending: true,
114
93
  suspended: true,
115
- },
94
+ },
95
+
116
96
  {
117
97
  title: t("Email"),
118
98
  dataIndex: "admin",
@@ -165,26 +145,28 @@ export const getColumns = ({
165
145
  pending: true,
166
146
  suspended: false,
167
147
  },
168
- {
169
- title: t("Email Verified"),
170
- dataIndex: "emailVerified",
171
- key: "emailVerified",
172
- render: (verified, all) => {
173
- if (all.empty) {
174
- return <div className="daf-default-cell" />;
175
- }
148
+ {
149
+ title: t("Email Verified"),
150
+ dataIndex: "emailVerified",
151
+ key: "emailVerified",
152
+ render: (verified, all) => {
153
+ if (all.empty) {
154
+ return <div className="daf-default-cell" />;
155
+ }
176
156
 
177
- return verified ? (
178
- <Tag color="green">{t("Yes")}</Tag>
179
- ) : (
180
- <Tag color="red">{t("No")}</Tag>
181
- );
182
- },
183
- ellipsis: false,
184
- active: false,
185
- pending: true,
186
- suspended: false,
157
+ const isVerified = all.users?.[0]?.emailVerified ?? verified ?? all.emailVerfied;
158
+
159
+ return isVerified ? (
160
+ <Tag color="green">{t("Yes")}</Tag>
161
+ ) : (
162
+ <Tag color="red">{t("No")}</Tag>
163
+ );
187
164
  },
165
+ ellipsis: false,
166
+ active: false,
167
+ pending: true,
168
+ suspended: false,
169
+ },
188
170
  {
189
171
  title: t("Date"),
190
172
  dataIndex: "createdAt",
@@ -154,21 +154,14 @@ function AdminView({
154
154
 
155
155
  try {
156
156
  const { data} = await updateAccount({ id: editData.id, data: newData });
157
- console.log({data})
158
157
 
159
- console.log('Checking for pending users...', {
160
- hasPendingUsers: pendingUsers.length > 0,
161
- hasInviteFunction: !!inviteCompanyAccount,
162
- pendingUsers: pendingUsers
163
- });
158
+
164
159
 
165
160
  if (pendingUsers.length > 0 && inviteCompanyAccount) {
166
161
  console.log('Inviting pending users:', pendingUsers.length);
167
162
  for (const user of pendingUsers) {
168
163
  try {
169
164
  const { pendingCompanyId, status, ...userDataToInvite } = user;
170
- console.log('Sending invitation for:', user.email, userDataToInvite);
171
- // Use the standalone invite function, don't mix it with updateAccount
172
165
  // await inviteCompanyAccount({
173
166
  // companyId: editData.id,
174
167
  // data: {
@@ -1,7 +1,7 @@
1
1
  import { useEffect, useState } from "react";
2
2
  import SourceService from "../services/SourceService.js";
3
3
 
4
- export default function useSource({ user = {}, t = () => {}, getData = () => {}, id }) {
4
+ export default function useSource({ user = {}, t = () => {}, getData = () => {}, id, stop }) {
5
5
  const [loading, setLoading] = useState(true);
6
6
  const [partners, setPartners] = useState([]);
7
7
  const [selectedPartners, setSelectedPartners] = useState({ loading: true });
@@ -59,8 +59,10 @@ export default function useSource({ user = {}, t = () => {}, getData = () => {},
59
59
  }
60
60
  }
61
61
 
62
- fetchPartners();
63
- }, [user.language, id]);
62
+ if(!stop) {
63
+ fetchPartners();
64
+ }
65
+ }, [user.language, id, stop]);
64
66
 
65
67
  function handleSelectedPartnersChange(selected) {
66
68
  setSelectedPartners((prev) => ({
@@ -82,7 +84,6 @@ export default function useSource({ user = {}, t = () => {}, getData = () => {},
82
84
 
83
85
  export const useSources = ({type, id, user, t = () => {}, stop}) => {
84
86
  function getData(params) {
85
- if(stop) return Promise.resolve({ data: [] });
86
87
  if(id !== undefined && id !== null) {
87
88
  return SourceService.getSources({type, id});
88
89
  } else {
@@ -95,6 +96,7 @@ export const useSources = ({type, id, user, t = () => {}, stop}) => {
95
96
  t,
96
97
  getData: getData,
97
98
  id,
99
+ stop,
98
100
  });
99
101
 
100
102
  const informationSources = partners?.length > 0 ? partners?.length - 1 : 0;
@@ -13,37 +13,27 @@ export const useWidgetFetch = ({config, getData = DashboardService.getWidget, on
13
13
  const { stop, defaultData, ...rest} = config;
14
14
  const [ data, setData ] = useState(defaultData || {});
15
15
  const [ loading, setLoading ] = useState(false);
16
- const [ initFetchDone, setInitFetchDone ] = useState(false);
17
- const isMounted = useRef(true);
18
16
 
19
17
  const fetchData = async () => {
20
18
  setLoading(true);
21
19
  try {
22
20
  const { data } = await getData(rest);
23
- if (!isMounted.current) return;
24
- setData(data || defaultData);
21
+ setData(data);
25
22
  if (isErrorResponse(data)) {
26
23
  const errorMessage = getErrorMessage(data);
27
24
  message.error(errorMessage);
28
25
  return;
29
26
  }
30
27
  onFetch();
31
- setInitFetchDone(true);
32
28
  } catch (err) {
33
29
  console.log(err);
34
- }
35
- if (isMounted.current) {
30
+ }finally {
36
31
  setLoading(false);
37
32
  }
38
33
  };
39
- useEffect(() => {
40
- isMounted.current = true;
41
- return () => {
42
- isMounted.current = false;
43
- };
44
- }, []);
45
34
  useEffect(() => {
46
35
  if(!stop) {
36
+ console.log('fetching data');
47
37
  fetchData();
48
38
  }
49
39
  }, [JSON.stringify(config), stop]);
@@ -51,6 +41,5 @@ export const useWidgetFetch = ({config, getData = DashboardService.getWidget, on
51
41
  data,
52
42
  loading,
53
43
  setData,
54
- initFetchDone
55
44
  }
56
45
  }
@@ -204,3 +204,6 @@ export function useTimelineBase({ language, selectedRange }) {
204
204
  }
205
205
 
206
206
  export default useTimelineBase;
207
+
208
+
209
+
@@ -1,16 +1,75 @@
1
- import { useMemo, useState } from "react";
1
+ import { useMemo, useState, useCallback } from "react";
2
2
  import useTimelineBase from "./config.js";
3
-
3
+ import DashboardService from "../../../../../../../services/DashboardService.js";
4
4
  export default function useIncidentsTimeline({
5
5
  t,
6
6
  language,
7
7
  severityOptions = [],
8
8
  selectedRange = "12",
9
+ selectedPartners = {},
10
+ user,
9
11
  }) {
10
12
  const [filters, setFilters] = useState({ severity: "all" });
11
-
12
13
  const { baseMonths, baseWeeks, mergeWithData } = useTimelineBase({ language, selectedRange });
13
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
+
72
+
14
73
  const filtersConfig = useMemo(
15
74
  () => ({
16
75
  language,
@@ -43,6 +102,12 @@ export default function useIncidentsTimeline({
43
102
  setFilters,
44
103
  baseMonths,
45
104
  baseWeeks,
46
- mergeWithData
105
+ mergeWithData,
106
+ defaultFetchConfig,
107
+ getSourceParam,
108
+ getIncidentsTimelineData,
109
+ severityColors,
110
+ renderSeverity,
111
+ categories,
47
112
  };
48
113
  }
@@ -1,27 +1,26 @@
1
- import { useMemo, useCallback } from "react";
1
+ import { useMemo } 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";
7
6
  import { renderDateFormatted } from "../../../../../../../../helpers/Forms.js";
8
7
  import StackChart from "../../../../../../../core/components/Charts/StackChart/index.jsx";
9
-
10
8
  export default function IncidentsTimeline({
11
9
  selectedRange,
12
- selectedPartners = {},
13
10
  t,
14
11
  language,
15
12
  goTo,
16
- user,
17
13
  options,
18
14
  }) {
19
15
  const {
20
- filters,
21
16
  filtersConfig,
17
+ defaultFetchConfig,
18
+ getSourceParam,
19
+ getIncidentsTimelineData,
22
20
  mergeWithData,
23
- baseMonths,
24
- baseWeeks,
21
+ severityColors,
22
+ renderSeverity,
23
+ categories,
25
24
  } = useIncidentsTimeline({
26
25
  t,
27
26
  language,
@@ -29,96 +28,13 @@ export default function IncidentsTimeline({
29
28
  selectedRange,
30
29
  });
31
30
 
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
31
  const { data, loading } = useWidgetFetch({
73
32
  config: defaultFetchConfig,
74
33
  getData: getIncidentsTimelineData,
75
34
  });
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
35
  const chartData = useMemo(() => mergeWithData(data), [data, mergeWithData]);
90
36
 
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})
96
37
 
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
- );
122
38
 
123
39
  return (
124
40
  <Widget
@@ -135,7 +51,28 @@ export default function IncidentsTimeline({
135
51
  seriesField="severity"
136
52
  colors={severityColors}
137
53
  doConstraints={false}
138
- renderTooltip={getTooltipContent}
54
+ renderTooltip={({ item }) => {
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
+ }}
139
76
  />
140
77
  </div>
141
78
  </Widget>