@visns-studio/visns-components 5.26.3 → 5.26.5
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/package.json
CHANGED
|
@@ -94,7 +94,7 @@
|
|
|
94
94
|
"react-dom": "^17.0.0 || ^18.0.0"
|
|
95
95
|
},
|
|
96
96
|
"name": "@visns-studio/visns-components",
|
|
97
|
-
"version": "5.26.
|
|
97
|
+
"version": "5.26.5",
|
|
98
98
|
"description": "Various packages to assist in the development of our Custom Applications.",
|
|
99
99
|
"main": "src/index.js",
|
|
100
100
|
"files": [
|
|
@@ -545,13 +545,34 @@ const showModal = (title, content) => {
|
|
|
545
545
|
};
|
|
546
546
|
|
|
547
547
|
|
|
548
|
+
// Duplicate widget ids (seen in saved user layouts) collide in the data map,
|
|
549
|
+
// double-fetch, and can crash the renderer — keep the first occurrence only.
|
|
550
|
+
const dedupeWidgets = (dashSetting) => {
|
|
551
|
+
if (!dashSetting?.widgets) return dashSetting;
|
|
552
|
+
const seen = new Set();
|
|
553
|
+
const widgets = dashSetting.widgets.filter((widget) => {
|
|
554
|
+
if (seen.has(widget.id)) {
|
|
555
|
+
console.warn(
|
|
556
|
+
`GenericDashboard: dropping duplicate widget id "${widget.id}"`
|
|
557
|
+
);
|
|
558
|
+
return false;
|
|
559
|
+
}
|
|
560
|
+
seen.add(widget.id);
|
|
561
|
+
return true;
|
|
562
|
+
});
|
|
563
|
+
return widgets.length === dashSetting.widgets.length
|
|
564
|
+
? dashSetting
|
|
565
|
+
: { ...dashSetting, widgets };
|
|
566
|
+
};
|
|
567
|
+
|
|
548
568
|
function GenericDashboard({ setting, userProfile, dynamicDashboard = false }) {
|
|
549
569
|
const swapy = useRef(null);
|
|
550
570
|
const container = useRef(null);
|
|
551
571
|
const navigate = useNavigate();
|
|
552
|
-
const
|
|
553
|
-
|
|
554
|
-
|
|
572
|
+
const [dashboardSetting, setDashboardSetting] = useState(() =>
|
|
573
|
+
dedupeWidgets(
|
|
574
|
+
dynamicDashboard ? userProfile.dashboard_setting || setting : setting
|
|
575
|
+
)
|
|
555
576
|
);
|
|
556
577
|
const [data, setData] = useState({});
|
|
557
578
|
const [dropdowns, setDropdowns] = useState({});
|
|
@@ -699,42 +720,14 @@ function GenericDashboard({ setting, userProfile, dynamicDashboard = false }) {
|
|
|
699
720
|
}
|
|
700
721
|
};
|
|
701
722
|
|
|
702
|
-
// Single
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
if (Object.keys(filters).length > 0 && initialLoadRef.current) {
|
|
706
|
-
// Fetch data once with initial filters
|
|
707
|
-
fetchData(filters);
|
|
708
|
-
// Mark initial load as complete
|
|
709
|
-
initialLoadRef.current = false;
|
|
710
|
-
}
|
|
711
|
-
}, [filters]);
|
|
712
|
-
|
|
713
|
-
// Handle filter changes after initial load
|
|
714
|
-
const isInitialFilterChangeRef = useRef(true);
|
|
715
|
-
|
|
723
|
+
// Single fetch trigger: filters are (re)built whenever dashboardSetting
|
|
724
|
+
// changes, so every load path funnels through this one effect — the old
|
|
725
|
+
// split effects fired twice per mount (every widget fetched twice).
|
|
716
726
|
useEffect(() => {
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
isInitialFilterChangeRef.current = false;
|
|
720
|
-
return;
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
// Only fetch data if filters have been initialized
|
|
724
|
-
if (!initialLoadRef.current && Object.keys(filters).length > 0) {
|
|
725
|
-
fetchData(filters);
|
|
726
|
-
}
|
|
727
|
+
if (Object.keys(filters).length === 0) return;
|
|
728
|
+
fetchData(filters);
|
|
727
729
|
}, [filters]);
|
|
728
730
|
|
|
729
|
-
// Handle dashboardSetting changes
|
|
730
|
-
useEffect(() => {
|
|
731
|
-
// Skip the initial render
|
|
732
|
-
if (!initialLoadRef.current) {
|
|
733
|
-
// Only fetch data if it's not the initial load
|
|
734
|
-
fetchData(filters);
|
|
735
|
-
}
|
|
736
|
-
}, [dashboardSetting]);
|
|
737
|
-
|
|
738
731
|
// Handle window resize events to update viewportWidth
|
|
739
732
|
useEffect(() => {
|
|
740
733
|
const handleResize = () => {
|
|
@@ -1122,11 +1115,10 @@ function GenericDashboard({ setting, userProfile, dynamicDashboard = false }) {
|
|
|
1122
1115
|
}`}
|
|
1123
1116
|
>
|
|
1124
1117
|
<span>
|
|
1125
|
-
{
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
: widgetData}
|
|
1118
|
+
{typeof widgetData === 'number' ||
|
|
1119
|
+
typeof widgetData === 'string'
|
|
1120
|
+
? widgetData
|
|
1121
|
+
: parse(` `)}
|
|
1130
1122
|
</span>
|
|
1131
1123
|
</div>
|
|
1132
1124
|
{widget.button && (
|