@optifye/dashboard-core 6.11.13 → 6.11.15
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 +13 -0
- package/dist/index.d.mts +12 -2
- package/dist/index.d.ts +12 -2
- package/dist/index.js +362 -97
- package/dist/index.mjs +362 -97
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -11742,6 +11742,9 @@ var toWorkspaceDetailedMetrics = ({
|
|
|
11742
11742
|
const idealOutput = coerceNumber(data.ideal_output ?? data.ideal_output_until_now, 0);
|
|
11743
11743
|
const outputDifference = totalActions - idealOutput;
|
|
11744
11744
|
const hourlyCycleTimes = Array.isArray(data.hourly_cycle_times) ? data.hourly_cycle_times.map((value) => coerceNumber(value, 0)) : [];
|
|
11745
|
+
const cycleCompletionClipCount = data.cycle_completion_clip_count === null || data.cycle_completion_clip_count === void 0 ? null : coerceNumber(data.cycle_completion_clip_count, 0);
|
|
11746
|
+
const cycleTimeDataStatus = data.cycle_time_data_status === "missing_clips" ? "missing_clips" : data.cycle_time_data_status === "available" ? "available" : null;
|
|
11747
|
+
const cycleTimeTimezone = typeof data.cycle_time_timezone === "string" ? data.cycle_time_timezone : null;
|
|
11745
11748
|
const totalWorkspacesValue = coerceNumber(
|
|
11746
11749
|
data.total_workspaces ?? lineMetricsById?.[data.line_id || ""]?.total_workspaces ?? workspaceConfig.totalWorkspaces,
|
|
11747
11750
|
0
|
|
@@ -11789,6 +11792,9 @@ var toWorkspaceDetailedMetrics = ({
|
|
|
11789
11792
|
total_actions: totalActions,
|
|
11790
11793
|
hourly_action_counts: hourlyActionCounts,
|
|
11791
11794
|
hourly_cycle_times: hourlyCycleTimes,
|
|
11795
|
+
cycle_completion_clip_count: cycleCompletionClipCount,
|
|
11796
|
+
cycle_time_data_status: cycleTimeDataStatus,
|
|
11797
|
+
cycle_time_timezone: cycleTimeTimezone,
|
|
11792
11798
|
workspace_rank: coerceNumber(data.workspace_rank, 0),
|
|
11793
11799
|
total_workspaces: totalWorkspacesValue,
|
|
11794
11800
|
ideal_output_until_now: idealOutput,
|
|
@@ -32669,16 +32675,162 @@ var CycleTimeOverTimeChart = ({
|
|
|
32669
32675
|
return `${minutes} minutes ${seconds} seconds ago`;
|
|
32670
32676
|
}
|
|
32671
32677
|
};
|
|
32678
|
+
const getNumericValue = React141__default.useCallback((value) => typeof value === "number" && Number.isFinite(value) ? value : null, []);
|
|
32679
|
+
const renderChartTooltip = React141__default.useCallback((tooltipProps) => {
|
|
32680
|
+
const { active, payload } = tooltipProps;
|
|
32681
|
+
if (!active || !Array.isArray(payload) || payload.length === 0) {
|
|
32682
|
+
return null;
|
|
32683
|
+
}
|
|
32684
|
+
const visibleEntries = payload.filter((entry) => getNumericValue(entry.value) !== null);
|
|
32685
|
+
if (!visibleEntries.length) {
|
|
32686
|
+
return null;
|
|
32687
|
+
}
|
|
32688
|
+
return /* @__PURE__ */ jsxs(
|
|
32689
|
+
"div",
|
|
32690
|
+
{
|
|
32691
|
+
style: {
|
|
32692
|
+
backgroundColor: "white",
|
|
32693
|
+
border: "none",
|
|
32694
|
+
borderRadius: "8px",
|
|
32695
|
+
boxShadow: "0 4px 12px rgba(0,0,0,0.1)",
|
|
32696
|
+
padding: "8px 12px",
|
|
32697
|
+
fontSize: "13px"
|
|
32698
|
+
},
|
|
32699
|
+
children: [
|
|
32700
|
+
/* @__PURE__ */ jsx(
|
|
32701
|
+
"div",
|
|
32702
|
+
{
|
|
32703
|
+
style: {
|
|
32704
|
+
color: "#374151",
|
|
32705
|
+
fontWeight: 600,
|
|
32706
|
+
marginBottom: "4px"
|
|
32707
|
+
},
|
|
32708
|
+
children: payload[0]?.payload?.tooltip || ""
|
|
32709
|
+
}
|
|
32710
|
+
),
|
|
32711
|
+
visibleEntries.map((entry) => {
|
|
32712
|
+
const numericValue = getNumericValue(entry.value);
|
|
32713
|
+
if (numericValue === null) {
|
|
32714
|
+
return null;
|
|
32715
|
+
}
|
|
32716
|
+
return /* @__PURE__ */ jsx(
|
|
32717
|
+
"div",
|
|
32718
|
+
{
|
|
32719
|
+
style: {
|
|
32720
|
+
color: "#4B5563",
|
|
32721
|
+
padding: "2px 0"
|
|
32722
|
+
},
|
|
32723
|
+
children: entry.name === "idleMinutes" ? `Idle Time: ${numericValue.toFixed(0)} minutes` : `Cycle Time: ${numericValue.toFixed(1)} seconds`
|
|
32724
|
+
},
|
|
32725
|
+
`${entry.name}-${numericValue}`
|
|
32726
|
+
);
|
|
32727
|
+
})
|
|
32728
|
+
]
|
|
32729
|
+
}
|
|
32730
|
+
);
|
|
32731
|
+
}, [getNumericValue]);
|
|
32732
|
+
const renderCycleDot = React141__default.useCallback((props) => {
|
|
32733
|
+
const { cx: cx2, cy, payload } = props;
|
|
32734
|
+
const cycleTime = getNumericValue(payload?.cycleTime);
|
|
32735
|
+
if (cycleTime === null) {
|
|
32736
|
+
return /* @__PURE__ */ jsx("g", {});
|
|
32737
|
+
}
|
|
32738
|
+
return /* @__PURE__ */ jsx(
|
|
32739
|
+
"circle",
|
|
32740
|
+
{
|
|
32741
|
+
cx: cx2,
|
|
32742
|
+
cy,
|
|
32743
|
+
r: 4,
|
|
32744
|
+
fill: cycleTime <= idealCycleTime ? "#00AB45" : "#E34329",
|
|
32745
|
+
stroke: "#fff",
|
|
32746
|
+
strokeWidth: 1,
|
|
32747
|
+
style: {
|
|
32748
|
+
filter: "brightness(1)",
|
|
32749
|
+
transition: "filter 0.3s ease, transform 0.3s ease",
|
|
32750
|
+
cursor: "pointer"
|
|
32751
|
+
},
|
|
32752
|
+
onMouseEnter: (e) => {
|
|
32753
|
+
const target = e.target;
|
|
32754
|
+
target.style.filter = "brightness(1.2)";
|
|
32755
|
+
target.style.transform = "scale(1.2)";
|
|
32756
|
+
},
|
|
32757
|
+
onMouseLeave: (e) => {
|
|
32758
|
+
const target = e.target;
|
|
32759
|
+
target.style.filter = "brightness(1)";
|
|
32760
|
+
target.style.transform = "scale(1)";
|
|
32761
|
+
}
|
|
32762
|
+
}
|
|
32763
|
+
);
|
|
32764
|
+
}, [getNumericValue, idealCycleTime]);
|
|
32765
|
+
const renderCycleActiveDot = React141__default.useCallback((props) => {
|
|
32766
|
+
const { cx: cx2, cy, payload } = props;
|
|
32767
|
+
const cycleTime = getNumericValue(payload?.cycleTime);
|
|
32768
|
+
if (cycleTime === null) {
|
|
32769
|
+
return /* @__PURE__ */ jsx("g", {});
|
|
32770
|
+
}
|
|
32771
|
+
return /* @__PURE__ */ jsx(
|
|
32772
|
+
"circle",
|
|
32773
|
+
{
|
|
32774
|
+
cx: cx2,
|
|
32775
|
+
cy,
|
|
32776
|
+
r: 6,
|
|
32777
|
+
fill: cycleTime <= idealCycleTime ? "#00AB45" : "#E34329",
|
|
32778
|
+
stroke: "#fff",
|
|
32779
|
+
strokeWidth: 2,
|
|
32780
|
+
style: {
|
|
32781
|
+
filter: "drop-shadow(0 0 2px rgba(0,0,0,0.2))"
|
|
32782
|
+
}
|
|
32783
|
+
}
|
|
32784
|
+
);
|
|
32785
|
+
}, [getNumericValue, idealCycleTime]);
|
|
32786
|
+
const renderIdleDot = React141__default.useCallback((props) => {
|
|
32787
|
+
const { cx: cx2, cy, payload } = props;
|
|
32788
|
+
const idleMinutes = getNumericValue(payload?.idleMinutes);
|
|
32789
|
+
if (idleMinutes === null) {
|
|
32790
|
+
return /* @__PURE__ */ jsx("g", {});
|
|
32791
|
+
}
|
|
32792
|
+
return /* @__PURE__ */ jsx(
|
|
32793
|
+
"circle",
|
|
32794
|
+
{
|
|
32795
|
+
cx: cx2,
|
|
32796
|
+
cy,
|
|
32797
|
+
r: 4,
|
|
32798
|
+
fill: "#f59e0b",
|
|
32799
|
+
stroke: "#fff",
|
|
32800
|
+
strokeWidth: 1
|
|
32801
|
+
}
|
|
32802
|
+
);
|
|
32803
|
+
}, [getNumericValue]);
|
|
32804
|
+
const renderIdleActiveDot = React141__default.useCallback((props) => {
|
|
32805
|
+
const { cx: cx2, cy, payload } = props;
|
|
32806
|
+
const idleMinutes = getNumericValue(payload?.idleMinutes);
|
|
32807
|
+
if (idleMinutes === null) {
|
|
32808
|
+
return /* @__PURE__ */ jsx("g", {});
|
|
32809
|
+
}
|
|
32810
|
+
return /* @__PURE__ */ jsx(
|
|
32811
|
+
"circle",
|
|
32812
|
+
{
|
|
32813
|
+
cx: cx2,
|
|
32814
|
+
cy,
|
|
32815
|
+
r: 6,
|
|
32816
|
+
fill: "#f59e0b",
|
|
32817
|
+
stroke: "#fff",
|
|
32818
|
+
strokeWidth: 2
|
|
32819
|
+
}
|
|
32820
|
+
);
|
|
32821
|
+
}, [getNumericValue]);
|
|
32672
32822
|
const chartData = React141__default.useMemo(() => Array.from({ length: DURATION }, (_, i) => {
|
|
32823
|
+
const cycleTime = getNumericValue(finalData[i]);
|
|
32824
|
+
const idleMinutes = showIdleTime ? getNumericValue(idleTimeData[i]) : null;
|
|
32673
32825
|
return {
|
|
32674
32826
|
timeIndex: i,
|
|
32675
32827
|
label: formatTimeLabel(i),
|
|
32676
32828
|
tooltip: formatTooltipTime(i),
|
|
32677
|
-
cycleTime
|
|
32678
|
-
idleMinutes
|
|
32679
|
-
color:
|
|
32829
|
+
cycleTime,
|
|
32830
|
+
idleMinutes,
|
|
32831
|
+
color: cycleTime !== null && cycleTime <= idealCycleTime ? "#00AB45" : "#E34329"
|
|
32680
32832
|
};
|
|
32681
|
-
}), [DURATION, finalData, showIdleTime, idleTimeData, idealCycleTime]);
|
|
32833
|
+
}), [DURATION, finalData, showIdleTime, idleTimeData, idealCycleTime, getNumericValue]);
|
|
32682
32834
|
const renderLegend = () => {
|
|
32683
32835
|
if (!showIdleTime) return null;
|
|
32684
32836
|
return /* @__PURE__ */ jsx("div", { className: "flex items-center justify-start text-[10px] font-bold text-gray-500 mb-6 tracking-[0.05em] gap-5", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
@@ -32765,36 +32917,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
32765
32917
|
Tooltip,
|
|
32766
32918
|
{
|
|
32767
32919
|
cursor: { stroke: "#E5E7EB", strokeWidth: 1 },
|
|
32768
|
-
|
|
32769
|
-
backgroundColor: "white",
|
|
32770
|
-
border: "none",
|
|
32771
|
-
borderRadius: "8px",
|
|
32772
|
-
boxShadow: "0 4px 12px rgba(0,0,0,0.1)",
|
|
32773
|
-
padding: "8px 12px",
|
|
32774
|
-
fontSize: "13px"
|
|
32775
|
-
},
|
|
32776
|
-
labelStyle: {
|
|
32777
|
-
color: "#374151",
|
|
32778
|
-
fontWeight: 600,
|
|
32779
|
-
marginBottom: "4px"
|
|
32780
|
-
},
|
|
32781
|
-
itemStyle: {
|
|
32782
|
-
color: "#4B5563",
|
|
32783
|
-
padding: "2px 0"
|
|
32784
|
-
},
|
|
32785
|
-
labelFormatter: (label, payload) => {
|
|
32786
|
-
if (payload && payload[0]) {
|
|
32787
|
-
return payload[0].payload.tooltip;
|
|
32788
|
-
}
|
|
32789
|
-
return label;
|
|
32790
|
-
},
|
|
32791
|
-
formatter: (value, name) => {
|
|
32792
|
-
const numValue = typeof value === "number" ? value : Number(value);
|
|
32793
|
-
if (name === "idleMinutes") {
|
|
32794
|
-
return [`${numValue.toFixed(0)} minutes`, "Idle Time"];
|
|
32795
|
-
}
|
|
32796
|
-
return [`${numValue.toFixed(1)} seconds`, "Cycle Time"];
|
|
32797
|
-
},
|
|
32920
|
+
content: renderChartTooltip,
|
|
32798
32921
|
animationDuration: 200
|
|
32799
32922
|
}
|
|
32800
32923
|
),
|
|
@@ -32823,52 +32946,9 @@ var CycleTimeOverTimeChart = ({
|
|
|
32823
32946
|
dataKey: "cycleTime",
|
|
32824
32947
|
stroke: "#3B82F6",
|
|
32825
32948
|
strokeWidth: 2,
|
|
32826
|
-
|
|
32827
|
-
|
|
32828
|
-
|
|
32829
|
-
"circle",
|
|
32830
|
-
{
|
|
32831
|
-
cx: cx2,
|
|
32832
|
-
cy,
|
|
32833
|
-
r: 4,
|
|
32834
|
-
fill: payload.cycleTime <= idealCycleTime ? "#00AB45" : "#E34329",
|
|
32835
|
-
stroke: "#fff",
|
|
32836
|
-
strokeWidth: 1,
|
|
32837
|
-
style: {
|
|
32838
|
-
filter: "brightness(1)",
|
|
32839
|
-
transition: "filter 0.3s ease, transform 0.3s ease",
|
|
32840
|
-
cursor: "pointer"
|
|
32841
|
-
},
|
|
32842
|
-
onMouseEnter: (e) => {
|
|
32843
|
-
const target = e.target;
|
|
32844
|
-
target.style.filter = "brightness(1.2)";
|
|
32845
|
-
target.style.transform = "scale(1.2)";
|
|
32846
|
-
},
|
|
32847
|
-
onMouseLeave: (e) => {
|
|
32848
|
-
const target = e.target;
|
|
32849
|
-
target.style.filter = "brightness(1)";
|
|
32850
|
-
target.style.transform = "scale(1)";
|
|
32851
|
-
}
|
|
32852
|
-
}
|
|
32853
|
-
);
|
|
32854
|
-
},
|
|
32855
|
-
activeDot: (props) => {
|
|
32856
|
-
const { cx: cx2, cy, payload } = props;
|
|
32857
|
-
return /* @__PURE__ */ jsx(
|
|
32858
|
-
"circle",
|
|
32859
|
-
{
|
|
32860
|
-
cx: cx2,
|
|
32861
|
-
cy,
|
|
32862
|
-
r: 6,
|
|
32863
|
-
fill: payload.cycleTime <= idealCycleTime ? "#00AB45" : "#E34329",
|
|
32864
|
-
stroke: "#fff",
|
|
32865
|
-
strokeWidth: 2,
|
|
32866
|
-
style: {
|
|
32867
|
-
filter: "drop-shadow(0 0 2px rgba(0,0,0,0.2))"
|
|
32868
|
-
}
|
|
32869
|
-
}
|
|
32870
|
-
);
|
|
32871
|
-
},
|
|
32949
|
+
connectNulls: false,
|
|
32950
|
+
dot: renderCycleDot,
|
|
32951
|
+
activeDot: renderCycleActiveDot,
|
|
32872
32952
|
isAnimationActive: shouldAnimate,
|
|
32873
32953
|
animationBegin: 0,
|
|
32874
32954
|
animationDuration: 1200,
|
|
@@ -32886,8 +32966,9 @@ var CycleTimeOverTimeChart = ({
|
|
|
32886
32966
|
stroke: "#f59e0b",
|
|
32887
32967
|
strokeWidth: 2,
|
|
32888
32968
|
strokeDasharray: "4 4",
|
|
32889
|
-
|
|
32890
|
-
|
|
32969
|
+
connectNulls: false,
|
|
32970
|
+
dot: renderIdleDot,
|
|
32971
|
+
activeDot: renderIdleActiveDot,
|
|
32891
32972
|
isAnimationActive: shouldAnimate,
|
|
32892
32973
|
animationBegin: 0,
|
|
32893
32974
|
animationDuration: 1200,
|
|
@@ -34615,8 +34696,20 @@ var CardFooter2 = (props) => {
|
|
|
34615
34696
|
return /* @__PURE__ */ jsx(RegisteredCardFooter, { ...props });
|
|
34616
34697
|
};
|
|
34617
34698
|
|
|
34699
|
+
// src/lib/utils/workspaceDetailCycleTime.ts
|
|
34700
|
+
var resolveWorkspaceDetailActionFamily = (workspace) => {
|
|
34701
|
+
if (workspace?.action_family === "assembly" || workspace?.action_family === "output" || workspace?.action_family === "other") {
|
|
34702
|
+
return workspace.action_family;
|
|
34703
|
+
}
|
|
34704
|
+
if (workspace?.action_type === "assembly" || workspace?.action_type === "output") {
|
|
34705
|
+
return workspace.action_type;
|
|
34706
|
+
}
|
|
34707
|
+
return null;
|
|
34708
|
+
};
|
|
34709
|
+
var shouldUseAssemblyCycleTimeLayout = (workspace) => workspace?.line_assembly_enabled === true && resolveWorkspaceDetailActionFamily(workspace) === "assembly";
|
|
34710
|
+
|
|
34618
34711
|
// src/components/dashboard/workspace/workspaceDetailCardRules.ts
|
|
34619
|
-
var shouldHideWorkspaceEfficiencyCard = (workspace) => workspace
|
|
34712
|
+
var shouldHideWorkspaceEfficiencyCard = (workspace) => shouldUseAssemblyCycleTimeLayout(workspace);
|
|
34620
34713
|
var WorkspaceMetricCardsImpl = ({
|
|
34621
34714
|
workspace,
|
|
34622
34715
|
className,
|
|
@@ -35325,6 +35418,37 @@ var getShiftElapsedMinutes = ({
|
|
|
35325
35418
|
const elapsed = differenceInMinutes(now4, shiftStartDate);
|
|
35326
35419
|
return Math.min(Math.max(elapsed, 0), shiftMinutes);
|
|
35327
35420
|
};
|
|
35421
|
+
var maskFutureHourlySeries = ({
|
|
35422
|
+
data,
|
|
35423
|
+
shiftStart,
|
|
35424
|
+
shiftEnd,
|
|
35425
|
+
shiftDate,
|
|
35426
|
+
timezone,
|
|
35427
|
+
now: now4 = /* @__PURE__ */ new Date()
|
|
35428
|
+
}) => {
|
|
35429
|
+
if (!Array.isArray(data)) {
|
|
35430
|
+
return [];
|
|
35431
|
+
}
|
|
35432
|
+
const normalizedData = data.map((value) => typeof value === "number" && Number.isFinite(value) ? value : null);
|
|
35433
|
+
if (!normalizedData.length) {
|
|
35434
|
+
return normalizedData;
|
|
35435
|
+
}
|
|
35436
|
+
const shiftMinutes = getShiftDurationMinutes(shiftStart, shiftEnd);
|
|
35437
|
+
const elapsedMinutes = getShiftElapsedMinutes({
|
|
35438
|
+
shiftStart,
|
|
35439
|
+
shiftEnd,
|
|
35440
|
+
shiftDate,
|
|
35441
|
+
timezone,
|
|
35442
|
+
now: now4
|
|
35443
|
+
});
|
|
35444
|
+
if (shiftMinutes === null || elapsedMinutes === null || elapsedMinutes >= shiftMinutes) {
|
|
35445
|
+
return normalizedData;
|
|
35446
|
+
}
|
|
35447
|
+
return normalizedData.map((value, index) => {
|
|
35448
|
+
const slotStartMinutes = index * 60;
|
|
35449
|
+
return slotStartMinutes > elapsedMinutes ? null : value;
|
|
35450
|
+
});
|
|
35451
|
+
};
|
|
35328
35452
|
var buildUptimeSeries = ({
|
|
35329
35453
|
idleTimeHourly,
|
|
35330
35454
|
shiftStart,
|
|
@@ -48863,7 +48987,7 @@ var WorkspacePdfGenerator = ({ workspace, className, idleTimeReasons, efficiency
|
|
|
48863
48987
|
setIsGenerating(true);
|
|
48864
48988
|
try {
|
|
48865
48989
|
const isUptimeMode = workspace.monitoring_mode === "uptime";
|
|
48866
|
-
const isAssemblyCycleMode = !isUptimeMode && workspace
|
|
48990
|
+
const isAssemblyCycleMode = !isUptimeMode && shouldUseAssemblyCycleTimeLayout(workspace);
|
|
48867
48991
|
const shiftMinutes = getShiftDurationMinutes(workspace.shift_start, workspace.shift_end);
|
|
48868
48992
|
const shiftSeconds = shiftMinutes ? shiftMinutes * 60 : 0;
|
|
48869
48993
|
const idleSeconds = Math.max(workspace.idle_time || 0, 0);
|
|
@@ -60324,6 +60448,7 @@ var MonthlyRangeFilter = ({
|
|
|
60324
60448
|
{
|
|
60325
60449
|
type: "button",
|
|
60326
60450
|
onClick: () => setIsOpen((prev) => !prev),
|
|
60451
|
+
"aria-label": showLabel ? void 0 : singleDateOnly ? "Select date" : "Select date range",
|
|
60327
60452
|
className: clsx(
|
|
60328
60453
|
"flex items-center transition-all duration-200 focus:outline-none",
|
|
60329
60454
|
!showLabel && "p-2 rounded-full hover:bg-gray-100",
|
|
@@ -62936,7 +63061,7 @@ var KPIsOverviewView = ({
|
|
|
62936
63061
|
() => getShiftEndDate(currentShiftDetails, configuredTimezone),
|
|
62937
63062
|
[currentShiftDetails, configuredTimezone]
|
|
62938
63063
|
);
|
|
62939
|
-
React141__default.useMemo(() => {
|
|
63064
|
+
const leaderboardShiftOptions = React141__default.useMemo(() => {
|
|
62940
63065
|
if (shiftConfig?.shifts && shiftConfig.shifts.length > 0) {
|
|
62941
63066
|
return shiftConfig.shifts.map((shift) => ({
|
|
62942
63067
|
id: shift.shiftId,
|
|
@@ -63735,6 +63860,17 @@ var KPIsOverviewView = ({
|
|
|
63735
63860
|
singleDateOnly: true
|
|
63736
63861
|
}
|
|
63737
63862
|
),
|
|
63863
|
+
/* @__PURE__ */ jsx("div", { className: "relative", children: /* @__PURE__ */ jsx(
|
|
63864
|
+
"select",
|
|
63865
|
+
{
|
|
63866
|
+
"aria-label": "Leaderboard shift",
|
|
63867
|
+
value: effectiveLeaderboardShiftId,
|
|
63868
|
+
onChange: (e) => setSelectedLeaderboardShiftId(Number(e.target.value)),
|
|
63869
|
+
className: "appearance-none pl-3 pr-8 py-1.5 text-sm font-medium bg-white border border-gray-200 hover:border-gray-300 rounded-lg text-gray-700 focus:outline-none focus:ring-2 focus:ring-blue-500 transition-all cursor-pointer shadow-sm min-w-[170px]",
|
|
63870
|
+
style: { 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")`, backgroundPosition: `right 0.5rem center`, backgroundRepeat: `no-repeat`, backgroundSize: `1.2em 1.2em` },
|
|
63871
|
+
children: leaderboardShiftOptions.map((shiftOption) => /* @__PURE__ */ jsx("option", { value: shiftOption.id, children: shiftOption.label }, shiftOption.id))
|
|
63872
|
+
}
|
|
63873
|
+
) }),
|
|
63738
63874
|
isHistoricalLeaderboardDaily && /* @__PURE__ */ jsx(
|
|
63739
63875
|
"button",
|
|
63740
63876
|
{
|
|
@@ -68022,8 +68158,74 @@ var TargetsView = ({
|
|
|
68022
68158
|
var TargetsViewWithDisplayNames = withAllWorkspaceDisplayNames(TargetsView);
|
|
68023
68159
|
var TargetsView_default = TargetsViewWithDisplayNames;
|
|
68024
68160
|
var AuthenticatedTargetsView = withAuth(React141__default.memo(TargetsViewWithDisplayNames));
|
|
68161
|
+
function useTimezone(options = {}) {
|
|
68162
|
+
const dashboardConfig = useDashboardConfig();
|
|
68163
|
+
const workspaceConfig = useWorkspaceConfig();
|
|
68164
|
+
const defaultTimezone = dashboardConfig?.dateTimeConfig?.defaultTimezone || "Asia/Kolkata";
|
|
68165
|
+
const [timezone, setTimezone] = useState(defaultTimezone);
|
|
68166
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
68167
|
+
const [error, setError] = useState(null);
|
|
68168
|
+
const fetchTimezone = useCallback(async () => {
|
|
68169
|
+
setIsLoading(true);
|
|
68170
|
+
setError(null);
|
|
68171
|
+
try {
|
|
68172
|
+
let fetchedTimezone = defaultTimezone;
|
|
68173
|
+
if (options.lineId) {
|
|
68174
|
+
fetchedTimezone = await timezoneService.getTimezoneForLine(options.lineId, defaultTimezone);
|
|
68175
|
+
} else if (options.workspaceId || workspaceConfig && "id" in workspaceConfig) {
|
|
68176
|
+
const wsId = options.workspaceId || (workspaceConfig && "id" in workspaceConfig ? workspaceConfig.id : void 0);
|
|
68177
|
+
if (wsId) {
|
|
68178
|
+
fetchedTimezone = await timezoneService.getTimezoneForWorkspace(wsId, defaultTimezone);
|
|
68179
|
+
}
|
|
68180
|
+
} else if (options.companyId || dashboardConfig && "company" in dashboardConfig) {
|
|
68181
|
+
const compId = options.companyId || (dashboardConfig && "company" in dashboardConfig ? dashboardConfig.company?.id : void 0);
|
|
68182
|
+
if (compId) {
|
|
68183
|
+
fetchedTimezone = await timezoneService.getTimezoneForCompany(compId, defaultTimezone);
|
|
68184
|
+
}
|
|
68185
|
+
}
|
|
68186
|
+
setTimezone(fetchedTimezone);
|
|
68187
|
+
} catch (err) {
|
|
68188
|
+
console.error("Error fetching timezone:", err);
|
|
68189
|
+
setError(err instanceof Error ? err : new Error("Failed to fetch timezone"));
|
|
68190
|
+
setTimezone(defaultTimezone);
|
|
68191
|
+
} finally {
|
|
68192
|
+
setIsLoading(false);
|
|
68193
|
+
}
|
|
68194
|
+
}, [
|
|
68195
|
+
options.lineId,
|
|
68196
|
+
options.workspaceId,
|
|
68197
|
+
options.companyId,
|
|
68198
|
+
workspaceConfig,
|
|
68199
|
+
dashboardConfig,
|
|
68200
|
+
defaultTimezone
|
|
68201
|
+
]);
|
|
68202
|
+
useEffect(() => {
|
|
68203
|
+
fetchTimezone();
|
|
68204
|
+
}, [fetchTimezone]);
|
|
68205
|
+
return {
|
|
68206
|
+
timezone,
|
|
68207
|
+
isLoading,
|
|
68208
|
+
error,
|
|
68209
|
+
refetch: fetchTimezone
|
|
68210
|
+
};
|
|
68211
|
+
}
|
|
68025
68212
|
|
|
68026
68213
|
// src/views/workspace-detail-view.utils.ts
|
|
68214
|
+
var getWorkspaceCycleTimePresentation = ({
|
|
68215
|
+
workspace,
|
|
68216
|
+
showCycleTimeChart
|
|
68217
|
+
}) => {
|
|
68218
|
+
if (workspace?.monitoring_mode === "uptime") {
|
|
68219
|
+
return "output";
|
|
68220
|
+
}
|
|
68221
|
+
if (showCycleTimeChart === false) {
|
|
68222
|
+
return "output";
|
|
68223
|
+
}
|
|
68224
|
+
if (!shouldUseAssemblyCycleTimeLayout(workspace)) {
|
|
68225
|
+
return "output";
|
|
68226
|
+
}
|
|
68227
|
+
return workspace?.cycle_time_data_status === "missing_clips" ? "cycle_unavailable" : "cycle_chart";
|
|
68228
|
+
};
|
|
68027
68229
|
var formatDateInTimezone = (date = /* @__PURE__ */ new Date(), timezone, options) => {
|
|
68028
68230
|
const defaultOptions = {
|
|
68029
68231
|
day: "numeric",
|
|
@@ -68407,6 +68609,7 @@ var WorkspaceDetailView = ({
|
|
|
68407
68609
|
date: cachedOverviewMetrics.date,
|
|
68408
68610
|
shift_id: cachedOverviewMetrics.shift_id,
|
|
68409
68611
|
action_name: "",
|
|
68612
|
+
action_family: cachedOverviewMetrics.action_family ?? null,
|
|
68410
68613
|
action_type: cachedOverviewMetrics.action_type ?? null,
|
|
68411
68614
|
monitoring_mode: cachedOverviewMetrics.monitoring_mode ?? "output",
|
|
68412
68615
|
shift_start: shiftDefinition?.startTime || "",
|
|
@@ -68430,6 +68633,11 @@ var WorkspaceDetailView = ({
|
|
|
68430
68633
|
};
|
|
68431
68634
|
}, [cachedOverviewMetrics, shiftConfig?.shifts]);
|
|
68432
68635
|
const workspace = (isHistoricView ? historicMetrics : liveMetrics) || cachedDetailedMetrics || overviewFallback;
|
|
68636
|
+
const { timezone: cycleTimeTimezone } = useTimezone({
|
|
68637
|
+
lineId: effectiveLineId || workspace?.line_id || void 0,
|
|
68638
|
+
workspaceId: workspaceId || void 0
|
|
68639
|
+
});
|
|
68640
|
+
const effectiveCycleTimeTimezone = cycleTimeTimezone || timezone;
|
|
68433
68641
|
const detailedWorkspaceMetrics = (isHistoricView ? historicMetrics : liveMetrics) || cachedDetailedMetrics;
|
|
68434
68642
|
const cycleTimeChartData = useMemo(
|
|
68435
68643
|
() => Array.isArray(workspace?.hourly_cycle_times) ? workspace.hourly_cycle_times.map((value) => {
|
|
@@ -68438,12 +68646,31 @@ var WorkspaceDetailView = ({
|
|
|
68438
68646
|
}) : [],
|
|
68439
68647
|
[workspace?.hourly_cycle_times]
|
|
68440
68648
|
);
|
|
68649
|
+
const maskedCycleTimeChartData = useMemo(
|
|
68650
|
+
() => maskFutureHourlySeries({
|
|
68651
|
+
data: cycleTimeChartData,
|
|
68652
|
+
shiftStart: workspace?.shift_start,
|
|
68653
|
+
shiftEnd: workspace?.shift_end,
|
|
68654
|
+
shiftDate: workspace?.date || date || calculatedOperationalDate || null,
|
|
68655
|
+
timezone: effectiveCycleTimeTimezone
|
|
68656
|
+
}),
|
|
68657
|
+
[
|
|
68658
|
+
cycleTimeChartData,
|
|
68659
|
+
workspace?.shift_start,
|
|
68660
|
+
workspace?.shift_end,
|
|
68661
|
+
workspace?.date,
|
|
68662
|
+
date,
|
|
68663
|
+
calculatedOperationalDate,
|
|
68664
|
+
effectiveCycleTimeTimezone
|
|
68665
|
+
]
|
|
68666
|
+
);
|
|
68441
68667
|
const cycleTimeDatasetKey = useMemo(
|
|
68442
68668
|
() => [
|
|
68443
68669
|
workspace?.workspace_id || workspaceId || "workspace",
|
|
68444
68670
|
date || workspace?.date || "live",
|
|
68445
68671
|
parsedShiftId ?? workspace?.shift_id ?? "current",
|
|
68446
|
-
"hourly"
|
|
68672
|
+
"hourly",
|
|
68673
|
+
"backend"
|
|
68447
68674
|
].join(":"),
|
|
68448
68675
|
[workspace?.workspace_id, workspaceId, date, workspace?.date, parsedShiftId, workspace?.shift_id]
|
|
68449
68676
|
);
|
|
@@ -68688,14 +68915,28 @@ var WorkspaceDetailView = ({
|
|
|
68688
68915
|
return filterDataByDateKeyRange(monthlyData, range);
|
|
68689
68916
|
}, [monthlyData, range]);
|
|
68690
68917
|
const formattedWorkspaceName = displayName || formatWorkspaceName3(workspace?.workspace_name || "", effectiveLineId);
|
|
68691
|
-
const
|
|
68692
|
-
|
|
68693
|
-
|
|
68694
|
-
|
|
68918
|
+
const workspaceCycleTimeEligibility = workspace ? {
|
|
68919
|
+
line_assembly_enabled: workspace.line_assembly_enabled,
|
|
68920
|
+
action_family: workspace.action_family,
|
|
68921
|
+
action_type: workspace.action_type
|
|
68922
|
+
} : null;
|
|
68923
|
+
const isAssemblyWorkspace = shouldUseAssemblyCycleTimeLayout(workspaceCycleTimeEligibility);
|
|
68924
|
+
const cycleTimePresentation = getWorkspaceCycleTimePresentation({
|
|
68925
|
+
workspace: workspace ? {
|
|
68926
|
+
monitoring_mode: workspace.monitoring_mode,
|
|
68927
|
+
line_assembly_enabled: workspace.line_assembly_enabled,
|
|
68928
|
+
action_family: workspace.action_family,
|
|
68929
|
+
action_type: workspace.action_type,
|
|
68930
|
+
cycle_time_data_status: workspace.cycle_time_data_status
|
|
68931
|
+
} : null,
|
|
68932
|
+
showCycleTimeChart
|
|
68933
|
+
});
|
|
68934
|
+
const shouldShowCycleTimeChart = cycleTimePresentation !== "output";
|
|
68935
|
+
const shouldShowCycleTimeUnavailableState = cycleTimePresentation === "cycle_unavailable";
|
|
68695
68936
|
const showIdleBreakdownChart = !shouldShowCycleTimeChart && idleTimeVlmEnabled;
|
|
68696
68937
|
const idleClipDate = date || workspace?.date || calculatedOperationalDate || getOperationalDate(timezone);
|
|
68697
68938
|
const idleClipShiftId = parsedShiftId ?? workspace?.shift_id;
|
|
68698
|
-
const
|
|
68939
|
+
const rawHourlyIdleMinutes = useMemo(() => {
|
|
68699
68940
|
if (!shouldShowCycleTimeChart || !workspace?.idle_time_hourly || !workspace?.shift_start) return [];
|
|
68700
68941
|
const parseTimeToMinutes3 = (time2) => {
|
|
68701
68942
|
const [h, m] = time2.split(":").map(Number);
|
|
@@ -68729,6 +68970,30 @@ var WorkspaceDetailView = ({
|
|
|
68729
68970
|
}
|
|
68730
68971
|
return result;
|
|
68731
68972
|
}, [shouldShowCycleTimeChart, workspace?.idle_time_hourly, workspace?.shift_start, workspace?.shift_end]);
|
|
68973
|
+
const hourlyIdleMinutes = useMemo(
|
|
68974
|
+
() => maskFutureHourlySeries({
|
|
68975
|
+
data: rawHourlyIdleMinutes,
|
|
68976
|
+
shiftStart: workspace?.shift_start,
|
|
68977
|
+
shiftEnd: workspace?.shift_end,
|
|
68978
|
+
shiftDate: idleClipDate,
|
|
68979
|
+
timezone: effectiveCycleTimeTimezone
|
|
68980
|
+
}),
|
|
68981
|
+
[
|
|
68982
|
+
rawHourlyIdleMinutes,
|
|
68983
|
+
workspace?.shift_start,
|
|
68984
|
+
workspace?.shift_end,
|
|
68985
|
+
idleClipDate,
|
|
68986
|
+
effectiveCycleTimeTimezone
|
|
68987
|
+
]
|
|
68988
|
+
);
|
|
68989
|
+
const cycleTimeUnavailableView = useMemo(() => /* @__PURE__ */ jsxs("div", { className: "w-full h-full rounded-lg border border-amber-200 bg-amber-50/70 px-6 py-5 text-center flex flex-col items-center justify-center", children: [
|
|
68990
|
+
/* @__PURE__ */ jsx("h4", { className: "text-base font-semibold text-amber-900", children: "Cycle data unavailable" }),
|
|
68991
|
+
/* @__PURE__ */ jsx("p", { className: "mt-2 max-w-md text-sm text-amber-800", children: "This workstation has cycle-time metrics for the selected shift, but no matching `cycle_completion` clips were found for the chart." }),
|
|
68992
|
+
typeof workspace?.cycle_completion_clip_count === "number" && /* @__PURE__ */ jsxs("p", { className: "mt-3 text-xs font-medium uppercase tracking-[0.08em] text-amber-700", children: [
|
|
68993
|
+
"matched cycle clips: ",
|
|
68994
|
+
workspace.cycle_completion_clip_count
|
|
68995
|
+
] })
|
|
68996
|
+
] }), [workspace?.cycle_completion_clip_count]);
|
|
68732
68997
|
const shiftDurationMinutes = useMemo(
|
|
68733
68998
|
() => getShiftDurationMinutes(workspace?.shift_start, workspace?.shift_end),
|
|
68734
68999
|
[workspace?.shift_start, workspace?.shift_end]
|
|
@@ -69225,7 +69490,7 @@ var WorkspaceDetailView = ({
|
|
|
69225
69490
|
children: [
|
|
69226
69491
|
/* @__PURE__ */ jsxs("div", { className: "flex justify-between items-center mb-4", children: [
|
|
69227
69492
|
/* @__PURE__ */ jsx("h3", { className: "text-lg font-bold text-gray-700", children: isUptimeMode ? "Machine Utilization" : shouldShowCycleTimeChart ? "Cycle time trend" : "Hourly Output" }),
|
|
69228
|
-
!isUptimeMode && /* @__PURE__ */ jsx(
|
|
69493
|
+
!isUptimeMode && !shouldShowCycleTimeUnavailableState && /* @__PURE__ */ jsx(
|
|
69229
69494
|
"button",
|
|
69230
69495
|
{
|
|
69231
69496
|
onClick: () => setShowChartIdleTime(!showChartIdleTime),
|
|
@@ -69254,10 +69519,10 @@ var WorkspaceDetailView = ({
|
|
|
69254
69519
|
timezone,
|
|
69255
69520
|
elapsedMinutes: elapsedShiftMinutes
|
|
69256
69521
|
}
|
|
69257
|
-
) : shouldShowCycleTimeChart ? /* @__PURE__ */ jsx(
|
|
69522
|
+
) : shouldShowCycleTimeUnavailableState ? cycleTimeUnavailableView : shouldShowCycleTimeChart ? /* @__PURE__ */ jsx(
|
|
69258
69523
|
CycleTimeOverTimeChart,
|
|
69259
69524
|
{
|
|
69260
|
-
data:
|
|
69525
|
+
data: maskedCycleTimeChartData,
|
|
69261
69526
|
idealCycleTime: workspace.ideal_cycle_time || 0,
|
|
69262
69527
|
shiftStart: workspace.shift_start || "",
|
|
69263
69528
|
shiftEnd: workspace.shift_end || "",
|
|
@@ -69358,7 +69623,7 @@ var WorkspaceDetailView = ({
|
|
|
69358
69623
|
children: [
|
|
69359
69624
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3 mb-4 flex-none", children: [
|
|
69360
69625
|
/* @__PURE__ */ jsx("h3", { className: "text-lg font-bold text-gray-700", children: isUptimeMode ? "Machine Utilization" : shouldShowCycleTimeChart ? "Cycle time trend" : "Hourly Output" }),
|
|
69361
|
-
!isUptimeMode && /* @__PURE__ */ jsx(
|
|
69626
|
+
!isUptimeMode && !shouldShowCycleTimeUnavailableState && /* @__PURE__ */ jsx(
|
|
69362
69627
|
"button",
|
|
69363
69628
|
{
|
|
69364
69629
|
onClick: () => setShowChartIdleTime(!showChartIdleTime),
|
|
@@ -69383,10 +69648,10 @@ var WorkspaceDetailView = ({
|
|
|
69383
69648
|
timezone,
|
|
69384
69649
|
elapsedMinutes: elapsedShiftMinutes
|
|
69385
69650
|
}
|
|
69386
|
-
) : shouldShowCycleTimeChart ? /* @__PURE__ */ jsx(
|
|
69651
|
+
) : shouldShowCycleTimeUnavailableState ? cycleTimeUnavailableView : shouldShowCycleTimeChart ? /* @__PURE__ */ jsx(
|
|
69387
69652
|
CycleTimeOverTimeChart,
|
|
69388
69653
|
{
|
|
69389
|
-
data:
|
|
69654
|
+
data: maskedCycleTimeChartData,
|
|
69390
69655
|
idealCycleTime: workspace.ideal_cycle_time || 0,
|
|
69391
69656
|
shiftStart: workspace.shift_start || "",
|
|
69392
69657
|
shiftEnd: workspace.shift_end || "",
|