@optifye/dashboard-core 6.11.14 → 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 +10 -0
- package/dist/index.d.mts +12 -2
- package/dist/index.d.ts +12 -2
- package/dist/index.js +349 -96
- package/dist/index.mjs +349 -96
- package/package.json +1 -1
package/dist/index.css
CHANGED
|
@@ -2639,6 +2639,9 @@ body {
|
|
|
2639
2639
|
--tw-bg-opacity: 1;
|
|
2640
2640
|
background-color: rgb(255 251 235 / var(--tw-bg-opacity, 1));
|
|
2641
2641
|
}
|
|
2642
|
+
.bg-amber-50\/70 {
|
|
2643
|
+
background-color: rgb(255 251 235 / 0.7);
|
|
2644
|
+
}
|
|
2642
2645
|
.bg-amber-500 {
|
|
2643
2646
|
--tw-bg-opacity: 1;
|
|
2644
2647
|
background-color: rgb(245 158 11 / var(--tw-bg-opacity, 1));
|
|
@@ -4253,6 +4256,9 @@ body {
|
|
|
4253
4256
|
.tracking-\[0\.05em\] {
|
|
4254
4257
|
letter-spacing: 0.05em;
|
|
4255
4258
|
}
|
|
4259
|
+
.tracking-\[0\.08em\] {
|
|
4260
|
+
letter-spacing: 0.08em;
|
|
4261
|
+
}
|
|
4256
4262
|
.tracking-\[0\.25em\] {
|
|
4257
4263
|
letter-spacing: 0.25em;
|
|
4258
4264
|
}
|
|
@@ -4369,6 +4375,10 @@ body {
|
|
|
4369
4375
|
--tw-text-opacity: 1;
|
|
4370
4376
|
color: rgb(146 64 14 / var(--tw-text-opacity, 1));
|
|
4371
4377
|
}
|
|
4378
|
+
.text-amber-900 {
|
|
4379
|
+
--tw-text-opacity: 1;
|
|
4380
|
+
color: rgb(120 53 15 / var(--tw-text-opacity, 1));
|
|
4381
|
+
}
|
|
4372
4382
|
.text-blue-300 {
|
|
4373
4383
|
--tw-text-opacity: 1;
|
|
4374
4384
|
color: rgb(147 197 253 / var(--tw-text-opacity, 1));
|
package/dist/index.d.mts
CHANGED
|
@@ -124,6 +124,9 @@ interface WorkspaceDetailedMetrics {
|
|
|
124
124
|
total_actions: number;
|
|
125
125
|
hourly_action_counts: number[];
|
|
126
126
|
hourly_cycle_times?: number[];
|
|
127
|
+
cycle_completion_clip_count?: number | null;
|
|
128
|
+
cycle_time_data_status?: 'available' | 'missing_clips' | null;
|
|
129
|
+
cycle_time_timezone?: string | null;
|
|
127
130
|
workspace_rank: number;
|
|
128
131
|
total_workspaces: number;
|
|
129
132
|
ideal_output_until_now: number;
|
|
@@ -2832,6 +2835,7 @@ interface HistoricWorkspaceMetrics {
|
|
|
2832
2835
|
workspace_name: string;
|
|
2833
2836
|
line_id: string;
|
|
2834
2837
|
line_name: string;
|
|
2838
|
+
line_assembly_enabled?: boolean;
|
|
2835
2839
|
company_id: string;
|
|
2836
2840
|
company_name: string;
|
|
2837
2841
|
date: string;
|
|
@@ -2852,9 +2856,15 @@ interface HistoricWorkspaceMetrics {
|
|
|
2852
2856
|
idle_time_hourly?: Record<string, string[]>;
|
|
2853
2857
|
hourly_action_counts: number[];
|
|
2854
2858
|
hourly_cycle_times?: number[];
|
|
2859
|
+
cycle_completion_clip_count?: number | null;
|
|
2860
|
+
cycle_time_data_status?: 'available' | 'missing_clips' | null;
|
|
2861
|
+
cycle_time_timezone?: string | null;
|
|
2855
2862
|
shift_start: string;
|
|
2856
2863
|
shift_end: string;
|
|
2857
2864
|
action_name: string;
|
|
2865
|
+
action_type?: 'assembly' | 'output' | null;
|
|
2866
|
+
action_family?: 'assembly' | 'output' | 'other' | null;
|
|
2867
|
+
action_display_name?: string | null;
|
|
2858
2868
|
monitoring_mode?: 'output' | 'uptime';
|
|
2859
2869
|
workspace_rank: number;
|
|
2860
2870
|
total_workspaces: number;
|
|
@@ -7193,7 +7203,7 @@ interface CycleTimeChartProps {
|
|
|
7193
7203
|
declare const CycleTimeChart: React__default.NamedExoticComponent<CycleTimeChartProps>;
|
|
7194
7204
|
|
|
7195
7205
|
interface CycleTimeOverTimeChartProps {
|
|
7196
|
-
data: number
|
|
7206
|
+
data: Array<number | null>;
|
|
7197
7207
|
idealCycleTime: number;
|
|
7198
7208
|
shiftStart: string;
|
|
7199
7209
|
shiftEnd?: string;
|
|
@@ -7201,7 +7211,7 @@ interface CycleTimeOverTimeChartProps {
|
|
|
7201
7211
|
datasetKey?: string;
|
|
7202
7212
|
className?: string;
|
|
7203
7213
|
showIdleTime?: boolean;
|
|
7204
|
-
idleTimeData?: number
|
|
7214
|
+
idleTimeData?: Array<number | null>;
|
|
7205
7215
|
}
|
|
7206
7216
|
declare const CycleTimeOverTimeChart: React__default.FC<CycleTimeOverTimeChartProps>;
|
|
7207
7217
|
|
package/dist/index.d.ts
CHANGED
|
@@ -124,6 +124,9 @@ interface WorkspaceDetailedMetrics {
|
|
|
124
124
|
total_actions: number;
|
|
125
125
|
hourly_action_counts: number[];
|
|
126
126
|
hourly_cycle_times?: number[];
|
|
127
|
+
cycle_completion_clip_count?: number | null;
|
|
128
|
+
cycle_time_data_status?: 'available' | 'missing_clips' | null;
|
|
129
|
+
cycle_time_timezone?: string | null;
|
|
127
130
|
workspace_rank: number;
|
|
128
131
|
total_workspaces: number;
|
|
129
132
|
ideal_output_until_now: number;
|
|
@@ -2832,6 +2835,7 @@ interface HistoricWorkspaceMetrics {
|
|
|
2832
2835
|
workspace_name: string;
|
|
2833
2836
|
line_id: string;
|
|
2834
2837
|
line_name: string;
|
|
2838
|
+
line_assembly_enabled?: boolean;
|
|
2835
2839
|
company_id: string;
|
|
2836
2840
|
company_name: string;
|
|
2837
2841
|
date: string;
|
|
@@ -2852,9 +2856,15 @@ interface HistoricWorkspaceMetrics {
|
|
|
2852
2856
|
idle_time_hourly?: Record<string, string[]>;
|
|
2853
2857
|
hourly_action_counts: number[];
|
|
2854
2858
|
hourly_cycle_times?: number[];
|
|
2859
|
+
cycle_completion_clip_count?: number | null;
|
|
2860
|
+
cycle_time_data_status?: 'available' | 'missing_clips' | null;
|
|
2861
|
+
cycle_time_timezone?: string | null;
|
|
2855
2862
|
shift_start: string;
|
|
2856
2863
|
shift_end: string;
|
|
2857
2864
|
action_name: string;
|
|
2865
|
+
action_type?: 'assembly' | 'output' | null;
|
|
2866
|
+
action_family?: 'assembly' | 'output' | 'other' | null;
|
|
2867
|
+
action_display_name?: string | null;
|
|
2858
2868
|
monitoring_mode?: 'output' | 'uptime';
|
|
2859
2869
|
workspace_rank: number;
|
|
2860
2870
|
total_workspaces: number;
|
|
@@ -7193,7 +7203,7 @@ interface CycleTimeChartProps {
|
|
|
7193
7203
|
declare const CycleTimeChart: React__default.NamedExoticComponent<CycleTimeChartProps>;
|
|
7194
7204
|
|
|
7195
7205
|
interface CycleTimeOverTimeChartProps {
|
|
7196
|
-
data: number
|
|
7206
|
+
data: Array<number | null>;
|
|
7197
7207
|
idealCycleTime: number;
|
|
7198
7208
|
shiftStart: string;
|
|
7199
7209
|
shiftEnd?: string;
|
|
@@ -7201,7 +7211,7 @@ interface CycleTimeOverTimeChartProps {
|
|
|
7201
7211
|
datasetKey?: string;
|
|
7202
7212
|
className?: string;
|
|
7203
7213
|
showIdleTime?: boolean;
|
|
7204
|
-
idleTimeData?: number
|
|
7214
|
+
idleTimeData?: Array<number | null>;
|
|
7205
7215
|
}
|
|
7206
7216
|
declare const CycleTimeOverTimeChart: React__default.FC<CycleTimeOverTimeChartProps>;
|
|
7207
7217
|
|
package/dist/index.js
CHANGED
|
@@ -11771,6 +11771,9 @@ var toWorkspaceDetailedMetrics = ({
|
|
|
11771
11771
|
const idealOutput = coerceNumber(data.ideal_output ?? data.ideal_output_until_now, 0);
|
|
11772
11772
|
const outputDifference = totalActions - idealOutput;
|
|
11773
11773
|
const hourlyCycleTimes = Array.isArray(data.hourly_cycle_times) ? data.hourly_cycle_times.map((value) => coerceNumber(value, 0)) : [];
|
|
11774
|
+
const cycleCompletionClipCount = data.cycle_completion_clip_count === null || data.cycle_completion_clip_count === void 0 ? null : coerceNumber(data.cycle_completion_clip_count, 0);
|
|
11775
|
+
const cycleTimeDataStatus = data.cycle_time_data_status === "missing_clips" ? "missing_clips" : data.cycle_time_data_status === "available" ? "available" : null;
|
|
11776
|
+
const cycleTimeTimezone = typeof data.cycle_time_timezone === "string" ? data.cycle_time_timezone : null;
|
|
11774
11777
|
const totalWorkspacesValue = coerceNumber(
|
|
11775
11778
|
data.total_workspaces ?? lineMetricsById?.[data.line_id || ""]?.total_workspaces ?? workspaceConfig.totalWorkspaces,
|
|
11776
11779
|
0
|
|
@@ -11818,6 +11821,9 @@ var toWorkspaceDetailedMetrics = ({
|
|
|
11818
11821
|
total_actions: totalActions,
|
|
11819
11822
|
hourly_action_counts: hourlyActionCounts,
|
|
11820
11823
|
hourly_cycle_times: hourlyCycleTimes,
|
|
11824
|
+
cycle_completion_clip_count: cycleCompletionClipCount,
|
|
11825
|
+
cycle_time_data_status: cycleTimeDataStatus,
|
|
11826
|
+
cycle_time_timezone: cycleTimeTimezone,
|
|
11821
11827
|
workspace_rank: coerceNumber(data.workspace_rank, 0),
|
|
11822
11828
|
total_workspaces: totalWorkspacesValue,
|
|
11823
11829
|
ideal_output_until_now: idealOutput,
|
|
@@ -32698,16 +32704,162 @@ var CycleTimeOverTimeChart = ({
|
|
|
32698
32704
|
return `${minutes} minutes ${seconds} seconds ago`;
|
|
32699
32705
|
}
|
|
32700
32706
|
};
|
|
32707
|
+
const getNumericValue = React141__namespace.default.useCallback((value) => typeof value === "number" && Number.isFinite(value) ? value : null, []);
|
|
32708
|
+
const renderChartTooltip = React141__namespace.default.useCallback((tooltipProps) => {
|
|
32709
|
+
const { active, payload } = tooltipProps;
|
|
32710
|
+
if (!active || !Array.isArray(payload) || payload.length === 0) {
|
|
32711
|
+
return null;
|
|
32712
|
+
}
|
|
32713
|
+
const visibleEntries = payload.filter((entry) => getNumericValue(entry.value) !== null);
|
|
32714
|
+
if (!visibleEntries.length) {
|
|
32715
|
+
return null;
|
|
32716
|
+
}
|
|
32717
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
32718
|
+
"div",
|
|
32719
|
+
{
|
|
32720
|
+
style: {
|
|
32721
|
+
backgroundColor: "white",
|
|
32722
|
+
border: "none",
|
|
32723
|
+
borderRadius: "8px",
|
|
32724
|
+
boxShadow: "0 4px 12px rgba(0,0,0,0.1)",
|
|
32725
|
+
padding: "8px 12px",
|
|
32726
|
+
fontSize: "13px"
|
|
32727
|
+
},
|
|
32728
|
+
children: [
|
|
32729
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
32730
|
+
"div",
|
|
32731
|
+
{
|
|
32732
|
+
style: {
|
|
32733
|
+
color: "#374151",
|
|
32734
|
+
fontWeight: 600,
|
|
32735
|
+
marginBottom: "4px"
|
|
32736
|
+
},
|
|
32737
|
+
children: payload[0]?.payload?.tooltip || ""
|
|
32738
|
+
}
|
|
32739
|
+
),
|
|
32740
|
+
visibleEntries.map((entry) => {
|
|
32741
|
+
const numericValue = getNumericValue(entry.value);
|
|
32742
|
+
if (numericValue === null) {
|
|
32743
|
+
return null;
|
|
32744
|
+
}
|
|
32745
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
32746
|
+
"div",
|
|
32747
|
+
{
|
|
32748
|
+
style: {
|
|
32749
|
+
color: "#4B5563",
|
|
32750
|
+
padding: "2px 0"
|
|
32751
|
+
},
|
|
32752
|
+
children: entry.name === "idleMinutes" ? `Idle Time: ${numericValue.toFixed(0)} minutes` : `Cycle Time: ${numericValue.toFixed(1)} seconds`
|
|
32753
|
+
},
|
|
32754
|
+
`${entry.name}-${numericValue}`
|
|
32755
|
+
);
|
|
32756
|
+
})
|
|
32757
|
+
]
|
|
32758
|
+
}
|
|
32759
|
+
);
|
|
32760
|
+
}, [getNumericValue]);
|
|
32761
|
+
const renderCycleDot = React141__namespace.default.useCallback((props) => {
|
|
32762
|
+
const { cx: cx2, cy, payload } = props;
|
|
32763
|
+
const cycleTime = getNumericValue(payload?.cycleTime);
|
|
32764
|
+
if (cycleTime === null) {
|
|
32765
|
+
return /* @__PURE__ */ jsxRuntime.jsx("g", {});
|
|
32766
|
+
}
|
|
32767
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
32768
|
+
"circle",
|
|
32769
|
+
{
|
|
32770
|
+
cx: cx2,
|
|
32771
|
+
cy,
|
|
32772
|
+
r: 4,
|
|
32773
|
+
fill: cycleTime <= idealCycleTime ? "#00AB45" : "#E34329",
|
|
32774
|
+
stroke: "#fff",
|
|
32775
|
+
strokeWidth: 1,
|
|
32776
|
+
style: {
|
|
32777
|
+
filter: "brightness(1)",
|
|
32778
|
+
transition: "filter 0.3s ease, transform 0.3s ease",
|
|
32779
|
+
cursor: "pointer"
|
|
32780
|
+
},
|
|
32781
|
+
onMouseEnter: (e) => {
|
|
32782
|
+
const target = e.target;
|
|
32783
|
+
target.style.filter = "brightness(1.2)";
|
|
32784
|
+
target.style.transform = "scale(1.2)";
|
|
32785
|
+
},
|
|
32786
|
+
onMouseLeave: (e) => {
|
|
32787
|
+
const target = e.target;
|
|
32788
|
+
target.style.filter = "brightness(1)";
|
|
32789
|
+
target.style.transform = "scale(1)";
|
|
32790
|
+
}
|
|
32791
|
+
}
|
|
32792
|
+
);
|
|
32793
|
+
}, [getNumericValue, idealCycleTime]);
|
|
32794
|
+
const renderCycleActiveDot = React141__namespace.default.useCallback((props) => {
|
|
32795
|
+
const { cx: cx2, cy, payload } = props;
|
|
32796
|
+
const cycleTime = getNumericValue(payload?.cycleTime);
|
|
32797
|
+
if (cycleTime === null) {
|
|
32798
|
+
return /* @__PURE__ */ jsxRuntime.jsx("g", {});
|
|
32799
|
+
}
|
|
32800
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
32801
|
+
"circle",
|
|
32802
|
+
{
|
|
32803
|
+
cx: cx2,
|
|
32804
|
+
cy,
|
|
32805
|
+
r: 6,
|
|
32806
|
+
fill: cycleTime <= idealCycleTime ? "#00AB45" : "#E34329",
|
|
32807
|
+
stroke: "#fff",
|
|
32808
|
+
strokeWidth: 2,
|
|
32809
|
+
style: {
|
|
32810
|
+
filter: "drop-shadow(0 0 2px rgba(0,0,0,0.2))"
|
|
32811
|
+
}
|
|
32812
|
+
}
|
|
32813
|
+
);
|
|
32814
|
+
}, [getNumericValue, idealCycleTime]);
|
|
32815
|
+
const renderIdleDot = React141__namespace.default.useCallback((props) => {
|
|
32816
|
+
const { cx: cx2, cy, payload } = props;
|
|
32817
|
+
const idleMinutes = getNumericValue(payload?.idleMinutes);
|
|
32818
|
+
if (idleMinutes === null) {
|
|
32819
|
+
return /* @__PURE__ */ jsxRuntime.jsx("g", {});
|
|
32820
|
+
}
|
|
32821
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
32822
|
+
"circle",
|
|
32823
|
+
{
|
|
32824
|
+
cx: cx2,
|
|
32825
|
+
cy,
|
|
32826
|
+
r: 4,
|
|
32827
|
+
fill: "#f59e0b",
|
|
32828
|
+
stroke: "#fff",
|
|
32829
|
+
strokeWidth: 1
|
|
32830
|
+
}
|
|
32831
|
+
);
|
|
32832
|
+
}, [getNumericValue]);
|
|
32833
|
+
const renderIdleActiveDot = React141__namespace.default.useCallback((props) => {
|
|
32834
|
+
const { cx: cx2, cy, payload } = props;
|
|
32835
|
+
const idleMinutes = getNumericValue(payload?.idleMinutes);
|
|
32836
|
+
if (idleMinutes === null) {
|
|
32837
|
+
return /* @__PURE__ */ jsxRuntime.jsx("g", {});
|
|
32838
|
+
}
|
|
32839
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
32840
|
+
"circle",
|
|
32841
|
+
{
|
|
32842
|
+
cx: cx2,
|
|
32843
|
+
cy,
|
|
32844
|
+
r: 6,
|
|
32845
|
+
fill: "#f59e0b",
|
|
32846
|
+
stroke: "#fff",
|
|
32847
|
+
strokeWidth: 2
|
|
32848
|
+
}
|
|
32849
|
+
);
|
|
32850
|
+
}, [getNumericValue]);
|
|
32701
32851
|
const chartData = React141__namespace.default.useMemo(() => Array.from({ length: DURATION }, (_, i) => {
|
|
32852
|
+
const cycleTime = getNumericValue(finalData[i]);
|
|
32853
|
+
const idleMinutes = showIdleTime ? getNumericValue(idleTimeData[i]) : null;
|
|
32702
32854
|
return {
|
|
32703
32855
|
timeIndex: i,
|
|
32704
32856
|
label: formatTimeLabel(i),
|
|
32705
32857
|
tooltip: formatTooltipTime(i),
|
|
32706
|
-
cycleTime
|
|
32707
|
-
idleMinutes
|
|
32708
|
-
color:
|
|
32858
|
+
cycleTime,
|
|
32859
|
+
idleMinutes,
|
|
32860
|
+
color: cycleTime !== null && cycleTime <= idealCycleTime ? "#00AB45" : "#E34329"
|
|
32709
32861
|
};
|
|
32710
|
-
}), [DURATION, finalData, showIdleTime, idleTimeData, idealCycleTime]);
|
|
32862
|
+
}), [DURATION, finalData, showIdleTime, idleTimeData, idealCycleTime, getNumericValue]);
|
|
32711
32863
|
const renderLegend = () => {
|
|
32712
32864
|
if (!showIdleTime) return null;
|
|
32713
32865
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-start text-[10px] font-bold text-gray-500 mb-6 tracking-[0.05em] gap-5", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
@@ -32794,36 +32946,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
32794
32946
|
recharts.Tooltip,
|
|
32795
32947
|
{
|
|
32796
32948
|
cursor: { stroke: "#E5E7EB", strokeWidth: 1 },
|
|
32797
|
-
|
|
32798
|
-
backgroundColor: "white",
|
|
32799
|
-
border: "none",
|
|
32800
|
-
borderRadius: "8px",
|
|
32801
|
-
boxShadow: "0 4px 12px rgba(0,0,0,0.1)",
|
|
32802
|
-
padding: "8px 12px",
|
|
32803
|
-
fontSize: "13px"
|
|
32804
|
-
},
|
|
32805
|
-
labelStyle: {
|
|
32806
|
-
color: "#374151",
|
|
32807
|
-
fontWeight: 600,
|
|
32808
|
-
marginBottom: "4px"
|
|
32809
|
-
},
|
|
32810
|
-
itemStyle: {
|
|
32811
|
-
color: "#4B5563",
|
|
32812
|
-
padding: "2px 0"
|
|
32813
|
-
},
|
|
32814
|
-
labelFormatter: (label, payload) => {
|
|
32815
|
-
if (payload && payload[0]) {
|
|
32816
|
-
return payload[0].payload.tooltip;
|
|
32817
|
-
}
|
|
32818
|
-
return label;
|
|
32819
|
-
},
|
|
32820
|
-
formatter: (value, name) => {
|
|
32821
|
-
const numValue = typeof value === "number" ? value : Number(value);
|
|
32822
|
-
if (name === "idleMinutes") {
|
|
32823
|
-
return [`${numValue.toFixed(0)} minutes`, "Idle Time"];
|
|
32824
|
-
}
|
|
32825
|
-
return [`${numValue.toFixed(1)} seconds`, "Cycle Time"];
|
|
32826
|
-
},
|
|
32949
|
+
content: renderChartTooltip,
|
|
32827
32950
|
animationDuration: 200
|
|
32828
32951
|
}
|
|
32829
32952
|
),
|
|
@@ -32852,52 +32975,9 @@ var CycleTimeOverTimeChart = ({
|
|
|
32852
32975
|
dataKey: "cycleTime",
|
|
32853
32976
|
stroke: "#3B82F6",
|
|
32854
32977
|
strokeWidth: 2,
|
|
32855
|
-
|
|
32856
|
-
|
|
32857
|
-
|
|
32858
|
-
"circle",
|
|
32859
|
-
{
|
|
32860
|
-
cx: cx2,
|
|
32861
|
-
cy,
|
|
32862
|
-
r: 4,
|
|
32863
|
-
fill: payload.cycleTime <= idealCycleTime ? "#00AB45" : "#E34329",
|
|
32864
|
-
stroke: "#fff",
|
|
32865
|
-
strokeWidth: 1,
|
|
32866
|
-
style: {
|
|
32867
|
-
filter: "brightness(1)",
|
|
32868
|
-
transition: "filter 0.3s ease, transform 0.3s ease",
|
|
32869
|
-
cursor: "pointer"
|
|
32870
|
-
},
|
|
32871
|
-
onMouseEnter: (e) => {
|
|
32872
|
-
const target = e.target;
|
|
32873
|
-
target.style.filter = "brightness(1.2)";
|
|
32874
|
-
target.style.transform = "scale(1.2)";
|
|
32875
|
-
},
|
|
32876
|
-
onMouseLeave: (e) => {
|
|
32877
|
-
const target = e.target;
|
|
32878
|
-
target.style.filter = "brightness(1)";
|
|
32879
|
-
target.style.transform = "scale(1)";
|
|
32880
|
-
}
|
|
32881
|
-
}
|
|
32882
|
-
);
|
|
32883
|
-
},
|
|
32884
|
-
activeDot: (props) => {
|
|
32885
|
-
const { cx: cx2, cy, payload } = props;
|
|
32886
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
32887
|
-
"circle",
|
|
32888
|
-
{
|
|
32889
|
-
cx: cx2,
|
|
32890
|
-
cy,
|
|
32891
|
-
r: 6,
|
|
32892
|
-
fill: payload.cycleTime <= idealCycleTime ? "#00AB45" : "#E34329",
|
|
32893
|
-
stroke: "#fff",
|
|
32894
|
-
strokeWidth: 2,
|
|
32895
|
-
style: {
|
|
32896
|
-
filter: "drop-shadow(0 0 2px rgba(0,0,0,0.2))"
|
|
32897
|
-
}
|
|
32898
|
-
}
|
|
32899
|
-
);
|
|
32900
|
-
},
|
|
32978
|
+
connectNulls: false,
|
|
32979
|
+
dot: renderCycleDot,
|
|
32980
|
+
activeDot: renderCycleActiveDot,
|
|
32901
32981
|
isAnimationActive: shouldAnimate,
|
|
32902
32982
|
animationBegin: 0,
|
|
32903
32983
|
animationDuration: 1200,
|
|
@@ -32915,8 +32995,9 @@ var CycleTimeOverTimeChart = ({
|
|
|
32915
32995
|
stroke: "#f59e0b",
|
|
32916
32996
|
strokeWidth: 2,
|
|
32917
32997
|
strokeDasharray: "4 4",
|
|
32918
|
-
|
|
32919
|
-
|
|
32998
|
+
connectNulls: false,
|
|
32999
|
+
dot: renderIdleDot,
|
|
33000
|
+
activeDot: renderIdleActiveDot,
|
|
32920
33001
|
isAnimationActive: shouldAnimate,
|
|
32921
33002
|
animationBegin: 0,
|
|
32922
33003
|
animationDuration: 1200,
|
|
@@ -34644,8 +34725,20 @@ var CardFooter2 = (props) => {
|
|
|
34644
34725
|
return /* @__PURE__ */ jsxRuntime.jsx(RegisteredCardFooter, { ...props });
|
|
34645
34726
|
};
|
|
34646
34727
|
|
|
34728
|
+
// src/lib/utils/workspaceDetailCycleTime.ts
|
|
34729
|
+
var resolveWorkspaceDetailActionFamily = (workspace) => {
|
|
34730
|
+
if (workspace?.action_family === "assembly" || workspace?.action_family === "output" || workspace?.action_family === "other") {
|
|
34731
|
+
return workspace.action_family;
|
|
34732
|
+
}
|
|
34733
|
+
if (workspace?.action_type === "assembly" || workspace?.action_type === "output") {
|
|
34734
|
+
return workspace.action_type;
|
|
34735
|
+
}
|
|
34736
|
+
return null;
|
|
34737
|
+
};
|
|
34738
|
+
var shouldUseAssemblyCycleTimeLayout = (workspace) => workspace?.line_assembly_enabled === true && resolveWorkspaceDetailActionFamily(workspace) === "assembly";
|
|
34739
|
+
|
|
34647
34740
|
// src/components/dashboard/workspace/workspaceDetailCardRules.ts
|
|
34648
|
-
var shouldHideWorkspaceEfficiencyCard = (workspace) => workspace
|
|
34741
|
+
var shouldHideWorkspaceEfficiencyCard = (workspace) => shouldUseAssemblyCycleTimeLayout(workspace);
|
|
34649
34742
|
var WorkspaceMetricCardsImpl = ({
|
|
34650
34743
|
workspace,
|
|
34651
34744
|
className,
|
|
@@ -35354,6 +35447,37 @@ var getShiftElapsedMinutes = ({
|
|
|
35354
35447
|
const elapsed = dateFns.differenceInMinutes(now4, shiftStartDate);
|
|
35355
35448
|
return Math.min(Math.max(elapsed, 0), shiftMinutes);
|
|
35356
35449
|
};
|
|
35450
|
+
var maskFutureHourlySeries = ({
|
|
35451
|
+
data,
|
|
35452
|
+
shiftStart,
|
|
35453
|
+
shiftEnd,
|
|
35454
|
+
shiftDate,
|
|
35455
|
+
timezone,
|
|
35456
|
+
now: now4 = /* @__PURE__ */ new Date()
|
|
35457
|
+
}) => {
|
|
35458
|
+
if (!Array.isArray(data)) {
|
|
35459
|
+
return [];
|
|
35460
|
+
}
|
|
35461
|
+
const normalizedData = data.map((value) => typeof value === "number" && Number.isFinite(value) ? value : null);
|
|
35462
|
+
if (!normalizedData.length) {
|
|
35463
|
+
return normalizedData;
|
|
35464
|
+
}
|
|
35465
|
+
const shiftMinutes = getShiftDurationMinutes(shiftStart, shiftEnd);
|
|
35466
|
+
const elapsedMinutes = getShiftElapsedMinutes({
|
|
35467
|
+
shiftStart,
|
|
35468
|
+
shiftEnd,
|
|
35469
|
+
shiftDate,
|
|
35470
|
+
timezone,
|
|
35471
|
+
now: now4
|
|
35472
|
+
});
|
|
35473
|
+
if (shiftMinutes === null || elapsedMinutes === null || elapsedMinutes >= shiftMinutes) {
|
|
35474
|
+
return normalizedData;
|
|
35475
|
+
}
|
|
35476
|
+
return normalizedData.map((value, index) => {
|
|
35477
|
+
const slotStartMinutes = index * 60;
|
|
35478
|
+
return slotStartMinutes > elapsedMinutes ? null : value;
|
|
35479
|
+
});
|
|
35480
|
+
};
|
|
35357
35481
|
var buildUptimeSeries = ({
|
|
35358
35482
|
idleTimeHourly,
|
|
35359
35483
|
shiftStart,
|
|
@@ -48892,7 +49016,7 @@ var WorkspacePdfGenerator = ({ workspace, className, idleTimeReasons, efficiency
|
|
|
48892
49016
|
setIsGenerating(true);
|
|
48893
49017
|
try {
|
|
48894
49018
|
const isUptimeMode = workspace.monitoring_mode === "uptime";
|
|
48895
|
-
const isAssemblyCycleMode = !isUptimeMode && workspace
|
|
49019
|
+
const isAssemblyCycleMode = !isUptimeMode && shouldUseAssemblyCycleTimeLayout(workspace);
|
|
48896
49020
|
const shiftMinutes = getShiftDurationMinutes(workspace.shift_start, workspace.shift_end);
|
|
48897
49021
|
const shiftSeconds = shiftMinutes ? shiftMinutes * 60 : 0;
|
|
48898
49022
|
const idleSeconds = Math.max(workspace.idle_time || 0, 0);
|
|
@@ -68063,8 +68187,74 @@ var TargetsView = ({
|
|
|
68063
68187
|
var TargetsViewWithDisplayNames = withAllWorkspaceDisplayNames(TargetsView);
|
|
68064
68188
|
var TargetsView_default = TargetsViewWithDisplayNames;
|
|
68065
68189
|
var AuthenticatedTargetsView = withAuth(React141__namespace.default.memo(TargetsViewWithDisplayNames));
|
|
68190
|
+
function useTimezone(options = {}) {
|
|
68191
|
+
const dashboardConfig = useDashboardConfig();
|
|
68192
|
+
const workspaceConfig = useWorkspaceConfig();
|
|
68193
|
+
const defaultTimezone = dashboardConfig?.dateTimeConfig?.defaultTimezone || "Asia/Kolkata";
|
|
68194
|
+
const [timezone, setTimezone] = React141.useState(defaultTimezone);
|
|
68195
|
+
const [isLoading, setIsLoading] = React141.useState(true);
|
|
68196
|
+
const [error, setError] = React141.useState(null);
|
|
68197
|
+
const fetchTimezone = React141.useCallback(async () => {
|
|
68198
|
+
setIsLoading(true);
|
|
68199
|
+
setError(null);
|
|
68200
|
+
try {
|
|
68201
|
+
let fetchedTimezone = defaultTimezone;
|
|
68202
|
+
if (options.lineId) {
|
|
68203
|
+
fetchedTimezone = await timezoneService.getTimezoneForLine(options.lineId, defaultTimezone);
|
|
68204
|
+
} else if (options.workspaceId || workspaceConfig && "id" in workspaceConfig) {
|
|
68205
|
+
const wsId = options.workspaceId || (workspaceConfig && "id" in workspaceConfig ? workspaceConfig.id : void 0);
|
|
68206
|
+
if (wsId) {
|
|
68207
|
+
fetchedTimezone = await timezoneService.getTimezoneForWorkspace(wsId, defaultTimezone);
|
|
68208
|
+
}
|
|
68209
|
+
} else if (options.companyId || dashboardConfig && "company" in dashboardConfig) {
|
|
68210
|
+
const compId = options.companyId || (dashboardConfig && "company" in dashboardConfig ? dashboardConfig.company?.id : void 0);
|
|
68211
|
+
if (compId) {
|
|
68212
|
+
fetchedTimezone = await timezoneService.getTimezoneForCompany(compId, defaultTimezone);
|
|
68213
|
+
}
|
|
68214
|
+
}
|
|
68215
|
+
setTimezone(fetchedTimezone);
|
|
68216
|
+
} catch (err) {
|
|
68217
|
+
console.error("Error fetching timezone:", err);
|
|
68218
|
+
setError(err instanceof Error ? err : new Error("Failed to fetch timezone"));
|
|
68219
|
+
setTimezone(defaultTimezone);
|
|
68220
|
+
} finally {
|
|
68221
|
+
setIsLoading(false);
|
|
68222
|
+
}
|
|
68223
|
+
}, [
|
|
68224
|
+
options.lineId,
|
|
68225
|
+
options.workspaceId,
|
|
68226
|
+
options.companyId,
|
|
68227
|
+
workspaceConfig,
|
|
68228
|
+
dashboardConfig,
|
|
68229
|
+
defaultTimezone
|
|
68230
|
+
]);
|
|
68231
|
+
React141.useEffect(() => {
|
|
68232
|
+
fetchTimezone();
|
|
68233
|
+
}, [fetchTimezone]);
|
|
68234
|
+
return {
|
|
68235
|
+
timezone,
|
|
68236
|
+
isLoading,
|
|
68237
|
+
error,
|
|
68238
|
+
refetch: fetchTimezone
|
|
68239
|
+
};
|
|
68240
|
+
}
|
|
68066
68241
|
|
|
68067
68242
|
// src/views/workspace-detail-view.utils.ts
|
|
68243
|
+
var getWorkspaceCycleTimePresentation = ({
|
|
68244
|
+
workspace,
|
|
68245
|
+
showCycleTimeChart
|
|
68246
|
+
}) => {
|
|
68247
|
+
if (workspace?.monitoring_mode === "uptime") {
|
|
68248
|
+
return "output";
|
|
68249
|
+
}
|
|
68250
|
+
if (showCycleTimeChart === false) {
|
|
68251
|
+
return "output";
|
|
68252
|
+
}
|
|
68253
|
+
if (!shouldUseAssemblyCycleTimeLayout(workspace)) {
|
|
68254
|
+
return "output";
|
|
68255
|
+
}
|
|
68256
|
+
return workspace?.cycle_time_data_status === "missing_clips" ? "cycle_unavailable" : "cycle_chart";
|
|
68257
|
+
};
|
|
68068
68258
|
var formatDateInTimezone = (date = /* @__PURE__ */ new Date(), timezone, options) => {
|
|
68069
68259
|
const defaultOptions = {
|
|
68070
68260
|
day: "numeric",
|
|
@@ -68448,6 +68638,7 @@ var WorkspaceDetailView = ({
|
|
|
68448
68638
|
date: cachedOverviewMetrics.date,
|
|
68449
68639
|
shift_id: cachedOverviewMetrics.shift_id,
|
|
68450
68640
|
action_name: "",
|
|
68641
|
+
action_family: cachedOverviewMetrics.action_family ?? null,
|
|
68451
68642
|
action_type: cachedOverviewMetrics.action_type ?? null,
|
|
68452
68643
|
monitoring_mode: cachedOverviewMetrics.monitoring_mode ?? "output",
|
|
68453
68644
|
shift_start: shiftDefinition?.startTime || "",
|
|
@@ -68471,6 +68662,11 @@ var WorkspaceDetailView = ({
|
|
|
68471
68662
|
};
|
|
68472
68663
|
}, [cachedOverviewMetrics, shiftConfig?.shifts]);
|
|
68473
68664
|
const workspace = (isHistoricView ? historicMetrics : liveMetrics) || cachedDetailedMetrics || overviewFallback;
|
|
68665
|
+
const { timezone: cycleTimeTimezone } = useTimezone({
|
|
68666
|
+
lineId: effectiveLineId || workspace?.line_id || void 0,
|
|
68667
|
+
workspaceId: workspaceId || void 0
|
|
68668
|
+
});
|
|
68669
|
+
const effectiveCycleTimeTimezone = cycleTimeTimezone || timezone;
|
|
68474
68670
|
const detailedWorkspaceMetrics = (isHistoricView ? historicMetrics : liveMetrics) || cachedDetailedMetrics;
|
|
68475
68671
|
const cycleTimeChartData = React141.useMemo(
|
|
68476
68672
|
() => Array.isArray(workspace?.hourly_cycle_times) ? workspace.hourly_cycle_times.map((value) => {
|
|
@@ -68479,12 +68675,31 @@ var WorkspaceDetailView = ({
|
|
|
68479
68675
|
}) : [],
|
|
68480
68676
|
[workspace?.hourly_cycle_times]
|
|
68481
68677
|
);
|
|
68678
|
+
const maskedCycleTimeChartData = React141.useMemo(
|
|
68679
|
+
() => maskFutureHourlySeries({
|
|
68680
|
+
data: cycleTimeChartData,
|
|
68681
|
+
shiftStart: workspace?.shift_start,
|
|
68682
|
+
shiftEnd: workspace?.shift_end,
|
|
68683
|
+
shiftDate: workspace?.date || date || calculatedOperationalDate || null,
|
|
68684
|
+
timezone: effectiveCycleTimeTimezone
|
|
68685
|
+
}),
|
|
68686
|
+
[
|
|
68687
|
+
cycleTimeChartData,
|
|
68688
|
+
workspace?.shift_start,
|
|
68689
|
+
workspace?.shift_end,
|
|
68690
|
+
workspace?.date,
|
|
68691
|
+
date,
|
|
68692
|
+
calculatedOperationalDate,
|
|
68693
|
+
effectiveCycleTimeTimezone
|
|
68694
|
+
]
|
|
68695
|
+
);
|
|
68482
68696
|
const cycleTimeDatasetKey = React141.useMemo(
|
|
68483
68697
|
() => [
|
|
68484
68698
|
workspace?.workspace_id || workspaceId || "workspace",
|
|
68485
68699
|
date || workspace?.date || "live",
|
|
68486
68700
|
parsedShiftId ?? workspace?.shift_id ?? "current",
|
|
68487
|
-
"hourly"
|
|
68701
|
+
"hourly",
|
|
68702
|
+
"backend"
|
|
68488
68703
|
].join(":"),
|
|
68489
68704
|
[workspace?.workspace_id, workspaceId, date, workspace?.date, parsedShiftId, workspace?.shift_id]
|
|
68490
68705
|
);
|
|
@@ -68729,14 +68944,28 @@ var WorkspaceDetailView = ({
|
|
|
68729
68944
|
return filterDataByDateKeyRange(monthlyData, range);
|
|
68730
68945
|
}, [monthlyData, range]);
|
|
68731
68946
|
const formattedWorkspaceName = displayName || formatWorkspaceName3(workspace?.workspace_name || "", effectiveLineId);
|
|
68732
|
-
const
|
|
68733
|
-
|
|
68734
|
-
|
|
68735
|
-
|
|
68947
|
+
const workspaceCycleTimeEligibility = workspace ? {
|
|
68948
|
+
line_assembly_enabled: workspace.line_assembly_enabled,
|
|
68949
|
+
action_family: workspace.action_family,
|
|
68950
|
+
action_type: workspace.action_type
|
|
68951
|
+
} : null;
|
|
68952
|
+
const isAssemblyWorkspace = shouldUseAssemblyCycleTimeLayout(workspaceCycleTimeEligibility);
|
|
68953
|
+
const cycleTimePresentation = getWorkspaceCycleTimePresentation({
|
|
68954
|
+
workspace: workspace ? {
|
|
68955
|
+
monitoring_mode: workspace.monitoring_mode,
|
|
68956
|
+
line_assembly_enabled: workspace.line_assembly_enabled,
|
|
68957
|
+
action_family: workspace.action_family,
|
|
68958
|
+
action_type: workspace.action_type,
|
|
68959
|
+
cycle_time_data_status: workspace.cycle_time_data_status
|
|
68960
|
+
} : null,
|
|
68961
|
+
showCycleTimeChart
|
|
68962
|
+
});
|
|
68963
|
+
const shouldShowCycleTimeChart = cycleTimePresentation !== "output";
|
|
68964
|
+
const shouldShowCycleTimeUnavailableState = cycleTimePresentation === "cycle_unavailable";
|
|
68736
68965
|
const showIdleBreakdownChart = !shouldShowCycleTimeChart && idleTimeVlmEnabled;
|
|
68737
68966
|
const idleClipDate = date || workspace?.date || calculatedOperationalDate || getOperationalDate(timezone);
|
|
68738
68967
|
const idleClipShiftId = parsedShiftId ?? workspace?.shift_id;
|
|
68739
|
-
const
|
|
68968
|
+
const rawHourlyIdleMinutes = React141.useMemo(() => {
|
|
68740
68969
|
if (!shouldShowCycleTimeChart || !workspace?.idle_time_hourly || !workspace?.shift_start) return [];
|
|
68741
68970
|
const parseTimeToMinutes3 = (time2) => {
|
|
68742
68971
|
const [h, m] = time2.split(":").map(Number);
|
|
@@ -68770,6 +68999,30 @@ var WorkspaceDetailView = ({
|
|
|
68770
68999
|
}
|
|
68771
69000
|
return result;
|
|
68772
69001
|
}, [shouldShowCycleTimeChart, workspace?.idle_time_hourly, workspace?.shift_start, workspace?.shift_end]);
|
|
69002
|
+
const hourlyIdleMinutes = React141.useMemo(
|
|
69003
|
+
() => maskFutureHourlySeries({
|
|
69004
|
+
data: rawHourlyIdleMinutes,
|
|
69005
|
+
shiftStart: workspace?.shift_start,
|
|
69006
|
+
shiftEnd: workspace?.shift_end,
|
|
69007
|
+
shiftDate: idleClipDate,
|
|
69008
|
+
timezone: effectiveCycleTimeTimezone
|
|
69009
|
+
}),
|
|
69010
|
+
[
|
|
69011
|
+
rawHourlyIdleMinutes,
|
|
69012
|
+
workspace?.shift_start,
|
|
69013
|
+
workspace?.shift_end,
|
|
69014
|
+
idleClipDate,
|
|
69015
|
+
effectiveCycleTimeTimezone
|
|
69016
|
+
]
|
|
69017
|
+
);
|
|
69018
|
+
const cycleTimeUnavailableView = React141.useMemo(() => /* @__PURE__ */ jsxRuntime.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: [
|
|
69019
|
+
/* @__PURE__ */ jsxRuntime.jsx("h4", { className: "text-base font-semibold text-amber-900", children: "Cycle data unavailable" }),
|
|
69020
|
+
/* @__PURE__ */ jsxRuntime.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." }),
|
|
69021
|
+
typeof workspace?.cycle_completion_clip_count === "number" && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "mt-3 text-xs font-medium uppercase tracking-[0.08em] text-amber-700", children: [
|
|
69022
|
+
"matched cycle clips: ",
|
|
69023
|
+
workspace.cycle_completion_clip_count
|
|
69024
|
+
] })
|
|
69025
|
+
] }), [workspace?.cycle_completion_clip_count]);
|
|
68773
69026
|
const shiftDurationMinutes = React141.useMemo(
|
|
68774
69027
|
() => getShiftDurationMinutes(workspace?.shift_start, workspace?.shift_end),
|
|
68775
69028
|
[workspace?.shift_start, workspace?.shift_end]
|
|
@@ -69266,7 +69519,7 @@ var WorkspaceDetailView = ({
|
|
|
69266
69519
|
children: [
|
|
69267
69520
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between items-center mb-4", children: [
|
|
69268
69521
|
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-bold text-gray-700", children: isUptimeMode ? "Machine Utilization" : shouldShowCycleTimeChart ? "Cycle time trend" : "Hourly Output" }),
|
|
69269
|
-
!isUptimeMode && /* @__PURE__ */ jsxRuntime.jsx(
|
|
69522
|
+
!isUptimeMode && !shouldShowCycleTimeUnavailableState && /* @__PURE__ */ jsxRuntime.jsx(
|
|
69270
69523
|
"button",
|
|
69271
69524
|
{
|
|
69272
69525
|
onClick: () => setShowChartIdleTime(!showChartIdleTime),
|
|
@@ -69295,10 +69548,10 @@ var WorkspaceDetailView = ({
|
|
|
69295
69548
|
timezone,
|
|
69296
69549
|
elapsedMinutes: elapsedShiftMinutes
|
|
69297
69550
|
}
|
|
69298
|
-
) : shouldShowCycleTimeChart ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
69551
|
+
) : shouldShowCycleTimeUnavailableState ? cycleTimeUnavailableView : shouldShowCycleTimeChart ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
69299
69552
|
CycleTimeOverTimeChart,
|
|
69300
69553
|
{
|
|
69301
|
-
data:
|
|
69554
|
+
data: maskedCycleTimeChartData,
|
|
69302
69555
|
idealCycleTime: workspace.ideal_cycle_time || 0,
|
|
69303
69556
|
shiftStart: workspace.shift_start || "",
|
|
69304
69557
|
shiftEnd: workspace.shift_end || "",
|
|
@@ -69399,7 +69652,7 @@ var WorkspaceDetailView = ({
|
|
|
69399
69652
|
children: [
|
|
69400
69653
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-3 mb-4 flex-none", children: [
|
|
69401
69654
|
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-bold text-gray-700", children: isUptimeMode ? "Machine Utilization" : shouldShowCycleTimeChart ? "Cycle time trend" : "Hourly Output" }),
|
|
69402
|
-
!isUptimeMode && /* @__PURE__ */ jsxRuntime.jsx(
|
|
69655
|
+
!isUptimeMode && !shouldShowCycleTimeUnavailableState && /* @__PURE__ */ jsxRuntime.jsx(
|
|
69403
69656
|
"button",
|
|
69404
69657
|
{
|
|
69405
69658
|
onClick: () => setShowChartIdleTime(!showChartIdleTime),
|
|
@@ -69424,10 +69677,10 @@ var WorkspaceDetailView = ({
|
|
|
69424
69677
|
timezone,
|
|
69425
69678
|
elapsedMinutes: elapsedShiftMinutes
|
|
69426
69679
|
}
|
|
69427
|
-
) : shouldShowCycleTimeChart ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
69680
|
+
) : shouldShowCycleTimeUnavailableState ? cycleTimeUnavailableView : shouldShowCycleTimeChart ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
69428
69681
|
CycleTimeOverTimeChart,
|
|
69429
69682
|
{
|
|
69430
|
-
data:
|
|
69683
|
+
data: maskedCycleTimeChartData,
|
|
69431
69684
|
idealCycleTime: workspace.ideal_cycle_time || 0,
|
|
69432
69685
|
shiftStart: workspace.shift_start || "",
|
|
69433
69686
|
shiftEnd: workspace.shift_end || "",
|
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);
|
|
@@ -68034,8 +68158,74 @@ var TargetsView = ({
|
|
|
68034
68158
|
var TargetsViewWithDisplayNames = withAllWorkspaceDisplayNames(TargetsView);
|
|
68035
68159
|
var TargetsView_default = TargetsViewWithDisplayNames;
|
|
68036
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
|
+
}
|
|
68037
68212
|
|
|
68038
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
|
+
};
|
|
68039
68229
|
var formatDateInTimezone = (date = /* @__PURE__ */ new Date(), timezone, options) => {
|
|
68040
68230
|
const defaultOptions = {
|
|
68041
68231
|
day: "numeric",
|
|
@@ -68419,6 +68609,7 @@ var WorkspaceDetailView = ({
|
|
|
68419
68609
|
date: cachedOverviewMetrics.date,
|
|
68420
68610
|
shift_id: cachedOverviewMetrics.shift_id,
|
|
68421
68611
|
action_name: "",
|
|
68612
|
+
action_family: cachedOverviewMetrics.action_family ?? null,
|
|
68422
68613
|
action_type: cachedOverviewMetrics.action_type ?? null,
|
|
68423
68614
|
monitoring_mode: cachedOverviewMetrics.monitoring_mode ?? "output",
|
|
68424
68615
|
shift_start: shiftDefinition?.startTime || "",
|
|
@@ -68442,6 +68633,11 @@ var WorkspaceDetailView = ({
|
|
|
68442
68633
|
};
|
|
68443
68634
|
}, [cachedOverviewMetrics, shiftConfig?.shifts]);
|
|
68444
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;
|
|
68445
68641
|
const detailedWorkspaceMetrics = (isHistoricView ? historicMetrics : liveMetrics) || cachedDetailedMetrics;
|
|
68446
68642
|
const cycleTimeChartData = useMemo(
|
|
68447
68643
|
() => Array.isArray(workspace?.hourly_cycle_times) ? workspace.hourly_cycle_times.map((value) => {
|
|
@@ -68450,12 +68646,31 @@ var WorkspaceDetailView = ({
|
|
|
68450
68646
|
}) : [],
|
|
68451
68647
|
[workspace?.hourly_cycle_times]
|
|
68452
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
|
+
);
|
|
68453
68667
|
const cycleTimeDatasetKey = useMemo(
|
|
68454
68668
|
() => [
|
|
68455
68669
|
workspace?.workspace_id || workspaceId || "workspace",
|
|
68456
68670
|
date || workspace?.date || "live",
|
|
68457
68671
|
parsedShiftId ?? workspace?.shift_id ?? "current",
|
|
68458
|
-
"hourly"
|
|
68672
|
+
"hourly",
|
|
68673
|
+
"backend"
|
|
68459
68674
|
].join(":"),
|
|
68460
68675
|
[workspace?.workspace_id, workspaceId, date, workspace?.date, parsedShiftId, workspace?.shift_id]
|
|
68461
68676
|
);
|
|
@@ -68700,14 +68915,28 @@ var WorkspaceDetailView = ({
|
|
|
68700
68915
|
return filterDataByDateKeyRange(monthlyData, range);
|
|
68701
68916
|
}, [monthlyData, range]);
|
|
68702
68917
|
const formattedWorkspaceName = displayName || formatWorkspaceName3(workspace?.workspace_name || "", effectiveLineId);
|
|
68703
|
-
const
|
|
68704
|
-
|
|
68705
|
-
|
|
68706
|
-
|
|
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";
|
|
68707
68936
|
const showIdleBreakdownChart = !shouldShowCycleTimeChart && idleTimeVlmEnabled;
|
|
68708
68937
|
const idleClipDate = date || workspace?.date || calculatedOperationalDate || getOperationalDate(timezone);
|
|
68709
68938
|
const idleClipShiftId = parsedShiftId ?? workspace?.shift_id;
|
|
68710
|
-
const
|
|
68939
|
+
const rawHourlyIdleMinutes = useMemo(() => {
|
|
68711
68940
|
if (!shouldShowCycleTimeChart || !workspace?.idle_time_hourly || !workspace?.shift_start) return [];
|
|
68712
68941
|
const parseTimeToMinutes3 = (time2) => {
|
|
68713
68942
|
const [h, m] = time2.split(":").map(Number);
|
|
@@ -68741,6 +68970,30 @@ var WorkspaceDetailView = ({
|
|
|
68741
68970
|
}
|
|
68742
68971
|
return result;
|
|
68743
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]);
|
|
68744
68997
|
const shiftDurationMinutes = useMemo(
|
|
68745
68998
|
() => getShiftDurationMinutes(workspace?.shift_start, workspace?.shift_end),
|
|
68746
68999
|
[workspace?.shift_start, workspace?.shift_end]
|
|
@@ -69237,7 +69490,7 @@ var WorkspaceDetailView = ({
|
|
|
69237
69490
|
children: [
|
|
69238
69491
|
/* @__PURE__ */ jsxs("div", { className: "flex justify-between items-center mb-4", children: [
|
|
69239
69492
|
/* @__PURE__ */ jsx("h3", { className: "text-lg font-bold text-gray-700", children: isUptimeMode ? "Machine Utilization" : shouldShowCycleTimeChart ? "Cycle time trend" : "Hourly Output" }),
|
|
69240
|
-
!isUptimeMode && /* @__PURE__ */ jsx(
|
|
69493
|
+
!isUptimeMode && !shouldShowCycleTimeUnavailableState && /* @__PURE__ */ jsx(
|
|
69241
69494
|
"button",
|
|
69242
69495
|
{
|
|
69243
69496
|
onClick: () => setShowChartIdleTime(!showChartIdleTime),
|
|
@@ -69266,10 +69519,10 @@ var WorkspaceDetailView = ({
|
|
|
69266
69519
|
timezone,
|
|
69267
69520
|
elapsedMinutes: elapsedShiftMinutes
|
|
69268
69521
|
}
|
|
69269
|
-
) : shouldShowCycleTimeChart ? /* @__PURE__ */ jsx(
|
|
69522
|
+
) : shouldShowCycleTimeUnavailableState ? cycleTimeUnavailableView : shouldShowCycleTimeChart ? /* @__PURE__ */ jsx(
|
|
69270
69523
|
CycleTimeOverTimeChart,
|
|
69271
69524
|
{
|
|
69272
|
-
data:
|
|
69525
|
+
data: maskedCycleTimeChartData,
|
|
69273
69526
|
idealCycleTime: workspace.ideal_cycle_time || 0,
|
|
69274
69527
|
shiftStart: workspace.shift_start || "",
|
|
69275
69528
|
shiftEnd: workspace.shift_end || "",
|
|
@@ -69370,7 +69623,7 @@ var WorkspaceDetailView = ({
|
|
|
69370
69623
|
children: [
|
|
69371
69624
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3 mb-4 flex-none", children: [
|
|
69372
69625
|
/* @__PURE__ */ jsx("h3", { className: "text-lg font-bold text-gray-700", children: isUptimeMode ? "Machine Utilization" : shouldShowCycleTimeChart ? "Cycle time trend" : "Hourly Output" }),
|
|
69373
|
-
!isUptimeMode && /* @__PURE__ */ jsx(
|
|
69626
|
+
!isUptimeMode && !shouldShowCycleTimeUnavailableState && /* @__PURE__ */ jsx(
|
|
69374
69627
|
"button",
|
|
69375
69628
|
{
|
|
69376
69629
|
onClick: () => setShowChartIdleTime(!showChartIdleTime),
|
|
@@ -69395,10 +69648,10 @@ var WorkspaceDetailView = ({
|
|
|
69395
69648
|
timezone,
|
|
69396
69649
|
elapsedMinutes: elapsedShiftMinutes
|
|
69397
69650
|
}
|
|
69398
|
-
) : shouldShowCycleTimeChart ? /* @__PURE__ */ jsx(
|
|
69651
|
+
) : shouldShowCycleTimeUnavailableState ? cycleTimeUnavailableView : shouldShowCycleTimeChart ? /* @__PURE__ */ jsx(
|
|
69399
69652
|
CycleTimeOverTimeChart,
|
|
69400
69653
|
{
|
|
69401
|
-
data:
|
|
69654
|
+
data: maskedCycleTimeChartData,
|
|
69402
69655
|
idealCycleTime: workspace.ideal_cycle_time || 0,
|
|
69403
69656
|
shiftStart: workspace.shift_start || "",
|
|
69404
69657
|
shiftEnd: workspace.shift_end || "",
|