@optifye/dashboard-core 6.11.8 → 6.11.9
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/index.css +6 -0
- package/dist/index.js +185 -48
- package/dist/index.mjs +185 -48
- package/package.json +1 -1
package/dist/index.css
CHANGED
|
@@ -5545,6 +5545,9 @@ input[type=range]:active::-moz-range-thumb {
|
|
|
5545
5545
|
--tw-bg-opacity: 1;
|
|
5546
5546
|
background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1));
|
|
5547
5547
|
}
|
|
5548
|
+
.hover\:bg-transparent:hover {
|
|
5549
|
+
background-color: transparent;
|
|
5550
|
+
}
|
|
5548
5551
|
.hover\:bg-white:hover {
|
|
5549
5552
|
--tw-bg-opacity: 1;
|
|
5550
5553
|
background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
|
|
@@ -5981,6 +5984,9 @@ input[type=range]:active::-moz-range-thumb {
|
|
|
5981
5984
|
--tw-bg-opacity: 1;
|
|
5982
5985
|
background-color: rgb(96 165 250 / var(--tw-bg-opacity, 1));
|
|
5983
5986
|
}
|
|
5987
|
+
.disabled\:opacity-40:disabled {
|
|
5988
|
+
opacity: 0.4;
|
|
5989
|
+
}
|
|
5984
5990
|
.disabled\:opacity-50:disabled {
|
|
5985
5991
|
opacity: 0.5;
|
|
5986
5992
|
}
|
package/dist/index.js
CHANGED
|
@@ -74667,33 +74667,51 @@ var OverviewImprovementsSkeleton = () => /* @__PURE__ */ jsxRuntime.jsx("div", {
|
|
|
74667
74667
|
var OperationsOverviewHeader = React141__namespace.default.memo(({
|
|
74668
74668
|
dateRange,
|
|
74669
74669
|
trendMode,
|
|
74670
|
+
lineOptions,
|
|
74671
|
+
selectedLineIds,
|
|
74670
74672
|
appTimezone,
|
|
74671
74673
|
mobileMenuContext,
|
|
74672
74674
|
onDateRangeChange,
|
|
74673
|
-
onTrendModeChange
|
|
74675
|
+
onTrendModeChange,
|
|
74676
|
+
onSelectedLineIdsChange
|
|
74674
74677
|
}) => {
|
|
74675
74678
|
bumpRenderCounter();
|
|
74676
74679
|
const [isFilterOpen, setIsFilterOpen] = React141__namespace.default.useState(false);
|
|
74680
|
+
const [isLinesDropdownOpen, setIsLinesDropdownOpen] = React141__namespace.default.useState(false);
|
|
74677
74681
|
const filterRef = React141__namespace.default.useRef(null);
|
|
74678
74682
|
const filterButtonRef = React141__namespace.default.useRef(null);
|
|
74679
74683
|
const mobileFilterButtonRef = React141__namespace.default.useRef(null);
|
|
74680
|
-
const
|
|
74681
|
-
() => getCurrentWeekToDateRange(appTimezone),
|
|
74682
|
-
[appTimezone]
|
|
74683
|
-
);
|
|
74684
|
-
const isCurrentWeekToDateRange = dateRange.startKey === currentWeekRange.startKey && dateRange.endKey === currentWeekRange.endKey;
|
|
74684
|
+
const linesDropdownRef = React141__namespace.default.useRef(null);
|
|
74685
74685
|
const mobileSubtitle = React141__namespace.default.useMemo(() => {
|
|
74686
|
-
if (
|
|
74687
|
-
return
|
|
74686
|
+
if (dateRange.startKey === dateRange.endKey) {
|
|
74687
|
+
return dateFns.format(parseDateKeyToDate(dateRange.startKey), "do MMM, yyyy");
|
|
74688
74688
|
}
|
|
74689
74689
|
return `${dateFns.format(parseDateKeyToDate(dateRange.startKey), "do MMM")} - ${dateFns.format(parseDateKeyToDate(dateRange.endKey), "do MMM, yyyy")}`;
|
|
74690
|
-
}, [dateRange.endKey, dateRange.startKey
|
|
74690
|
+
}, [dateRange.endKey, dateRange.startKey]);
|
|
74691
74691
|
const desktopSubtitle = React141__namespace.default.useMemo(() => {
|
|
74692
|
-
if (
|
|
74693
|
-
return
|
|
74692
|
+
if (dateRange.startKey === dateRange.endKey) {
|
|
74693
|
+
return dateFns.format(parseDateKeyToDate(dateRange.startKey), "do MMMM, yyyy");
|
|
74694
74694
|
}
|
|
74695
74695
|
return `${dateFns.format(parseDateKeyToDate(dateRange.startKey), "do MMMM, yyyy")} - ${dateFns.format(parseDateKeyToDate(dateRange.endKey), "do MMMM, yyyy")}`;
|
|
74696
|
-
}, [dateRange.endKey, dateRange.startKey
|
|
74696
|
+
}, [dateRange.endKey, dateRange.startKey]);
|
|
74697
|
+
const availableLineIds = React141__namespace.default.useMemo(
|
|
74698
|
+
() => lineOptions.map((line) => line.id),
|
|
74699
|
+
[lineOptions]
|
|
74700
|
+
);
|
|
74701
|
+
const selectedLineIdSet = React141__namespace.default.useMemo(
|
|
74702
|
+
() => new Set(selectedLineIds),
|
|
74703
|
+
[selectedLineIds]
|
|
74704
|
+
);
|
|
74705
|
+
const isAllLinesSelected = React141__namespace.default.useMemo(() => {
|
|
74706
|
+
if (availableLineIds.length === 0) return true;
|
|
74707
|
+
return availableLineIds.every((lineId) => selectedLineIdSet.has(lineId));
|
|
74708
|
+
}, [availableLineIds, selectedLineIdSet]);
|
|
74709
|
+
const activeFilterCount = React141__namespace.default.useMemo(() => {
|
|
74710
|
+
let count = 0;
|
|
74711
|
+
if (trendMode !== "all") count += 1;
|
|
74712
|
+
if (!isAllLinesSelected) count += 1;
|
|
74713
|
+
return count;
|
|
74714
|
+
}, [isAllLinesSelected, trendMode]);
|
|
74697
74715
|
const handleFilterToggle = React141__namespace.default.useCallback(() => {
|
|
74698
74716
|
trackCoreEvent("Operations Overview Filter Toggled", {
|
|
74699
74717
|
action: !isFilterOpen ? "open" : "close"
|
|
@@ -74707,10 +74725,43 @@ var OperationsOverviewHeader = React141__namespace.default.memo(({
|
|
|
74707
74725
|
});
|
|
74708
74726
|
onTrendModeChange(nextMode);
|
|
74709
74727
|
}, [onTrendModeChange]);
|
|
74728
|
+
const handleAllLinesToggle = React141__namespace.default.useCallback(() => {
|
|
74729
|
+
trackCoreEvent("Operations Overview Line Filter Changed", {
|
|
74730
|
+
selected_line_ids: availableLineIds,
|
|
74731
|
+
selected_line_count: availableLineIds.length,
|
|
74732
|
+
mode: "all"
|
|
74733
|
+
});
|
|
74734
|
+
onSelectedLineIdsChange(availableLineIds);
|
|
74735
|
+
}, [availableLineIds, onSelectedLineIdsChange]);
|
|
74736
|
+
const handleLineToggle = React141__namespace.default.useCallback((lineId) => {
|
|
74737
|
+
const current = new Set(selectedLineIds);
|
|
74738
|
+
if (current.has(lineId)) {
|
|
74739
|
+
if (current.size <= 1) return;
|
|
74740
|
+
current.delete(lineId);
|
|
74741
|
+
} else {
|
|
74742
|
+
current.add(lineId);
|
|
74743
|
+
}
|
|
74744
|
+
const next = availableLineIds.filter((id3) => current.has(id3));
|
|
74745
|
+
trackCoreEvent("Operations Overview Line Filter Changed", {
|
|
74746
|
+
selected_line_ids: next,
|
|
74747
|
+
selected_line_count: next.length,
|
|
74748
|
+
mode: "custom"
|
|
74749
|
+
});
|
|
74750
|
+
onSelectedLineIdsChange(next);
|
|
74751
|
+
}, [availableLineIds, onSelectedLineIdsChange, selectedLineIds]);
|
|
74752
|
+
const handleClearAllFilters = React141__namespace.default.useCallback(() => {
|
|
74753
|
+
onTrendModeChange("all");
|
|
74754
|
+
onSelectedLineIdsChange(availableLineIds);
|
|
74755
|
+
setIsFilterOpen(false);
|
|
74756
|
+
}, [availableLineIds, onSelectedLineIdsChange, onTrendModeChange]);
|
|
74710
74757
|
React141__namespace.default.useEffect(() => {
|
|
74711
74758
|
const handleClickOutside = (event) => {
|
|
74712
|
-
|
|
74759
|
+
const target = event.target;
|
|
74760
|
+
if (filterRef.current && !filterRef.current.contains(target) && filterButtonRef.current && !filterButtonRef.current.contains(target) && mobileFilterButtonRef.current && !mobileFilterButtonRef.current.contains(target)) {
|
|
74713
74761
|
setIsFilterOpen(false);
|
|
74762
|
+
setIsLinesDropdownOpen(false);
|
|
74763
|
+
} else if (linesDropdownRef.current && !linesDropdownRef.current.contains(target)) {
|
|
74764
|
+
setIsLinesDropdownOpen(false);
|
|
74714
74765
|
}
|
|
74715
74766
|
};
|
|
74716
74767
|
document.addEventListener("mousedown", handleClickOutside);
|
|
@@ -74749,11 +74800,11 @@ var OperationsOverviewHeader = React141__namespace.default.memo(({
|
|
|
74749
74800
|
{
|
|
74750
74801
|
ref: mobileFilterButtonRef,
|
|
74751
74802
|
onClick: handleFilterToggle,
|
|
74752
|
-
className: `p-2 rounded-full transition-colors relative ${isFilterOpen ||
|
|
74803
|
+
className: `p-2 rounded-full transition-colors relative ${isFilterOpen || activeFilterCount > 0 ? "bg-blue-50" : "active:bg-gray-100"}`,
|
|
74753
74804
|
"aria-label": "Open filters",
|
|
74754
74805
|
children: [
|
|
74755
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Filter, { className: `w-5 h-5 ${
|
|
74756
|
-
|
|
74806
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Filter, { className: `w-5 h-5 ${activeFilterCount > 0 ? "text-blue-600" : "text-gray-700"}` }),
|
|
74807
|
+
activeFilterCount > 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute -top-1 -right-1 flex items-center justify-center w-4 h-4 bg-blue-600 text-white text-[10px] rounded-full font-bold", children: activeFilterCount }) : null
|
|
74757
74808
|
]
|
|
74758
74809
|
}
|
|
74759
74810
|
)
|
|
@@ -74781,10 +74832,10 @@ var OperationsOverviewHeader = React141__namespace.default.memo(({
|
|
|
74781
74832
|
{
|
|
74782
74833
|
ref: filterButtonRef,
|
|
74783
74834
|
onClick: handleFilterToggle,
|
|
74784
|
-
className: `flex items-center gap-2 px-3 py-1.5 rounded-lg border text-sm font-medium transition-all shadow-sm ${isFilterOpen ||
|
|
74835
|
+
className: `flex items-center gap-2 px-3 py-1.5 rounded-lg border text-sm font-medium transition-all shadow-sm ${isFilterOpen || activeFilterCount > 0 ? "border-blue-500 bg-blue-50 text-blue-700 ring-1 ring-blue-500" : "border-slate-200 bg-white text-slate-700 hover:bg-slate-50"}`,
|
|
74785
74836
|
"aria-label": "Open filters",
|
|
74786
74837
|
children: [
|
|
74787
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Filter, { className: `w-[18px] h-[18px] ${
|
|
74838
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Filter, { className: `w-[18px] h-[18px] ${activeFilterCount > 0 ? "text-blue-600" : "text-slate-500"}` }),
|
|
74788
74839
|
"Filters",
|
|
74789
74840
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: `w-4 h-4 ml-0.5 transition-transform duration-200 ${isFilterOpen ? "rotate-180" : ""}` })
|
|
74790
74841
|
]
|
|
@@ -74795,40 +74846,94 @@ var OperationsOverviewHeader = React141__namespace.default.memo(({
|
|
|
74795
74846
|
isFilterOpen ? /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: filterRef, className: "absolute right-3 sm:right-4 md:right-5 lg:right-6 top-full mt-2 w-72 bg-white rounded-xl shadow-xl border border-gray-100 p-4 z-50", children: [
|
|
74796
74847
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-3", children: [
|
|
74797
74848
|
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-semibold text-gray-900", children: "Filter View" }),
|
|
74798
|
-
|
|
74849
|
+
activeFilterCount > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
74799
74850
|
"button",
|
|
74800
74851
|
{
|
|
74801
|
-
onClick:
|
|
74802
|
-
onTrendModeChange("all");
|
|
74803
|
-
setIsFilterOpen(false);
|
|
74804
|
-
},
|
|
74852
|
+
onClick: handleClearAllFilters,
|
|
74805
74853
|
className: "text-xs text-red-600 hover:text-red-700 font-medium",
|
|
74806
74854
|
children: "Clear all"
|
|
74807
74855
|
}
|
|
74808
74856
|
) : null
|
|
74809
74857
|
] }),
|
|
74810
|
-
/* @__PURE__ */ jsxRuntime.
|
|
74811
|
-
/* @__PURE__ */ jsxRuntime.
|
|
74812
|
-
|
|
74813
|
-
"
|
|
74814
|
-
|
|
74815
|
-
|
|
74816
|
-
|
|
74817
|
-
|
|
74818
|
-
|
|
74819
|
-
|
|
74820
|
-
|
|
74821
|
-
|
|
74822
|
-
|
|
74823
|
-
|
|
74824
|
-
|
|
74825
|
-
|
|
74826
|
-
|
|
74827
|
-
|
|
74828
|
-
|
|
74829
|
-
|
|
74830
|
-
|
|
74831
|
-
|
|
74858
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
74859
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
|
|
74860
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-xs font-medium text-gray-500 uppercase tracking-wide ml-1", children: "Shift" }),
|
|
74861
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
74862
|
+
"select",
|
|
74863
|
+
{
|
|
74864
|
+
value: trendMode,
|
|
74865
|
+
onChange: handleTrendModeChange,
|
|
74866
|
+
className: "w-full appearance-none pl-3 pr-8 py-2 text-sm bg-gray-50 border border-gray-200 hover:border-gray-300 rounded-lg text-gray-900 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:bg-white transition-all cursor-pointer",
|
|
74867
|
+
style: {
|
|
74868
|
+
backgroundImage: `url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e")`,
|
|
74869
|
+
backgroundPosition: "right 0.75rem center",
|
|
74870
|
+
backgroundRepeat: "no-repeat",
|
|
74871
|
+
backgroundSize: "1.2em 1.2em"
|
|
74872
|
+
},
|
|
74873
|
+
children: [
|
|
74874
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All Shifts" }),
|
|
74875
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "day", children: "Day Shift" }),
|
|
74876
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "night", children: "Night Shift" })
|
|
74877
|
+
]
|
|
74878
|
+
}
|
|
74879
|
+
) })
|
|
74880
|
+
] }),
|
|
74881
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", ref: linesDropdownRef, children: [
|
|
74882
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-xs font-medium text-gray-500 uppercase tracking-wide ml-1", children: "Lines" }),
|
|
74883
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
74884
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
74885
|
+
"button",
|
|
74886
|
+
{
|
|
74887
|
+
type: "button",
|
|
74888
|
+
onClick: () => setIsLinesDropdownOpen((prev) => !prev),
|
|
74889
|
+
className: "w-full flex items-center justify-between pl-3 pr-3 py-2 text-sm bg-gray-50 border border-gray-200 hover:border-gray-300 rounded-lg text-gray-900 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:bg-white transition-all cursor-pointer text-left",
|
|
74890
|
+
children: [
|
|
74891
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate pr-2", children: isAllLinesSelected ? "All Lines" : selectedLineIds.length === 1 ? lineOptions.find((l) => l.id === selectedLineIds[0])?.name || "1 Line Selected" : `${selectedLineIds.length} Lines Selected` }),
|
|
74892
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: `w-4 h-4 text-gray-500 flex-shrink-0 transition-transform ${isLinesDropdownOpen ? "rotate-180" : ""}` })
|
|
74893
|
+
]
|
|
74894
|
+
}
|
|
74895
|
+
),
|
|
74896
|
+
isLinesDropdownOpen ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute top-full left-0 right-0 mt-1 max-h-48 overflow-y-auto rounded-lg border border-gray-200 bg-white shadow-lg p-1.5 space-y-0.5 z-[60]", children: [
|
|
74897
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2.5 rounded-md px-2 py-1.5 text-sm text-gray-900 hover:bg-gray-50 cursor-pointer", children: [
|
|
74898
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
74899
|
+
"input",
|
|
74900
|
+
{
|
|
74901
|
+
type: "checkbox",
|
|
74902
|
+
className: "h-4 w-4 rounded border-slate-300 text-blue-600 focus:ring-blue-500",
|
|
74903
|
+
checked: isAllLinesSelected,
|
|
74904
|
+
onChange: handleAllLinesToggle
|
|
74905
|
+
}
|
|
74906
|
+
),
|
|
74907
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: "All Lines" })
|
|
74908
|
+
] }),
|
|
74909
|
+
lineOptions.map((line) => {
|
|
74910
|
+
const isChecked = selectedLineIdSet.has(line.id);
|
|
74911
|
+
const disableUncheck = isChecked && selectedLineIds.length <= 1;
|
|
74912
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
74913
|
+
"label",
|
|
74914
|
+
{
|
|
74915
|
+
className: `flex items-center gap-2.5 rounded-md px-2 py-1.5 text-sm cursor-pointer transition-colors ${disableUncheck ? "text-gray-400 hover:bg-transparent" : "text-gray-800 hover:bg-gray-50"}`,
|
|
74916
|
+
children: [
|
|
74917
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
74918
|
+
"input",
|
|
74919
|
+
{
|
|
74920
|
+
type: "checkbox",
|
|
74921
|
+
className: "h-4 w-4 rounded border-slate-300 text-blue-600 focus:ring-blue-500 disabled:opacity-40",
|
|
74922
|
+
checked: isChecked,
|
|
74923
|
+
disabled: disableUncheck,
|
|
74924
|
+
onChange: () => handleLineToggle(line.id)
|
|
74925
|
+
}
|
|
74926
|
+
),
|
|
74927
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: line.name })
|
|
74928
|
+
]
|
|
74929
|
+
},
|
|
74930
|
+
line.id
|
|
74931
|
+
);
|
|
74932
|
+
})
|
|
74933
|
+
] }) : null
|
|
74934
|
+
] })
|
|
74935
|
+
] })
|
|
74936
|
+
] })
|
|
74832
74937
|
] }) : null
|
|
74833
74938
|
] }) });
|
|
74834
74939
|
});
|
|
@@ -75727,6 +75832,7 @@ var PlantHeadView = () => {
|
|
|
75727
75832
|
const [dateRange, setDateRange] = React141__namespace.default.useState(() => getCurrentWeekToDateRange(appTimezone));
|
|
75728
75833
|
const [usesThisWeekComparison, setUsesThisWeekComparison] = React141__namespace.default.useState(true);
|
|
75729
75834
|
const [trendMode, setTrendMode] = React141__namespace.default.useState("all");
|
|
75835
|
+
const [selectedLineIds, setSelectedLineIds] = React141__namespace.default.useState([]);
|
|
75730
75836
|
React141__namespace.default.useEffect(() => {
|
|
75731
75837
|
trackCorePageView("Operations Overview", {
|
|
75732
75838
|
dashboard_surface: "operations_overview"
|
|
@@ -75745,9 +75851,27 @@ var PlantHeadView = () => {
|
|
|
75745
75851
|
() => normalizedLineIds.join(","),
|
|
75746
75852
|
[normalizedLineIds]
|
|
75747
75853
|
);
|
|
75854
|
+
const lineOptions = React141__namespace.default.useMemo(
|
|
75855
|
+
() => normalizedLineIds.map((lineId) => ({
|
|
75856
|
+
id: lineId,
|
|
75857
|
+
name: getLineDisplayName(entityConfig, lineId)
|
|
75858
|
+
})),
|
|
75859
|
+
[entityConfig, normalizedLineIds]
|
|
75860
|
+
);
|
|
75861
|
+
React141__namespace.default.useEffect(() => {
|
|
75862
|
+
setSelectedLineIds((previous) => {
|
|
75863
|
+
if (normalizedLineIds.length === 0) return [];
|
|
75864
|
+
const previousSet = new Set(previous);
|
|
75865
|
+
const next = normalizedLineIds.filter((lineId) => previousSet.has(lineId));
|
|
75866
|
+
if (next.length === 0) {
|
|
75867
|
+
return normalizedLineIds;
|
|
75868
|
+
}
|
|
75869
|
+
return next;
|
|
75870
|
+
});
|
|
75871
|
+
}, [lineIdsKey, normalizedLineIds]);
|
|
75748
75872
|
const scopedLineIds = React141__namespace.default.useMemo(
|
|
75749
|
-
() =>
|
|
75750
|
-
[
|
|
75873
|
+
() => selectedLineIds.length > 0 ? selectedLineIds : normalizedLineIds,
|
|
75874
|
+
[normalizedLineIds, selectedLineIds]
|
|
75751
75875
|
);
|
|
75752
75876
|
const initializedTimezoneRef = React141__namespace.default.useRef(appTimezone);
|
|
75753
75877
|
React141__namespace.default.useEffect(() => {
|
|
@@ -75775,6 +75899,16 @@ var PlantHeadView = () => {
|
|
|
75775
75899
|
const handleTrendModeChange = React141__namespace.default.useCallback((mode) => {
|
|
75776
75900
|
setTrendMode(mode);
|
|
75777
75901
|
}, []);
|
|
75902
|
+
const handleSelectedLineIdsChange = React141__namespace.default.useCallback((lineIds) => {
|
|
75903
|
+
if (normalizedLineIds.length === 0) {
|
|
75904
|
+
setSelectedLineIds([]);
|
|
75905
|
+
return;
|
|
75906
|
+
}
|
|
75907
|
+
const uniqueSelected = Array.from(new Set(lineIds));
|
|
75908
|
+
const selectedSet = new Set(uniqueSelected);
|
|
75909
|
+
const next = normalizedLineIds.filter((lineId) => selectedSet.has(lineId));
|
|
75910
|
+
setSelectedLineIds(next.length > 0 ? next : normalizedLineIds);
|
|
75911
|
+
}, [normalizedLineIds]);
|
|
75778
75912
|
const buildLineMonthlyHistoryUrl = React141__namespace.default.useCallback((lineId) => {
|
|
75779
75913
|
const rangeStartDate = parseDateKeyToDate(dateRange.startKey);
|
|
75780
75914
|
const params = new URLSearchParams();
|
|
@@ -75841,10 +75975,13 @@ var PlantHeadView = () => {
|
|
|
75841
75975
|
{
|
|
75842
75976
|
dateRange,
|
|
75843
75977
|
trendMode,
|
|
75978
|
+
lineOptions,
|
|
75979
|
+
selectedLineIds: scopedLineIds,
|
|
75844
75980
|
appTimezone,
|
|
75845
75981
|
mobileMenuContext,
|
|
75846
75982
|
onDateRangeChange: handleDateRangeChange,
|
|
75847
|
-
onTrendModeChange: handleTrendModeChange
|
|
75983
|
+
onTrendModeChange: handleTrendModeChange,
|
|
75984
|
+
onSelectedLineIdsChange: handleSelectedLineIdsChange
|
|
75848
75985
|
}
|
|
75849
75986
|
),
|
|
75850
75987
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4 sm:p-6 pb-6 max-w-[1800px] mx-auto w-full flex-1 min-h-0 overflow-y-auto flex flex-col gap-5", children: [
|
package/dist/index.mjs
CHANGED
|
@@ -74638,33 +74638,51 @@ var OverviewImprovementsSkeleton = () => /* @__PURE__ */ jsx("div", { className:
|
|
|
74638
74638
|
var OperationsOverviewHeader = React141__default.memo(({
|
|
74639
74639
|
dateRange,
|
|
74640
74640
|
trendMode,
|
|
74641
|
+
lineOptions,
|
|
74642
|
+
selectedLineIds,
|
|
74641
74643
|
appTimezone,
|
|
74642
74644
|
mobileMenuContext,
|
|
74643
74645
|
onDateRangeChange,
|
|
74644
|
-
onTrendModeChange
|
|
74646
|
+
onTrendModeChange,
|
|
74647
|
+
onSelectedLineIdsChange
|
|
74645
74648
|
}) => {
|
|
74646
74649
|
bumpRenderCounter();
|
|
74647
74650
|
const [isFilterOpen, setIsFilterOpen] = React141__default.useState(false);
|
|
74651
|
+
const [isLinesDropdownOpen, setIsLinesDropdownOpen] = React141__default.useState(false);
|
|
74648
74652
|
const filterRef = React141__default.useRef(null);
|
|
74649
74653
|
const filterButtonRef = React141__default.useRef(null);
|
|
74650
74654
|
const mobileFilterButtonRef = React141__default.useRef(null);
|
|
74651
|
-
const
|
|
74652
|
-
() => getCurrentWeekToDateRange(appTimezone),
|
|
74653
|
-
[appTimezone]
|
|
74654
|
-
);
|
|
74655
|
-
const isCurrentWeekToDateRange = dateRange.startKey === currentWeekRange.startKey && dateRange.endKey === currentWeekRange.endKey;
|
|
74655
|
+
const linesDropdownRef = React141__default.useRef(null);
|
|
74656
74656
|
const mobileSubtitle = React141__default.useMemo(() => {
|
|
74657
|
-
if (
|
|
74658
|
-
return
|
|
74657
|
+
if (dateRange.startKey === dateRange.endKey) {
|
|
74658
|
+
return format(parseDateKeyToDate(dateRange.startKey), "do MMM, yyyy");
|
|
74659
74659
|
}
|
|
74660
74660
|
return `${format(parseDateKeyToDate(dateRange.startKey), "do MMM")} - ${format(parseDateKeyToDate(dateRange.endKey), "do MMM, yyyy")}`;
|
|
74661
|
-
}, [dateRange.endKey, dateRange.startKey
|
|
74661
|
+
}, [dateRange.endKey, dateRange.startKey]);
|
|
74662
74662
|
const desktopSubtitle = React141__default.useMemo(() => {
|
|
74663
|
-
if (
|
|
74664
|
-
return
|
|
74663
|
+
if (dateRange.startKey === dateRange.endKey) {
|
|
74664
|
+
return format(parseDateKeyToDate(dateRange.startKey), "do MMMM, yyyy");
|
|
74665
74665
|
}
|
|
74666
74666
|
return `${format(parseDateKeyToDate(dateRange.startKey), "do MMMM, yyyy")} - ${format(parseDateKeyToDate(dateRange.endKey), "do MMMM, yyyy")}`;
|
|
74667
|
-
}, [dateRange.endKey, dateRange.startKey
|
|
74667
|
+
}, [dateRange.endKey, dateRange.startKey]);
|
|
74668
|
+
const availableLineIds = React141__default.useMemo(
|
|
74669
|
+
() => lineOptions.map((line) => line.id),
|
|
74670
|
+
[lineOptions]
|
|
74671
|
+
);
|
|
74672
|
+
const selectedLineIdSet = React141__default.useMemo(
|
|
74673
|
+
() => new Set(selectedLineIds),
|
|
74674
|
+
[selectedLineIds]
|
|
74675
|
+
);
|
|
74676
|
+
const isAllLinesSelected = React141__default.useMemo(() => {
|
|
74677
|
+
if (availableLineIds.length === 0) return true;
|
|
74678
|
+
return availableLineIds.every((lineId) => selectedLineIdSet.has(lineId));
|
|
74679
|
+
}, [availableLineIds, selectedLineIdSet]);
|
|
74680
|
+
const activeFilterCount = React141__default.useMemo(() => {
|
|
74681
|
+
let count = 0;
|
|
74682
|
+
if (trendMode !== "all") count += 1;
|
|
74683
|
+
if (!isAllLinesSelected) count += 1;
|
|
74684
|
+
return count;
|
|
74685
|
+
}, [isAllLinesSelected, trendMode]);
|
|
74668
74686
|
const handleFilterToggle = React141__default.useCallback(() => {
|
|
74669
74687
|
trackCoreEvent("Operations Overview Filter Toggled", {
|
|
74670
74688
|
action: !isFilterOpen ? "open" : "close"
|
|
@@ -74678,10 +74696,43 @@ var OperationsOverviewHeader = React141__default.memo(({
|
|
|
74678
74696
|
});
|
|
74679
74697
|
onTrendModeChange(nextMode);
|
|
74680
74698
|
}, [onTrendModeChange]);
|
|
74699
|
+
const handleAllLinesToggle = React141__default.useCallback(() => {
|
|
74700
|
+
trackCoreEvent("Operations Overview Line Filter Changed", {
|
|
74701
|
+
selected_line_ids: availableLineIds,
|
|
74702
|
+
selected_line_count: availableLineIds.length,
|
|
74703
|
+
mode: "all"
|
|
74704
|
+
});
|
|
74705
|
+
onSelectedLineIdsChange(availableLineIds);
|
|
74706
|
+
}, [availableLineIds, onSelectedLineIdsChange]);
|
|
74707
|
+
const handleLineToggle = React141__default.useCallback((lineId) => {
|
|
74708
|
+
const current = new Set(selectedLineIds);
|
|
74709
|
+
if (current.has(lineId)) {
|
|
74710
|
+
if (current.size <= 1) return;
|
|
74711
|
+
current.delete(lineId);
|
|
74712
|
+
} else {
|
|
74713
|
+
current.add(lineId);
|
|
74714
|
+
}
|
|
74715
|
+
const next = availableLineIds.filter((id3) => current.has(id3));
|
|
74716
|
+
trackCoreEvent("Operations Overview Line Filter Changed", {
|
|
74717
|
+
selected_line_ids: next,
|
|
74718
|
+
selected_line_count: next.length,
|
|
74719
|
+
mode: "custom"
|
|
74720
|
+
});
|
|
74721
|
+
onSelectedLineIdsChange(next);
|
|
74722
|
+
}, [availableLineIds, onSelectedLineIdsChange, selectedLineIds]);
|
|
74723
|
+
const handleClearAllFilters = React141__default.useCallback(() => {
|
|
74724
|
+
onTrendModeChange("all");
|
|
74725
|
+
onSelectedLineIdsChange(availableLineIds);
|
|
74726
|
+
setIsFilterOpen(false);
|
|
74727
|
+
}, [availableLineIds, onSelectedLineIdsChange, onTrendModeChange]);
|
|
74681
74728
|
React141__default.useEffect(() => {
|
|
74682
74729
|
const handleClickOutside = (event) => {
|
|
74683
|
-
|
|
74730
|
+
const target = event.target;
|
|
74731
|
+
if (filterRef.current && !filterRef.current.contains(target) && filterButtonRef.current && !filterButtonRef.current.contains(target) && mobileFilterButtonRef.current && !mobileFilterButtonRef.current.contains(target)) {
|
|
74684
74732
|
setIsFilterOpen(false);
|
|
74733
|
+
setIsLinesDropdownOpen(false);
|
|
74734
|
+
} else if (linesDropdownRef.current && !linesDropdownRef.current.contains(target)) {
|
|
74735
|
+
setIsLinesDropdownOpen(false);
|
|
74685
74736
|
}
|
|
74686
74737
|
};
|
|
74687
74738
|
document.addEventListener("mousedown", handleClickOutside);
|
|
@@ -74720,11 +74771,11 @@ var OperationsOverviewHeader = React141__default.memo(({
|
|
|
74720
74771
|
{
|
|
74721
74772
|
ref: mobileFilterButtonRef,
|
|
74722
74773
|
onClick: handleFilterToggle,
|
|
74723
|
-
className: `p-2 rounded-full transition-colors relative ${isFilterOpen ||
|
|
74774
|
+
className: `p-2 rounded-full transition-colors relative ${isFilterOpen || activeFilterCount > 0 ? "bg-blue-50" : "active:bg-gray-100"}`,
|
|
74724
74775
|
"aria-label": "Open filters",
|
|
74725
74776
|
children: [
|
|
74726
|
-
/* @__PURE__ */ jsx(Filter, { className: `w-5 h-5 ${
|
|
74727
|
-
|
|
74777
|
+
/* @__PURE__ */ jsx(Filter, { className: `w-5 h-5 ${activeFilterCount > 0 ? "text-blue-600" : "text-gray-700"}` }),
|
|
74778
|
+
activeFilterCount > 0 ? /* @__PURE__ */ jsx("span", { className: "absolute -top-1 -right-1 flex items-center justify-center w-4 h-4 bg-blue-600 text-white text-[10px] rounded-full font-bold", children: activeFilterCount }) : null
|
|
74728
74779
|
]
|
|
74729
74780
|
}
|
|
74730
74781
|
)
|
|
@@ -74752,10 +74803,10 @@ var OperationsOverviewHeader = React141__default.memo(({
|
|
|
74752
74803
|
{
|
|
74753
74804
|
ref: filterButtonRef,
|
|
74754
74805
|
onClick: handleFilterToggle,
|
|
74755
|
-
className: `flex items-center gap-2 px-3 py-1.5 rounded-lg border text-sm font-medium transition-all shadow-sm ${isFilterOpen ||
|
|
74806
|
+
className: `flex items-center gap-2 px-3 py-1.5 rounded-lg border text-sm font-medium transition-all shadow-sm ${isFilterOpen || activeFilterCount > 0 ? "border-blue-500 bg-blue-50 text-blue-700 ring-1 ring-blue-500" : "border-slate-200 bg-white text-slate-700 hover:bg-slate-50"}`,
|
|
74756
74807
|
"aria-label": "Open filters",
|
|
74757
74808
|
children: [
|
|
74758
|
-
/* @__PURE__ */ jsx(Filter, { className: `w-[18px] h-[18px] ${
|
|
74809
|
+
/* @__PURE__ */ jsx(Filter, { className: `w-[18px] h-[18px] ${activeFilterCount > 0 ? "text-blue-600" : "text-slate-500"}` }),
|
|
74759
74810
|
"Filters",
|
|
74760
74811
|
/* @__PURE__ */ jsx(ChevronDown, { className: `w-4 h-4 ml-0.5 transition-transform duration-200 ${isFilterOpen ? "rotate-180" : ""}` })
|
|
74761
74812
|
]
|
|
@@ -74766,40 +74817,94 @@ var OperationsOverviewHeader = React141__default.memo(({
|
|
|
74766
74817
|
isFilterOpen ? /* @__PURE__ */ jsxs("div", { ref: filterRef, className: "absolute right-3 sm:right-4 md:right-5 lg:right-6 top-full mt-2 w-72 bg-white rounded-xl shadow-xl border border-gray-100 p-4 z-50", children: [
|
|
74767
74818
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-3", children: [
|
|
74768
74819
|
/* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-gray-900", children: "Filter View" }),
|
|
74769
|
-
|
|
74820
|
+
activeFilterCount > 0 ? /* @__PURE__ */ jsx(
|
|
74770
74821
|
"button",
|
|
74771
74822
|
{
|
|
74772
|
-
onClick:
|
|
74773
|
-
onTrendModeChange("all");
|
|
74774
|
-
setIsFilterOpen(false);
|
|
74775
|
-
},
|
|
74823
|
+
onClick: handleClearAllFilters,
|
|
74776
74824
|
className: "text-xs text-red-600 hover:text-red-700 font-medium",
|
|
74777
74825
|
children: "Clear all"
|
|
74778
74826
|
}
|
|
74779
74827
|
) : null
|
|
74780
74828
|
] }),
|
|
74781
|
-
/* @__PURE__ */
|
|
74782
|
-
/* @__PURE__ */
|
|
74783
|
-
|
|
74784
|
-
"
|
|
74785
|
-
|
|
74786
|
-
|
|
74787
|
-
|
|
74788
|
-
|
|
74789
|
-
|
|
74790
|
-
|
|
74791
|
-
|
|
74792
|
-
|
|
74793
|
-
|
|
74794
|
-
|
|
74795
|
-
|
|
74796
|
-
|
|
74797
|
-
|
|
74798
|
-
|
|
74799
|
-
|
|
74800
|
-
|
|
74801
|
-
|
|
74802
|
-
|
|
74829
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
74830
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
74831
|
+
/* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-gray-500 uppercase tracking-wide ml-1", children: "Shift" }),
|
|
74832
|
+
/* @__PURE__ */ jsx("div", { className: "relative", children: /* @__PURE__ */ jsxs(
|
|
74833
|
+
"select",
|
|
74834
|
+
{
|
|
74835
|
+
value: trendMode,
|
|
74836
|
+
onChange: handleTrendModeChange,
|
|
74837
|
+
className: "w-full appearance-none pl-3 pr-8 py-2 text-sm bg-gray-50 border border-gray-200 hover:border-gray-300 rounded-lg text-gray-900 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:bg-white transition-all cursor-pointer",
|
|
74838
|
+
style: {
|
|
74839
|
+
backgroundImage: `url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e")`,
|
|
74840
|
+
backgroundPosition: "right 0.75rem center",
|
|
74841
|
+
backgroundRepeat: "no-repeat",
|
|
74842
|
+
backgroundSize: "1.2em 1.2em"
|
|
74843
|
+
},
|
|
74844
|
+
children: [
|
|
74845
|
+
/* @__PURE__ */ jsx("option", { value: "all", children: "All Shifts" }),
|
|
74846
|
+
/* @__PURE__ */ jsx("option", { value: "day", children: "Day Shift" }),
|
|
74847
|
+
/* @__PURE__ */ jsx("option", { value: "night", children: "Night Shift" })
|
|
74848
|
+
]
|
|
74849
|
+
}
|
|
74850
|
+
) })
|
|
74851
|
+
] }),
|
|
74852
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1", ref: linesDropdownRef, children: [
|
|
74853
|
+
/* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-gray-500 uppercase tracking-wide ml-1", children: "Lines" }),
|
|
74854
|
+
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
74855
|
+
/* @__PURE__ */ jsxs(
|
|
74856
|
+
"button",
|
|
74857
|
+
{
|
|
74858
|
+
type: "button",
|
|
74859
|
+
onClick: () => setIsLinesDropdownOpen((prev) => !prev),
|
|
74860
|
+
className: "w-full flex items-center justify-between pl-3 pr-3 py-2 text-sm bg-gray-50 border border-gray-200 hover:border-gray-300 rounded-lg text-gray-900 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:bg-white transition-all cursor-pointer text-left",
|
|
74861
|
+
children: [
|
|
74862
|
+
/* @__PURE__ */ jsx("span", { className: "truncate pr-2", children: isAllLinesSelected ? "All Lines" : selectedLineIds.length === 1 ? lineOptions.find((l) => l.id === selectedLineIds[0])?.name || "1 Line Selected" : `${selectedLineIds.length} Lines Selected` }),
|
|
74863
|
+
/* @__PURE__ */ jsx(ChevronDown, { className: `w-4 h-4 text-gray-500 flex-shrink-0 transition-transform ${isLinesDropdownOpen ? "rotate-180" : ""}` })
|
|
74864
|
+
]
|
|
74865
|
+
}
|
|
74866
|
+
),
|
|
74867
|
+
isLinesDropdownOpen ? /* @__PURE__ */ jsxs("div", { className: "absolute top-full left-0 right-0 mt-1 max-h-48 overflow-y-auto rounded-lg border border-gray-200 bg-white shadow-lg p-1.5 space-y-0.5 z-[60]", children: [
|
|
74868
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2.5 rounded-md px-2 py-1.5 text-sm text-gray-900 hover:bg-gray-50 cursor-pointer", children: [
|
|
74869
|
+
/* @__PURE__ */ jsx(
|
|
74870
|
+
"input",
|
|
74871
|
+
{
|
|
74872
|
+
type: "checkbox",
|
|
74873
|
+
className: "h-4 w-4 rounded border-slate-300 text-blue-600 focus:ring-blue-500",
|
|
74874
|
+
checked: isAllLinesSelected,
|
|
74875
|
+
onChange: handleAllLinesToggle
|
|
74876
|
+
}
|
|
74877
|
+
),
|
|
74878
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: "All Lines" })
|
|
74879
|
+
] }),
|
|
74880
|
+
lineOptions.map((line) => {
|
|
74881
|
+
const isChecked = selectedLineIdSet.has(line.id);
|
|
74882
|
+
const disableUncheck = isChecked && selectedLineIds.length <= 1;
|
|
74883
|
+
return /* @__PURE__ */ jsxs(
|
|
74884
|
+
"label",
|
|
74885
|
+
{
|
|
74886
|
+
className: `flex items-center gap-2.5 rounded-md px-2 py-1.5 text-sm cursor-pointer transition-colors ${disableUncheck ? "text-gray-400 hover:bg-transparent" : "text-gray-800 hover:bg-gray-50"}`,
|
|
74887
|
+
children: [
|
|
74888
|
+
/* @__PURE__ */ jsx(
|
|
74889
|
+
"input",
|
|
74890
|
+
{
|
|
74891
|
+
type: "checkbox",
|
|
74892
|
+
className: "h-4 w-4 rounded border-slate-300 text-blue-600 focus:ring-blue-500 disabled:opacity-40",
|
|
74893
|
+
checked: isChecked,
|
|
74894
|
+
disabled: disableUncheck,
|
|
74895
|
+
onChange: () => handleLineToggle(line.id)
|
|
74896
|
+
}
|
|
74897
|
+
),
|
|
74898
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: line.name })
|
|
74899
|
+
]
|
|
74900
|
+
},
|
|
74901
|
+
line.id
|
|
74902
|
+
);
|
|
74903
|
+
})
|
|
74904
|
+
] }) : null
|
|
74905
|
+
] })
|
|
74906
|
+
] })
|
|
74907
|
+
] })
|
|
74803
74908
|
] }) : null
|
|
74804
74909
|
] }) });
|
|
74805
74910
|
});
|
|
@@ -75698,6 +75803,7 @@ var PlantHeadView = () => {
|
|
|
75698
75803
|
const [dateRange, setDateRange] = React141__default.useState(() => getCurrentWeekToDateRange(appTimezone));
|
|
75699
75804
|
const [usesThisWeekComparison, setUsesThisWeekComparison] = React141__default.useState(true);
|
|
75700
75805
|
const [trendMode, setTrendMode] = React141__default.useState("all");
|
|
75806
|
+
const [selectedLineIds, setSelectedLineIds] = React141__default.useState([]);
|
|
75701
75807
|
React141__default.useEffect(() => {
|
|
75702
75808
|
trackCorePageView("Operations Overview", {
|
|
75703
75809
|
dashboard_surface: "operations_overview"
|
|
@@ -75716,9 +75822,27 @@ var PlantHeadView = () => {
|
|
|
75716
75822
|
() => normalizedLineIds.join(","),
|
|
75717
75823
|
[normalizedLineIds]
|
|
75718
75824
|
);
|
|
75825
|
+
const lineOptions = React141__default.useMemo(
|
|
75826
|
+
() => normalizedLineIds.map((lineId) => ({
|
|
75827
|
+
id: lineId,
|
|
75828
|
+
name: getLineDisplayName(entityConfig, lineId)
|
|
75829
|
+
})),
|
|
75830
|
+
[entityConfig, normalizedLineIds]
|
|
75831
|
+
);
|
|
75832
|
+
React141__default.useEffect(() => {
|
|
75833
|
+
setSelectedLineIds((previous) => {
|
|
75834
|
+
if (normalizedLineIds.length === 0) return [];
|
|
75835
|
+
const previousSet = new Set(previous);
|
|
75836
|
+
const next = normalizedLineIds.filter((lineId) => previousSet.has(lineId));
|
|
75837
|
+
if (next.length === 0) {
|
|
75838
|
+
return normalizedLineIds;
|
|
75839
|
+
}
|
|
75840
|
+
return next;
|
|
75841
|
+
});
|
|
75842
|
+
}, [lineIdsKey, normalizedLineIds]);
|
|
75719
75843
|
const scopedLineIds = React141__default.useMemo(
|
|
75720
|
-
() =>
|
|
75721
|
-
[
|
|
75844
|
+
() => selectedLineIds.length > 0 ? selectedLineIds : normalizedLineIds,
|
|
75845
|
+
[normalizedLineIds, selectedLineIds]
|
|
75722
75846
|
);
|
|
75723
75847
|
const initializedTimezoneRef = React141__default.useRef(appTimezone);
|
|
75724
75848
|
React141__default.useEffect(() => {
|
|
@@ -75746,6 +75870,16 @@ var PlantHeadView = () => {
|
|
|
75746
75870
|
const handleTrendModeChange = React141__default.useCallback((mode) => {
|
|
75747
75871
|
setTrendMode(mode);
|
|
75748
75872
|
}, []);
|
|
75873
|
+
const handleSelectedLineIdsChange = React141__default.useCallback((lineIds) => {
|
|
75874
|
+
if (normalizedLineIds.length === 0) {
|
|
75875
|
+
setSelectedLineIds([]);
|
|
75876
|
+
return;
|
|
75877
|
+
}
|
|
75878
|
+
const uniqueSelected = Array.from(new Set(lineIds));
|
|
75879
|
+
const selectedSet = new Set(uniqueSelected);
|
|
75880
|
+
const next = normalizedLineIds.filter((lineId) => selectedSet.has(lineId));
|
|
75881
|
+
setSelectedLineIds(next.length > 0 ? next : normalizedLineIds);
|
|
75882
|
+
}, [normalizedLineIds]);
|
|
75749
75883
|
const buildLineMonthlyHistoryUrl = React141__default.useCallback((lineId) => {
|
|
75750
75884
|
const rangeStartDate = parseDateKeyToDate(dateRange.startKey);
|
|
75751
75885
|
const params = new URLSearchParams();
|
|
@@ -75812,10 +75946,13 @@ var PlantHeadView = () => {
|
|
|
75812
75946
|
{
|
|
75813
75947
|
dateRange,
|
|
75814
75948
|
trendMode,
|
|
75949
|
+
lineOptions,
|
|
75950
|
+
selectedLineIds: scopedLineIds,
|
|
75815
75951
|
appTimezone,
|
|
75816
75952
|
mobileMenuContext,
|
|
75817
75953
|
onDateRangeChange: handleDateRangeChange,
|
|
75818
|
-
onTrendModeChange: handleTrendModeChange
|
|
75954
|
+
onTrendModeChange: handleTrendModeChange,
|
|
75955
|
+
onSelectedLineIdsChange: handleSelectedLineIdsChange
|
|
75819
75956
|
}
|
|
75820
75957
|
),
|
|
75821
75958
|
/* @__PURE__ */ jsxs("div", { className: "p-4 sm:p-6 pb-6 max-w-[1800px] mx-auto w-full flex-1 min-h-0 overflow-y-auto flex flex-col gap-5", children: [
|