@bygd/nc-report-ui 0.1.29 → 0.1.30
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/app/esm/index.html +21 -0
- package/dist/app/esm/index.js +93988 -0
- package/dist/default/cjs/index.cjs +6447 -1
- package/dist/default/esm/index.js +125 -29
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import React__default, { useEffect, useMemo, useState, useRef,
|
|
2
|
+
import React__default, { useEffect, useMemo, useState, useRef, useContext, createContext } from 'react';
|
|
3
3
|
import Paper from '@material-ui/core/Paper';
|
|
4
4
|
import { makeStyles } from '@material-ui/core/styles';
|
|
5
5
|
import { CircularProgress } from '@material-ui/core';
|
|
@@ -43,6 +43,9 @@ import CheckIcon from '@mui/icons-material/Check';
|
|
|
43
43
|
import CloseIcon from '@mui/icons-material/Close';
|
|
44
44
|
import RestartAltIcon from '@mui/icons-material/RestartAlt';
|
|
45
45
|
import PlaylistAddIcon from '@mui/icons-material/PlaylistAdd';
|
|
46
|
+
import StorageIcon from '@mui/icons-material/Storage';
|
|
47
|
+
import TrendingUpIcon from '@mui/icons-material/TrendingUp';
|
|
48
|
+
import BoltIcon from '@mui/icons-material/Bolt';
|
|
46
49
|
import FilterAltIcon from '@mui/icons-material/FilterAlt';
|
|
47
50
|
import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined';
|
|
48
51
|
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
|
|
@@ -876,7 +879,8 @@ function SingleSelect({
|
|
|
876
879
|
const {
|
|
877
880
|
key,
|
|
878
881
|
value,
|
|
879
|
-
disabled
|
|
882
|
+
disabled,
|
|
883
|
+
icon
|
|
880
884
|
} = itm;
|
|
881
885
|
return /*#__PURE__*/React__default.createElement(MenuItem, {
|
|
882
886
|
key: key,
|
|
@@ -884,9 +888,18 @@ function SingleSelect({
|
|
|
884
888
|
disabled: disabled,
|
|
885
889
|
sx: {
|
|
886
890
|
fontFamily: "system-ui",
|
|
887
|
-
minHeight: "36px"
|
|
891
|
+
minHeight: "36px",
|
|
892
|
+
display: "flex",
|
|
893
|
+
alignItems: "center",
|
|
894
|
+
gap: "6px"
|
|
895
|
+
}
|
|
896
|
+
}, icon && /*#__PURE__*/React__default.createElement(Box, {
|
|
897
|
+
component: "span",
|
|
898
|
+
sx: {
|
|
899
|
+
display: "inline-flex",
|
|
900
|
+
alignItems: "center"
|
|
888
901
|
}
|
|
889
|
-
}, formatLabel(value));
|
|
902
|
+
}, icon), formatLabel(value));
|
|
890
903
|
}))));
|
|
891
904
|
}
|
|
892
905
|
|
|
@@ -2888,6 +2901,51 @@ const Dimensions = ({
|
|
|
2888
2901
|
})))))));
|
|
2889
2902
|
};
|
|
2890
2903
|
|
|
2904
|
+
const MetricSourceIcon = ({
|
|
2905
|
+
source
|
|
2906
|
+
}) => {
|
|
2907
|
+
const iconSx = {
|
|
2908
|
+
fontSize: '15px'
|
|
2909
|
+
};
|
|
2910
|
+
if (source === 'kpi') {
|
|
2911
|
+
return /*#__PURE__*/React__default.createElement(Tooltip, {
|
|
2912
|
+
title: "KPI Metric",
|
|
2913
|
+
arrow: true,
|
|
2914
|
+
placement: "top"
|
|
2915
|
+
}, /*#__PURE__*/React__default.createElement(TrendingUpIcon, {
|
|
2916
|
+
sx: {
|
|
2917
|
+
...iconSx,
|
|
2918
|
+
color: 'rgb(70, 134, 128)'
|
|
2919
|
+
}
|
|
2920
|
+
}));
|
|
2921
|
+
}
|
|
2922
|
+
if (source === 'dynamic') {
|
|
2923
|
+
return /*#__PURE__*/React__default.createElement(Tooltip, {
|
|
2924
|
+
title: "Dynamic Metric",
|
|
2925
|
+
arrow: true,
|
|
2926
|
+
placement: "top"
|
|
2927
|
+
}, /*#__PURE__*/React__default.createElement(BoltIcon, {
|
|
2928
|
+
sx: {
|
|
2929
|
+
...iconSx,
|
|
2930
|
+
color: '#e65100'
|
|
2931
|
+
}
|
|
2932
|
+
}));
|
|
2933
|
+
}
|
|
2934
|
+
if (source === 'provider') {
|
|
2935
|
+
return /*#__PURE__*/React__default.createElement(Tooltip, {
|
|
2936
|
+
title: "Provider Metric",
|
|
2937
|
+
arrow: true,
|
|
2938
|
+
placement: "top"
|
|
2939
|
+
}, /*#__PURE__*/React__default.createElement(StorageIcon, {
|
|
2940
|
+
sx: {
|
|
2941
|
+
...iconSx,
|
|
2942
|
+
color: '#546e7a'
|
|
2943
|
+
}
|
|
2944
|
+
}));
|
|
2945
|
+
}
|
|
2946
|
+
return null;
|
|
2947
|
+
};
|
|
2948
|
+
|
|
2891
2949
|
// Sortable Chip Component
|
|
2892
2950
|
const SortableChip = ({
|
|
2893
2951
|
id,
|
|
@@ -2902,7 +2960,8 @@ const SortableChip = ({
|
|
|
2902
2960
|
defaultTitle,
|
|
2903
2961
|
customTitle,
|
|
2904
2962
|
onUpdateTitle,
|
|
2905
|
-
onResetTitle
|
|
2963
|
+
onResetTitle,
|
|
2964
|
+
source
|
|
2906
2965
|
}) => {
|
|
2907
2966
|
const [isEditing, setIsEditing] = useState(false);
|
|
2908
2967
|
const [editValue, setEditValue] = useState('');
|
|
@@ -3015,7 +3074,15 @@ const SortableChip = ({
|
|
|
3015
3074
|
cursor: "grab",
|
|
3016
3075
|
color: "rgba(110, 110, 110, 0.62)"
|
|
3017
3076
|
}
|
|
3018
|
-
})), !isEditing ? /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement(Box$1, {
|
|
3077
|
+
})), !isEditing ? /*#__PURE__*/React__default.createElement(React__default.Fragment, null, source && /*#__PURE__*/React__default.createElement(Box$1, {
|
|
3078
|
+
sx: {
|
|
3079
|
+
display: 'flex',
|
|
3080
|
+
alignItems: 'center',
|
|
3081
|
+
flexShrink: 0
|
|
3082
|
+
}
|
|
3083
|
+
}, /*#__PURE__*/React__default.createElement(MetricSourceIcon, {
|
|
3084
|
+
source: source
|
|
3085
|
+
})), /*#__PURE__*/React__default.createElement(Box$1, {
|
|
3019
3086
|
sx: {
|
|
3020
3087
|
minWidth: 0
|
|
3021
3088
|
}
|
|
@@ -3247,7 +3314,10 @@ const Metrics = ({
|
|
|
3247
3314
|
value: metric.title || metric.name,
|
|
3248
3315
|
metricName: metric.name,
|
|
3249
3316
|
metric: metric,
|
|
3250
|
-
disabled: isAlreadySelected
|
|
3317
|
+
disabled: isAlreadySelected,
|
|
3318
|
+
icon: metric.source ? /*#__PURE__*/React__default.createElement(MetricSourceIcon, {
|
|
3319
|
+
source: metric.source
|
|
3320
|
+
}) : undefined
|
|
3251
3321
|
};
|
|
3252
3322
|
});
|
|
3253
3323
|
return items;
|
|
@@ -3556,7 +3626,8 @@ const Metrics = ({
|
|
|
3556
3626
|
defaultTitle: metric.metricTitle,
|
|
3557
3627
|
customTitle: titleOverrides[metric.fullPath],
|
|
3558
3628
|
onUpdateTitle: onUpdateTitle,
|
|
3559
|
-
onResetTitle: onResetTitle
|
|
3629
|
+
onResetTitle: onResetTitle,
|
|
3630
|
+
source: metric.metric?.source
|
|
3560
3631
|
})))))));
|
|
3561
3632
|
};
|
|
3562
3633
|
|
|
@@ -4838,31 +4909,39 @@ const ReportDataGrid = ({
|
|
|
4838
4909
|
});
|
|
4839
4910
|
|
|
4840
4911
|
// Add metric columns
|
|
4841
|
-
//
|
|
4842
|
-
//
|
|
4843
|
-
// -
|
|
4912
|
+
// The API returns metric keys in two different forms depending on the path depth:
|
|
4913
|
+
//
|
|
4914
|
+
// • 2-part path "mc.record_count" → API key: "record_count"
|
|
4915
|
+
// • 2-part path "mc_fa.total_amount" (nested) → API key: "fa_total_amount"
|
|
4916
|
+
// • 3+-part path "mc.dkpi.activeAgreementsCount"→ API key: "mc.dkpi.activeAgreementsCount" (dots)
|
|
4917
|
+
//
|
|
4918
|
+
// For 3+-part paths the API key contains dots. MUI DataGrid interprets dots
|
|
4919
|
+
// in field names as nested-object accessors, so the rows useMemo normalises
|
|
4920
|
+
// those keys (dots → underscores). The column field must match that normalised key.
|
|
4844
4921
|
metrics.forEach(metric => {
|
|
4845
4922
|
const metricDef = metric.metric;
|
|
4846
4923
|
let fieldName;
|
|
4847
4924
|
let headerName;
|
|
4848
|
-
|
|
4849
|
-
|
|
4850
|
-
|
|
4851
|
-
//
|
|
4852
|
-
// Example:
|
|
4925
|
+
const dotCount = (metric.fullPath.match(/\./g) || []).length;
|
|
4926
|
+
if (dotCount >= 2) {
|
|
4927
|
+
// 3+-part namespaced path: API returns the full dotted path as the key.
|
|
4928
|
+
// Normalise dots to underscores to match the row key normalisation below.
|
|
4929
|
+
// Example: "mc.dkpi.activeAgreementsCount" -> "mc_dkpi_activeAgreementsCount"
|
|
4930
|
+
fieldName = metric.fullPath.replace(/\./g, '_');
|
|
4931
|
+
} else if (metric.relations && metric.relations.length > 0) {
|
|
4932
|
+
// 2-part path from a nested provider: API drops the base provider alias.
|
|
4933
|
+
// Example: "mc_fa.total_amount" -> "fa_total_amount"
|
|
4853
4934
|
const parts = metric.fullPath.split('.');
|
|
4854
|
-
const pathWithoutField = parts[0]; // e.g., "
|
|
4935
|
+
const pathWithoutField = parts[0]; // e.g., "mc_fa"
|
|
4855
4936
|
const field = parts[1]; // e.g., "total_amount"
|
|
4856
4937
|
|
|
4857
|
-
// Remove the base provider alias (first part before first underscore)
|
|
4858
4938
|
const pathParts = pathWithoutField.split('_');
|
|
4859
|
-
pathParts.shift(); //
|
|
4860
|
-
const pathWithoutBase = pathParts.join('_');
|
|
4861
|
-
|
|
4939
|
+
pathParts.shift(); // remove base provider alias
|
|
4940
|
+
const pathWithoutBase = pathParts.join('_');
|
|
4862
4941
|
fieldName = pathWithoutBase ? `${pathWithoutBase}_${field}` : field;
|
|
4863
4942
|
} else {
|
|
4864
|
-
//
|
|
4865
|
-
// Example:
|
|
4943
|
+
// 2-part path from the base provider: API returns just the metric name.
|
|
4944
|
+
// Example: "mc.record_count" -> "record_count"
|
|
4866
4945
|
fieldName = metric.metricName;
|
|
4867
4946
|
}
|
|
4868
4947
|
|
|
@@ -4874,6 +4953,15 @@ const ReportDataGrid = ({
|
|
|
4874
4953
|
flex: 1,
|
|
4875
4954
|
minWidth: 150,
|
|
4876
4955
|
type: metricDef?.type === 'integer' || metricDef?.type === 'currency' ? 'number' : 'string',
|
|
4956
|
+
renderHeader: () => /*#__PURE__*/React__default.createElement(Box$1, {
|
|
4957
|
+
sx: {
|
|
4958
|
+
display: 'flex',
|
|
4959
|
+
alignItems: 'center',
|
|
4960
|
+
gap: 0.5
|
|
4961
|
+
}
|
|
4962
|
+
}, /*#__PURE__*/React__default.createElement(MetricSourceIcon, {
|
|
4963
|
+
source: metricDef?.source
|
|
4964
|
+
}), /*#__PURE__*/React__default.createElement("span", null, headerName)),
|
|
4877
4965
|
valueFormatter: value => {
|
|
4878
4966
|
if (value == null) return '';
|
|
4879
4967
|
|
|
@@ -4892,14 +4980,22 @@ const ReportDataGrid = ({
|
|
|
4892
4980
|
return cols;
|
|
4893
4981
|
}, [dimensions, metrics, titleOverrides]);
|
|
4894
4982
|
|
|
4895
|
-
// Transform report data to rows with unique IDs
|
|
4983
|
+
// Transform report data to rows with unique IDs.
|
|
4984
|
+
// Keys are normalised by replacing dots with underscores so that MUI DataGrid
|
|
4985
|
+
// does not misinterpret dotted keys (e.g. "mc.dkpi.exposure") as nested
|
|
4986
|
+
// object paths. Dimension keys returned by the API are already underscore-
|
|
4987
|
+
// based, so normalisation is a no-op for them.
|
|
4896
4988
|
const rows = React__default.useMemo(() => {
|
|
4897
4989
|
if (!reportData || !Array.isArray(reportData)) return [];
|
|
4898
|
-
return reportData.map((row, index) =>
|
|
4899
|
-
|
|
4900
|
-
|
|
4901
|
-
|
|
4902
|
-
|
|
4990
|
+
return reportData.map((row, index) => {
|
|
4991
|
+
const normalizedRow = {
|
|
4992
|
+
id: index
|
|
4993
|
+
};
|
|
4994
|
+
Object.entries(row).forEach(([key, value]) => {
|
|
4995
|
+
normalizedRow[key.replace(/\./g, '_')] = value;
|
|
4996
|
+
});
|
|
4997
|
+
return normalizedRow;
|
|
4998
|
+
});
|
|
4903
4999
|
}, [reportData]);
|
|
4904
5000
|
|
|
4905
5001
|
// Handle pagination change
|