@optifye/dashboard-core 6.5.9 → 6.5.11
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.js +769 -172
- package/dist/index.mjs +769 -172
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -878,20 +878,121 @@ var dashboardService = {
|
|
|
878
878
|
}
|
|
879
879
|
console.log("Expected shift hours:", expectedHours);
|
|
880
880
|
console.log("Available data hours:", Object.keys(outputHourly));
|
|
881
|
-
hourlyActionCounts = expectedHours.map((expectedHour) => {
|
|
882
|
-
let
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
881
|
+
hourlyActionCounts = expectedHours.map((expectedHour, index) => {
|
|
882
|
+
let hourSum = 0;
|
|
883
|
+
const hourData = outputHourly[expectedHour.toString()] || [];
|
|
884
|
+
if (startMinute > 0) {
|
|
885
|
+
if (index === 0) {
|
|
886
|
+
if (Array.isArray(hourData)) {
|
|
887
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
888
|
+
const val = hourData[i];
|
|
889
|
+
if (val !== "x" && typeof val === "number") {
|
|
890
|
+
hourSum += val;
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
895
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
896
|
+
if (Array.isArray(nextHourData)) {
|
|
897
|
+
for (let i = 0; i < startMinute && i < nextHourData.length; i++) {
|
|
898
|
+
const val = nextHourData[i];
|
|
899
|
+
if (val !== "x" && typeof val === "number") {
|
|
900
|
+
hourSum += val;
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
} else if (index < expectedHours.length - 1) {
|
|
905
|
+
if (Array.isArray(hourData)) {
|
|
906
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
907
|
+
const val = hourData[i];
|
|
908
|
+
if (val !== "x" && typeof val === "number") {
|
|
909
|
+
hourSum += val;
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
914
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
915
|
+
if (Array.isArray(nextHourData)) {
|
|
916
|
+
for (let i = 0; i < startMinute && i < nextHourData.length; i++) {
|
|
917
|
+
const val = nextHourData[i];
|
|
918
|
+
if (val !== "x" && typeof val === "number") {
|
|
919
|
+
hourSum += val;
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
} else {
|
|
924
|
+
if (hasPartialLastHour && endMinute > 0) {
|
|
925
|
+
if (startMinute > 0) {
|
|
926
|
+
if (Array.isArray(hourData)) {
|
|
927
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
928
|
+
const val = hourData[i];
|
|
929
|
+
if (val !== "x" && typeof val === "number") {
|
|
930
|
+
hourSum += val;
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
935
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
936
|
+
if (Array.isArray(nextHourData)) {
|
|
937
|
+
for (let i = 0; i < endMinute && i < nextHourData.length; i++) {
|
|
938
|
+
const val = nextHourData[i];
|
|
939
|
+
if (val !== "x" && typeof val === "number") {
|
|
940
|
+
hourSum += val;
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
} else {
|
|
945
|
+
if (Array.isArray(hourData)) {
|
|
946
|
+
for (let i = 0; i < endMinute && i < hourData.length; i++) {
|
|
947
|
+
const val = hourData[i];
|
|
948
|
+
if (val !== "x" && typeof val === "number") {
|
|
949
|
+
hourSum += val;
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
} else {
|
|
955
|
+
if (Array.isArray(hourData)) {
|
|
956
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
957
|
+
const val = hourData[i];
|
|
958
|
+
if (val !== "x" && typeof val === "number") {
|
|
959
|
+
hourSum += val;
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
964
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
965
|
+
if (Array.isArray(nextHourData)) {
|
|
966
|
+
for (let i = 0; i < startMinute && i < nextHourData.length; i++) {
|
|
967
|
+
const val = nextHourData[i];
|
|
968
|
+
if (val !== "x" && typeof val === "number") {
|
|
969
|
+
hourSum += val;
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
} else {
|
|
976
|
+
if (Array.isArray(hourData)) {
|
|
977
|
+
hourData.forEach((val) => {
|
|
978
|
+
if (val !== "x" && typeof val === "number") {
|
|
979
|
+
hourSum += val;
|
|
980
|
+
}
|
|
981
|
+
});
|
|
982
|
+
}
|
|
983
|
+
if (index === expectedHours.length - 1 && hasPartialLastHour && endMinute > 0) {
|
|
984
|
+
hourSum = 0;
|
|
985
|
+
if (Array.isArray(hourData)) {
|
|
986
|
+
for (let i = 0; i < endMinute && i < hourData.length; i++) {
|
|
987
|
+
const val = hourData[i];
|
|
988
|
+
if (val !== "x" && typeof val === "number") {
|
|
989
|
+
hourSum += val;
|
|
990
|
+
}
|
|
890
991
|
}
|
|
891
992
|
}
|
|
892
993
|
}
|
|
893
994
|
}
|
|
894
|
-
return
|
|
995
|
+
return hourSum;
|
|
895
996
|
});
|
|
896
997
|
console.log("Final hourly action counts:", hourlyActionCounts);
|
|
897
998
|
} else {
|
|
@@ -2092,136 +2193,142 @@ var WorkspaceHealthService = class _WorkspaceHealthService {
|
|
|
2092
2193
|
const now2 = /* @__PURE__ */ new Date();
|
|
2093
2194
|
const currentHour = now2.getHours();
|
|
2094
2195
|
const currentMinute = now2.getMinutes();
|
|
2095
|
-
|
|
2096
|
-
|
|
2196
|
+
const dayShiftStart = shiftConfig?.dayShift?.startTime || "08:00";
|
|
2197
|
+
const dayShiftEnd = shiftConfig?.dayShift?.endTime || "19:30";
|
|
2198
|
+
const nightShiftStart = shiftConfig?.nightShift?.startTime || "19:30";
|
|
2199
|
+
const nightShiftEnd = shiftConfig?.nightShift?.endTime || "06:00";
|
|
2200
|
+
const parseShiftTime = (timeStr) => {
|
|
2201
|
+
const [hour, minute] = timeStr.split(":").map(Number);
|
|
2202
|
+
return { hour, minute };
|
|
2203
|
+
};
|
|
2204
|
+
let shiftStart, shiftEnd;
|
|
2097
2205
|
if (currentShiftId === 0) {
|
|
2098
|
-
|
|
2099
|
-
|
|
2206
|
+
shiftStart = parseShiftTime(dayShiftStart);
|
|
2207
|
+
shiftEnd = parseShiftTime(dayShiftEnd);
|
|
2100
2208
|
} else {
|
|
2101
|
-
|
|
2102
|
-
|
|
2209
|
+
shiftStart = parseShiftTime(nightShiftStart);
|
|
2210
|
+
shiftEnd = parseShiftTime(nightShiftEnd);
|
|
2103
2211
|
}
|
|
2104
2212
|
let elapsedMinutes = 0;
|
|
2105
2213
|
if (currentShiftId === 0) {
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2214
|
+
const shiftStartTotalMinutes = shiftStart.hour * 60 + shiftStart.minute;
|
|
2215
|
+
const currentTotalMinutes = currentHour * 60 + currentMinute;
|
|
2216
|
+
const shiftEndTotalMinutes = shiftEnd.hour * 60 + shiftEnd.minute;
|
|
2217
|
+
if (currentTotalMinutes >= shiftStartTotalMinutes && currentTotalMinutes < shiftEndTotalMinutes) {
|
|
2218
|
+
elapsedMinutes = currentTotalMinutes - shiftStartTotalMinutes;
|
|
2219
|
+
} else if (currentTotalMinutes >= shiftEndTotalMinutes) {
|
|
2220
|
+
elapsedMinutes = shiftEndTotalMinutes - shiftStartTotalMinutes;
|
|
2110
2221
|
}
|
|
2111
2222
|
} else {
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2223
|
+
const shiftStartTotalMinutes = shiftStart.hour * 60 + shiftStart.minute;
|
|
2224
|
+
const currentTotalMinutes = currentHour * 60 + currentMinute;
|
|
2225
|
+
const shiftEndTotalMinutes = shiftEnd.hour * 60 + shiftEnd.minute;
|
|
2226
|
+
if (currentHour >= shiftStart.hour || currentHour < shiftEnd.hour) {
|
|
2227
|
+
if (currentHour >= shiftStart.hour) {
|
|
2228
|
+
elapsedMinutes = currentTotalMinutes - shiftStartTotalMinutes;
|
|
2229
|
+
} else {
|
|
2230
|
+
elapsedMinutes = 24 * 60 - shiftStartTotalMinutes + currentTotalMinutes;
|
|
2231
|
+
}
|
|
2232
|
+
if (currentHour >= shiftEnd.hour && currentTotalMinutes >= shiftEndTotalMinutes) {
|
|
2233
|
+
const totalShiftMinutes = 24 * 60 - shiftStartTotalMinutes + shiftEndTotalMinutes;
|
|
2234
|
+
elapsedMinutes = Math.min(elapsedMinutes, totalShiftMinutes);
|
|
2235
|
+
}
|
|
2116
2236
|
}
|
|
2117
2237
|
}
|
|
2118
2238
|
const tableName = `performance_metrics_${companyId.replace(/-/g, "_")}`;
|
|
2119
|
-
const query = `
|
|
2120
|
-
WITH workspace_uptime AS (
|
|
2121
|
-
SELECT
|
|
2122
|
-
workspace_id,
|
|
2123
|
-
workspace_display_name,
|
|
2124
|
-
idle_time_hourly,
|
|
2125
|
-
output_hourly,
|
|
2126
|
-
shift_start,
|
|
2127
|
-
shift_end
|
|
2128
|
-
FROM ${tableName}
|
|
2129
|
-
WHERE date = $1::date
|
|
2130
|
-
AND shift_id = $2
|
|
2131
|
-
),
|
|
2132
|
-
calculated_uptime AS (
|
|
2133
|
-
SELECT
|
|
2134
|
-
workspace_id,
|
|
2135
|
-
workspace_display_name,
|
|
2136
|
-
-- Calculate actual minutes from hourly data
|
|
2137
|
-
(
|
|
2138
|
-
SELECT COALESCE(SUM(
|
|
2139
|
-
CASE
|
|
2140
|
-
WHEN jsonb_array_length(idle_time_hourly->key::text) >= 58 THEN 60
|
|
2141
|
-
WHEN jsonb_array_length(idle_time_hourly->key::text) > 0 THEN jsonb_array_length(idle_time_hourly->key::text)
|
|
2142
|
-
ELSE 0
|
|
2143
|
-
END
|
|
2144
|
-
), 0)
|
|
2145
|
-
FROM jsonb_object_keys(idle_time_hourly) AS key
|
|
2146
|
-
WHERE key::int >= $3 AND key::int < $4
|
|
2147
|
-
) +
|
|
2148
|
-
-- Add current hour's data if applicable
|
|
2149
|
-
CASE
|
|
2150
|
-
WHEN $4::int >= $3 AND $4::int < $5 THEN
|
|
2151
|
-
LEAST($6::int,
|
|
2152
|
-
COALESCE(jsonb_array_length(idle_time_hourly->$4::text), 0))
|
|
2153
|
-
ELSE 0
|
|
2154
|
-
END as actual_minutes
|
|
2155
|
-
FROM workspace_uptime
|
|
2156
|
-
)
|
|
2157
|
-
SELECT
|
|
2158
|
-
workspace_id,
|
|
2159
|
-
workspace_display_name,
|
|
2160
|
-
actual_minutes,
|
|
2161
|
-
$7::int as expected_minutes,
|
|
2162
|
-
ROUND(
|
|
2163
|
-
CASE
|
|
2164
|
-
WHEN $7::int > 0 THEN (actual_minutes::numeric / $7::numeric) * 100
|
|
2165
|
-
ELSE 100
|
|
2166
|
-
END, 1
|
|
2167
|
-
) as uptime_percentage
|
|
2168
|
-
FROM calculated_uptime
|
|
2169
|
-
`;
|
|
2170
2239
|
try {
|
|
2171
|
-
const { data, error } = await supabase.
|
|
2172
|
-
query_text: query,
|
|
2173
|
-
params: [
|
|
2174
|
-
currentDate,
|
|
2175
|
-
currentShiftId,
|
|
2176
|
-
shiftStartHour,
|
|
2177
|
-
currentHour,
|
|
2178
|
-
shiftEndHour,
|
|
2179
|
-
currentMinute,
|
|
2180
|
-
elapsedMinutes
|
|
2181
|
-
]
|
|
2182
|
-
}).single();
|
|
2240
|
+
const { data: queryData, error } = await supabase.from(tableName).select("workspace_id, workspace_display_name, output_hourly").eq("date", currentDate).eq("shift_id", currentShiftId);
|
|
2183
2241
|
if (error) {
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2242
|
+
console.error("Error fetching performance metrics:", error);
|
|
2243
|
+
return /* @__PURE__ */ new Map();
|
|
2244
|
+
}
|
|
2245
|
+
const uptimeMap = /* @__PURE__ */ new Map();
|
|
2246
|
+
for (const record of queryData || []) {
|
|
2247
|
+
let actualMinutes = 0;
|
|
2248
|
+
let totalPossibleMinutes = 0;
|
|
2249
|
+
const outputHourly = record.output_hourly || {};
|
|
2250
|
+
const hoursElapsed = Math.ceil(elapsedMinutes / 60);
|
|
2251
|
+
for (let hourIndex = 0; hourIndex < hoursElapsed; hourIndex++) {
|
|
2252
|
+
const actualHour = (shiftStart.hour + hourIndex) % 24;
|
|
2253
|
+
let hourData = [];
|
|
2254
|
+
let minutesInThisHour = 60;
|
|
2255
|
+
if (shiftStart.minute > 0) {
|
|
2256
|
+
if (hourIndex === 0) {
|
|
2257
|
+
const firstHourData = outputHourly[actualHour.toString()] || [];
|
|
2258
|
+
const nextHour = (actualHour + 1) % 24;
|
|
2259
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
2260
|
+
hourData = [
|
|
2261
|
+
...Array.isArray(firstHourData) ? firstHourData.slice(shiftStart.minute) : [],
|
|
2262
|
+
...Array.isArray(nextHourData) ? nextHourData.slice(0, shiftStart.minute) : []
|
|
2263
|
+
];
|
|
2264
|
+
} else if (hourIndex < hoursElapsed - 1) {
|
|
2265
|
+
const currentHourData = outputHourly[actualHour.toString()] || [];
|
|
2266
|
+
const nextHour = (actualHour + 1) % 24;
|
|
2267
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
2268
|
+
hourData = [
|
|
2269
|
+
...Array.isArray(currentHourData) ? currentHourData.slice(shiftStart.minute) : [],
|
|
2270
|
+
...Array.isArray(nextHourData) ? nextHourData.slice(0, shiftStart.minute) : []
|
|
2271
|
+
];
|
|
2272
|
+
} else {
|
|
2273
|
+
const isLastHourPartial = hourIndex === hoursElapsed - 1 && elapsedMinutes % 60 > 0;
|
|
2274
|
+
if (isLastHourPartial) {
|
|
2275
|
+
minutesInThisHour = elapsedMinutes % 60;
|
|
2276
|
+
const currentHourData = outputHourly[actualHour.toString()] || [];
|
|
2277
|
+
if (shiftStart.minute > 0) {
|
|
2278
|
+
const nextHour = (actualHour + 1) % 24;
|
|
2279
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
2280
|
+
const firstPart = Array.isArray(currentHourData) ? currentHourData.slice(shiftStart.minute) : [];
|
|
2281
|
+
const secondPart = Array.isArray(nextHourData) ? nextHourData.slice(0, Math.min(shiftStart.minute, minutesInThisHour)) : [];
|
|
2282
|
+
hourData = [...firstPart, ...secondPart].slice(0, minutesInThisHour);
|
|
2283
|
+
} else {
|
|
2284
|
+
hourData = Array.isArray(currentHourData) ? currentHourData.slice(0, minutesInThisHour) : [];
|
|
2285
|
+
}
|
|
2286
|
+
} else {
|
|
2287
|
+
const currentHourData = outputHourly[actualHour.toString()] || [];
|
|
2288
|
+
const nextHour = (actualHour + 1) % 24;
|
|
2289
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
2290
|
+
hourData = [
|
|
2291
|
+
...Array.isArray(currentHourData) ? currentHourData.slice(shiftStart.minute) : [],
|
|
2292
|
+
...Array.isArray(nextHourData) ? nextHourData.slice(0, shiftStart.minute) : []
|
|
2293
|
+
];
|
|
2294
|
+
}
|
|
2295
|
+
}
|
|
2296
|
+
} else {
|
|
2297
|
+
hourData = outputHourly[actualHour.toString()] || [];
|
|
2298
|
+
if (hourIndex === hoursElapsed - 1) {
|
|
2299
|
+
const remainingMinutes = elapsedMinutes % 60;
|
|
2300
|
+
if (remainingMinutes > 0) {
|
|
2301
|
+
minutesInThisHour = remainingMinutes;
|
|
2302
|
+
hourData = Array.isArray(hourData) ? hourData.slice(0, minutesInThisHour) : [];
|
|
2202
2303
|
}
|
|
2203
2304
|
}
|
|
2204
2305
|
}
|
|
2205
|
-
const
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
});
|
|
2306
|
+
const hasXArchitecture = Array.isArray(hourData) && hourData.some((val) => val === "x");
|
|
2307
|
+
if (hasXArchitecture) {
|
|
2308
|
+
const xCount = hourData.filter((val) => val === "x").length;
|
|
2309
|
+
if (xCount <= 2) {
|
|
2310
|
+
actualMinutes += minutesInThisHour;
|
|
2311
|
+
} else {
|
|
2312
|
+
const uptimeCount = hourData.filter((val) => val !== "x").length;
|
|
2313
|
+
actualMinutes += Math.min(uptimeCount, minutesInThisHour);
|
|
2314
|
+
}
|
|
2315
|
+
} else {
|
|
2316
|
+
const arrayLength = Array.isArray(hourData) ? hourData.length : 0;
|
|
2317
|
+
if (arrayLength >= Math.min(58, minutesInThisHour - 2)) {
|
|
2318
|
+
actualMinutes += minutesInThisHour;
|
|
2319
|
+
} else {
|
|
2320
|
+
actualMinutes += Math.min(arrayLength, minutesInThisHour);
|
|
2321
|
+
}
|
|
2322
|
+
}
|
|
2323
|
+
totalPossibleMinutes += minutesInThisHour;
|
|
2224
2324
|
}
|
|
2325
|
+
const percentage = totalPossibleMinutes > 0 ? Math.round(actualMinutes / totalPossibleMinutes * 1e3) / 10 : 100;
|
|
2326
|
+
uptimeMap.set(record.workspace_id, {
|
|
2327
|
+
expectedMinutes: totalPossibleMinutes,
|
|
2328
|
+
actualMinutes,
|
|
2329
|
+
percentage,
|
|
2330
|
+
lastCalculated: (/* @__PURE__ */ new Date()).toISOString()
|
|
2331
|
+
});
|
|
2225
2332
|
}
|
|
2226
2333
|
return uptimeMap;
|
|
2227
2334
|
} catch (error) {
|
|
@@ -5690,20 +5797,121 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
|
|
|
5690
5797
|
}
|
|
5691
5798
|
console.log("Expected shift hours (fallback):", expectedHours);
|
|
5692
5799
|
console.log("Available data hours (fallback):", Object.keys(outputHourly2));
|
|
5693
|
-
hourlyActionCounts2 = expectedHours.map((expectedHour) => {
|
|
5694
|
-
let
|
|
5695
|
-
|
|
5696
|
-
|
|
5697
|
-
|
|
5698
|
-
|
|
5699
|
-
|
|
5700
|
-
|
|
5701
|
-
|
|
5800
|
+
hourlyActionCounts2 = expectedHours.map((expectedHour, index) => {
|
|
5801
|
+
let hourSum = 0;
|
|
5802
|
+
const hourData = outputHourly2[expectedHour.toString()] || [];
|
|
5803
|
+
if (startMinute > 0) {
|
|
5804
|
+
if (index === 0) {
|
|
5805
|
+
if (Array.isArray(hourData)) {
|
|
5806
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
5807
|
+
const val = hourData[i];
|
|
5808
|
+
if (val !== "x" && typeof val === "number") {
|
|
5809
|
+
hourSum += val;
|
|
5810
|
+
}
|
|
5811
|
+
}
|
|
5812
|
+
}
|
|
5813
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
5814
|
+
const nextHourData = outputHourly2[nextHour.toString()] || [];
|
|
5815
|
+
if (Array.isArray(nextHourData)) {
|
|
5816
|
+
for (let i = 0; i < startMinute && i < nextHourData.length; i++) {
|
|
5817
|
+
const val = nextHourData[i];
|
|
5818
|
+
if (val !== "x" && typeof val === "number") {
|
|
5819
|
+
hourSum += val;
|
|
5820
|
+
}
|
|
5821
|
+
}
|
|
5822
|
+
}
|
|
5823
|
+
} else if (index < expectedHours.length - 1) {
|
|
5824
|
+
if (Array.isArray(hourData)) {
|
|
5825
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
5826
|
+
const val = hourData[i];
|
|
5827
|
+
if (val !== "x" && typeof val === "number") {
|
|
5828
|
+
hourSum += val;
|
|
5829
|
+
}
|
|
5830
|
+
}
|
|
5831
|
+
}
|
|
5832
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
5833
|
+
const nextHourData = outputHourly2[nextHour.toString()] || [];
|
|
5834
|
+
if (Array.isArray(nextHourData)) {
|
|
5835
|
+
for (let i = 0; i < startMinute && i < nextHourData.length; i++) {
|
|
5836
|
+
const val = nextHourData[i];
|
|
5837
|
+
if (val !== "x" && typeof val === "number") {
|
|
5838
|
+
hourSum += val;
|
|
5839
|
+
}
|
|
5840
|
+
}
|
|
5841
|
+
}
|
|
5842
|
+
} else {
|
|
5843
|
+
if (hasPartialLastHour && endMinute > 0) {
|
|
5844
|
+
if (startMinute > 0) {
|
|
5845
|
+
if (Array.isArray(hourData)) {
|
|
5846
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
5847
|
+
const val = hourData[i];
|
|
5848
|
+
if (val !== "x" && typeof val === "number") {
|
|
5849
|
+
hourSum += val;
|
|
5850
|
+
}
|
|
5851
|
+
}
|
|
5852
|
+
}
|
|
5853
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
5854
|
+
const nextHourData = outputHourly2[nextHour.toString()] || [];
|
|
5855
|
+
if (Array.isArray(nextHourData)) {
|
|
5856
|
+
for (let i = 0; i < endMinute && i < nextHourData.length; i++) {
|
|
5857
|
+
const val = nextHourData[i];
|
|
5858
|
+
if (val !== "x" && typeof val === "number") {
|
|
5859
|
+
hourSum += val;
|
|
5860
|
+
}
|
|
5861
|
+
}
|
|
5862
|
+
}
|
|
5863
|
+
} else {
|
|
5864
|
+
if (Array.isArray(hourData)) {
|
|
5865
|
+
for (let i = 0; i < endMinute && i < hourData.length; i++) {
|
|
5866
|
+
const val = hourData[i];
|
|
5867
|
+
if (val !== "x" && typeof val === "number") {
|
|
5868
|
+
hourSum += val;
|
|
5869
|
+
}
|
|
5870
|
+
}
|
|
5871
|
+
}
|
|
5872
|
+
}
|
|
5873
|
+
} else {
|
|
5874
|
+
if (Array.isArray(hourData)) {
|
|
5875
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
5876
|
+
const val = hourData[i];
|
|
5877
|
+
if (val !== "x" && typeof val === "number") {
|
|
5878
|
+
hourSum += val;
|
|
5879
|
+
}
|
|
5880
|
+
}
|
|
5881
|
+
}
|
|
5882
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
5883
|
+
const nextHourData = outputHourly2[nextHour.toString()] || [];
|
|
5884
|
+
if (Array.isArray(nextHourData)) {
|
|
5885
|
+
for (let i = 0; i < startMinute && i < nextHourData.length; i++) {
|
|
5886
|
+
const val = nextHourData[i];
|
|
5887
|
+
if (val !== "x" && typeof val === "number") {
|
|
5888
|
+
hourSum += val;
|
|
5889
|
+
}
|
|
5890
|
+
}
|
|
5891
|
+
}
|
|
5892
|
+
}
|
|
5893
|
+
}
|
|
5894
|
+
} else {
|
|
5895
|
+
if (Array.isArray(hourData)) {
|
|
5896
|
+
hourData.forEach((val) => {
|
|
5897
|
+
if (val !== "x" && typeof val === "number") {
|
|
5898
|
+
hourSum += val;
|
|
5899
|
+
}
|
|
5900
|
+
});
|
|
5901
|
+
}
|
|
5902
|
+
if (index === expectedHours.length - 1 && hasPartialLastHour && endMinute > 0) {
|
|
5903
|
+
hourSum = 0;
|
|
5904
|
+
if (Array.isArray(hourData)) {
|
|
5905
|
+
for (let i = 0; i < endMinute && i < hourData.length; i++) {
|
|
5906
|
+
const val = hourData[i];
|
|
5907
|
+
if (val !== "x" && typeof val === "number") {
|
|
5908
|
+
hourSum += val;
|
|
5909
|
+
}
|
|
5702
5910
|
}
|
|
5703
5911
|
}
|
|
5704
5912
|
}
|
|
5705
5913
|
}
|
|
5706
|
-
return
|
|
5914
|
+
return hourSum;
|
|
5707
5915
|
});
|
|
5708
5916
|
console.log("Final hourly action counts (fallback):", hourlyActionCounts2);
|
|
5709
5917
|
} else {
|
|
@@ -5805,20 +6013,121 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
|
|
|
5805
6013
|
}
|
|
5806
6014
|
console.log("Expected shift hours:", expectedHours);
|
|
5807
6015
|
console.log("Available data hours:", Object.keys(outputHourly));
|
|
5808
|
-
hourlyActionCounts = expectedHours.map((expectedHour) => {
|
|
5809
|
-
let
|
|
5810
|
-
|
|
5811
|
-
|
|
5812
|
-
|
|
5813
|
-
|
|
5814
|
-
|
|
5815
|
-
|
|
5816
|
-
|
|
6016
|
+
hourlyActionCounts = expectedHours.map((expectedHour, index) => {
|
|
6017
|
+
let hourSum = 0;
|
|
6018
|
+
const hourData = outputHourly[expectedHour.toString()] || [];
|
|
6019
|
+
if (startMinute > 0) {
|
|
6020
|
+
if (index === 0) {
|
|
6021
|
+
if (Array.isArray(hourData)) {
|
|
6022
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
6023
|
+
const val = hourData[i];
|
|
6024
|
+
if (val !== "x" && typeof val === "number") {
|
|
6025
|
+
hourSum += val;
|
|
6026
|
+
}
|
|
6027
|
+
}
|
|
6028
|
+
}
|
|
6029
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
6030
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
6031
|
+
if (Array.isArray(nextHourData)) {
|
|
6032
|
+
for (let i = 0; i < startMinute && i < nextHourData.length; i++) {
|
|
6033
|
+
const val = nextHourData[i];
|
|
6034
|
+
if (val !== "x" && typeof val === "number") {
|
|
6035
|
+
hourSum += val;
|
|
6036
|
+
}
|
|
6037
|
+
}
|
|
6038
|
+
}
|
|
6039
|
+
} else if (index < expectedHours.length - 1) {
|
|
6040
|
+
if (Array.isArray(hourData)) {
|
|
6041
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
6042
|
+
const val = hourData[i];
|
|
6043
|
+
if (val !== "x" && typeof val === "number") {
|
|
6044
|
+
hourSum += val;
|
|
6045
|
+
}
|
|
6046
|
+
}
|
|
6047
|
+
}
|
|
6048
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
6049
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
6050
|
+
if (Array.isArray(nextHourData)) {
|
|
6051
|
+
for (let i = 0; i < startMinute && i < nextHourData.length; i++) {
|
|
6052
|
+
const val = nextHourData[i];
|
|
6053
|
+
if (val !== "x" && typeof val === "number") {
|
|
6054
|
+
hourSum += val;
|
|
6055
|
+
}
|
|
6056
|
+
}
|
|
6057
|
+
}
|
|
6058
|
+
} else {
|
|
6059
|
+
if (hasPartialLastHour && endMinute > 0) {
|
|
6060
|
+
if (startMinute > 0) {
|
|
6061
|
+
if (Array.isArray(hourData)) {
|
|
6062
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
6063
|
+
const val = hourData[i];
|
|
6064
|
+
if (val !== "x" && typeof val === "number") {
|
|
6065
|
+
hourSum += val;
|
|
6066
|
+
}
|
|
6067
|
+
}
|
|
6068
|
+
}
|
|
6069
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
6070
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
6071
|
+
if (Array.isArray(nextHourData)) {
|
|
6072
|
+
for (let i = 0; i < endMinute && i < nextHourData.length; i++) {
|
|
6073
|
+
const val = nextHourData[i];
|
|
6074
|
+
if (val !== "x" && typeof val === "number") {
|
|
6075
|
+
hourSum += val;
|
|
6076
|
+
}
|
|
6077
|
+
}
|
|
6078
|
+
}
|
|
6079
|
+
} else {
|
|
6080
|
+
if (Array.isArray(hourData)) {
|
|
6081
|
+
for (let i = 0; i < endMinute && i < hourData.length; i++) {
|
|
6082
|
+
const val = hourData[i];
|
|
6083
|
+
if (val !== "x" && typeof val === "number") {
|
|
6084
|
+
hourSum += val;
|
|
6085
|
+
}
|
|
6086
|
+
}
|
|
6087
|
+
}
|
|
6088
|
+
}
|
|
6089
|
+
} else {
|
|
6090
|
+
if (Array.isArray(hourData)) {
|
|
6091
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
6092
|
+
const val = hourData[i];
|
|
6093
|
+
if (val !== "x" && typeof val === "number") {
|
|
6094
|
+
hourSum += val;
|
|
6095
|
+
}
|
|
6096
|
+
}
|
|
6097
|
+
}
|
|
6098
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
6099
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
6100
|
+
if (Array.isArray(nextHourData)) {
|
|
6101
|
+
for (let i = 0; i < startMinute && i < nextHourData.length; i++) {
|
|
6102
|
+
const val = nextHourData[i];
|
|
6103
|
+
if (val !== "x" && typeof val === "number") {
|
|
6104
|
+
hourSum += val;
|
|
6105
|
+
}
|
|
6106
|
+
}
|
|
6107
|
+
}
|
|
6108
|
+
}
|
|
6109
|
+
}
|
|
6110
|
+
} else {
|
|
6111
|
+
if (Array.isArray(hourData)) {
|
|
6112
|
+
hourData.forEach((val) => {
|
|
6113
|
+
if (val !== "x" && typeof val === "number") {
|
|
6114
|
+
hourSum += val;
|
|
6115
|
+
}
|
|
6116
|
+
});
|
|
6117
|
+
}
|
|
6118
|
+
if (index === expectedHours.length - 1 && hasPartialLastHour && endMinute > 0) {
|
|
6119
|
+
hourSum = 0;
|
|
6120
|
+
if (Array.isArray(hourData)) {
|
|
6121
|
+
for (let i = 0; i < endMinute && i < hourData.length; i++) {
|
|
6122
|
+
const val = hourData[i];
|
|
6123
|
+
if (val !== "x" && typeof val === "number") {
|
|
6124
|
+
hourSum += val;
|
|
6125
|
+
}
|
|
5817
6126
|
}
|
|
5818
6127
|
}
|
|
5819
6128
|
}
|
|
5820
6129
|
}
|
|
5821
|
-
return
|
|
6130
|
+
return hourSum;
|
|
5822
6131
|
});
|
|
5823
6132
|
console.log("Final hourly action counts:", hourlyActionCounts);
|
|
5824
6133
|
} else {
|
|
@@ -21432,8 +21741,60 @@ var HourlyOutputChartComponent = ({
|
|
|
21432
21741
|
const chartData = React19__default.useMemo(() => {
|
|
21433
21742
|
return Array.from({ length: SHIFT_DURATION }, (_, i) => {
|
|
21434
21743
|
const actualHour = (shiftStartTime.hour + i) % 24;
|
|
21435
|
-
const
|
|
21436
|
-
|
|
21744
|
+
const startMinute = shiftStartTime.minute;
|
|
21745
|
+
let idleArray = [];
|
|
21746
|
+
let idleMinutes = 0;
|
|
21747
|
+
if (idleTimeHourly) {
|
|
21748
|
+
if (startMinute > 0) {
|
|
21749
|
+
if (i === 0) {
|
|
21750
|
+
const firstHourData = idleTimeHourly[actualHour.toString()] || [];
|
|
21751
|
+
const nextHour = (actualHour + 1) % 24;
|
|
21752
|
+
const nextHourData = idleTimeHourly[nextHour.toString()] || [];
|
|
21753
|
+
idleArray = [
|
|
21754
|
+
...firstHourData.slice(startMinute) || [],
|
|
21755
|
+
...nextHourData.slice(0, startMinute) || []
|
|
21756
|
+
];
|
|
21757
|
+
} else if (i < SHIFT_DURATION - 1) {
|
|
21758
|
+
const currentHourData = idleTimeHourly[actualHour.toString()] || [];
|
|
21759
|
+
const nextHour = (actualHour + 1) % 24;
|
|
21760
|
+
const nextHourData = idleTimeHourly[nextHour.toString()] || [];
|
|
21761
|
+
idleArray = [
|
|
21762
|
+
...currentHourData.slice(startMinute) || [],
|
|
21763
|
+
...nextHourData.slice(0, startMinute) || []
|
|
21764
|
+
];
|
|
21765
|
+
} else {
|
|
21766
|
+
const hasPartialLastHour2 = shiftEndTime && shiftEndTime.minute > 0 && shiftEndTime.minute < 60;
|
|
21767
|
+
if (hasPartialLastHour2) {
|
|
21768
|
+
const currentHourData = idleTimeHourly[actualHour.toString()] || [];
|
|
21769
|
+
const nextHour = (actualHour + 1) % 24;
|
|
21770
|
+
const nextHourData = idleTimeHourly[nextHour.toString()] || [];
|
|
21771
|
+
if (startMinute > 0) {
|
|
21772
|
+
const firstPart = currentHourData.slice(startMinute) || [];
|
|
21773
|
+
const secondPart = nextHourData.slice(0, shiftEndTime.minute) || [];
|
|
21774
|
+
idleArray = [...firstPart, ...secondPart];
|
|
21775
|
+
} else {
|
|
21776
|
+
idleArray = currentHourData.slice(0, shiftEndTime.minute) || [];
|
|
21777
|
+
}
|
|
21778
|
+
} else {
|
|
21779
|
+
const currentHourData = idleTimeHourly[actualHour.toString()] || [];
|
|
21780
|
+
const nextHour = (actualHour + 1) % 24;
|
|
21781
|
+
const nextHourData = idleTimeHourly[nextHour.toString()] || [];
|
|
21782
|
+
idleArray = [
|
|
21783
|
+
...currentHourData.slice(startMinute) || [],
|
|
21784
|
+
...nextHourData.slice(0, startMinute) || []
|
|
21785
|
+
];
|
|
21786
|
+
}
|
|
21787
|
+
}
|
|
21788
|
+
} else {
|
|
21789
|
+
const currentHourData = idleTimeHourly[actualHour.toString()] || [];
|
|
21790
|
+
if (i === SHIFT_DURATION - 1 && shiftEndTime && shiftEndTime.minute > 0 && shiftEndTime.minute < 60) {
|
|
21791
|
+
idleArray = currentHourData.slice(0, shiftEndTime.minute) || [];
|
|
21792
|
+
} else {
|
|
21793
|
+
idleArray = currentHourData || [];
|
|
21794
|
+
}
|
|
21795
|
+
}
|
|
21796
|
+
}
|
|
21797
|
+
idleMinutes = idleArray.filter((val) => val === "1" || val === 1).length;
|
|
21437
21798
|
return {
|
|
21438
21799
|
hour: formatHour(i),
|
|
21439
21800
|
timeRange: formatTimeRange(i),
|
|
@@ -21445,7 +21806,7 @@ var HourlyOutputChartComponent = ({
|
|
|
21445
21806
|
idleArray
|
|
21446
21807
|
};
|
|
21447
21808
|
});
|
|
21448
|
-
}, [animatedData, data, pphThreshold, idleTimeHourly, shiftStartTime.hour, formatHour, formatTimeRange]);
|
|
21809
|
+
}, [animatedData, data, pphThreshold, idleTimeHourly, shiftStartTime.hour, shiftStartTime.minute, shiftEndTime, formatHour, formatTimeRange, SHIFT_DURATION]);
|
|
21449
21810
|
const IdleBar = React19__default.useMemo(() => {
|
|
21450
21811
|
if (!idleBarState.visible) return null;
|
|
21451
21812
|
return /* @__PURE__ */ jsx(
|
|
@@ -21605,13 +21966,13 @@ var HourlyOutputChartComponent = ({
|
|
|
21605
21966
|
if (showIdleTime && data2.idleArray) {
|
|
21606
21967
|
let currentRange = null;
|
|
21607
21968
|
data2.idleArray.forEach((val, idx) => {
|
|
21608
|
-
if (val === "1") {
|
|
21969
|
+
if (val === "1" || val === 1) {
|
|
21609
21970
|
if (!currentRange) {
|
|
21610
21971
|
currentRange = { start: idx, end: idx };
|
|
21611
21972
|
} else {
|
|
21612
21973
|
currentRange.end = idx;
|
|
21613
21974
|
}
|
|
21614
|
-
} else if (currentRange) {
|
|
21975
|
+
} else if (val !== "x" && currentRange) {
|
|
21615
21976
|
idleRanges.push(currentRange);
|
|
21616
21977
|
currentRange = null;
|
|
21617
21978
|
}
|
|
@@ -24948,29 +25309,36 @@ var LinePdfGenerator = ({
|
|
|
24948
25309
|
const startHour = parseInt(hours);
|
|
24949
25310
|
const startMinute = parseInt(minutes || "0");
|
|
24950
25311
|
let SHIFT_DURATION = 11;
|
|
25312
|
+
let endHour = startHour + 11;
|
|
25313
|
+
let endMinute = startMinute;
|
|
24951
25314
|
if (endTimeStr) {
|
|
24952
25315
|
const [endHours, endMinutes] = endTimeStr.split(":");
|
|
24953
|
-
|
|
24954
|
-
|
|
25316
|
+
endHour = parseInt(endHours);
|
|
25317
|
+
endMinute = parseInt(endMinutes || "0");
|
|
24955
25318
|
let duration = endHour - startHour;
|
|
24956
25319
|
if (duration <= 0) {
|
|
24957
25320
|
duration += 24;
|
|
24958
25321
|
}
|
|
24959
|
-
const
|
|
24960
|
-
|
|
24961
|
-
duration += minuteDiff / 60;
|
|
24962
|
-
}
|
|
24963
|
-
SHIFT_DURATION = Math.round(duration);
|
|
25322
|
+
const hasPartialLastHour = endMinute > 0 && endMinute < 60;
|
|
25323
|
+
SHIFT_DURATION = hasPartialLastHour ? Math.ceil(duration) : Math.round(duration);
|
|
24964
25324
|
}
|
|
24965
25325
|
return Array.from({ length: SHIFT_DURATION }, (_, i) => {
|
|
25326
|
+
const isLastHour = i === SHIFT_DURATION - 1;
|
|
24966
25327
|
const hourStartTime = /* @__PURE__ */ new Date();
|
|
24967
|
-
hourStartTime.setHours(startHour);
|
|
25328
|
+
hourStartTime.setHours((startHour + i) % 24);
|
|
24968
25329
|
hourStartTime.setMinutes(startMinute);
|
|
24969
25330
|
hourStartTime.setSeconds(0);
|
|
24970
25331
|
hourStartTime.setMilliseconds(0);
|
|
24971
|
-
|
|
24972
|
-
|
|
24973
|
-
|
|
25332
|
+
let hourEndTime = /* @__PURE__ */ new Date();
|
|
25333
|
+
if (isLastHour && endTimeStr) {
|
|
25334
|
+
hourEndTime.setHours(endHour % 24);
|
|
25335
|
+
hourEndTime.setMinutes(endMinute);
|
|
25336
|
+
} else {
|
|
25337
|
+
hourEndTime.setHours((startHour + i + 1) % 24);
|
|
25338
|
+
hourEndTime.setMinutes(startMinute);
|
|
25339
|
+
}
|
|
25340
|
+
hourEndTime.setSeconds(0);
|
|
25341
|
+
hourEndTime.setMilliseconds(0);
|
|
24974
25342
|
const formatTime3 = (date2) => {
|
|
24975
25343
|
return date2.toLocaleTimeString("en-IN", {
|
|
24976
25344
|
hour: "2-digit",
|
|
@@ -24987,17 +25355,132 @@ var LinePdfGenerator = ({
|
|
|
24987
25355
|
const targetOutputPerHour = Math.round(lineInfo.metrics.line_threshold / shiftDuration);
|
|
24988
25356
|
let hourlyActualOutput = [];
|
|
24989
25357
|
if (lineInfo.metrics.output_hourly && Object.keys(lineInfo.metrics.output_hourly).length > 0) {
|
|
24990
|
-
const
|
|
25358
|
+
const [startHourStr, startMinuteStr] = (lineInfo.metrics.shift_start || "6:00").split(":");
|
|
25359
|
+
const startHour = parseInt(startHourStr);
|
|
25360
|
+
const startMinute = parseInt(startMinuteStr || "0");
|
|
25361
|
+
const [endHourStr, endMinuteStr] = (lineInfo.metrics.shift_end || "18:00").split(":");
|
|
25362
|
+
const endMinute = parseInt(endMinuteStr || "0");
|
|
25363
|
+
const hasPartialLastHour = endMinute > 0 && endMinute < 60;
|
|
24991
25364
|
const expectedHours = [];
|
|
24992
25365
|
for (let i = 0; i < shiftDuration; i++) {
|
|
24993
25366
|
expectedHours.push((startHour + i) % 24);
|
|
24994
25367
|
}
|
|
24995
|
-
hourlyActualOutput = expectedHours.map((
|
|
24996
|
-
|
|
24997
|
-
|
|
24998
|
-
|
|
25368
|
+
hourlyActualOutput = expectedHours.map((expectedHour, index) => {
|
|
25369
|
+
let hourSum = 0;
|
|
25370
|
+
const outputHourly = lineInfo.metrics.output_hourly;
|
|
25371
|
+
const hourData = outputHourly[expectedHour.toString()] || [];
|
|
25372
|
+
if (startMinute > 0) {
|
|
25373
|
+
if (index === 0) {
|
|
25374
|
+
if (Array.isArray(hourData)) {
|
|
25375
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
25376
|
+
const val = hourData[i];
|
|
25377
|
+
if (val !== "x" && typeof val === "number") {
|
|
25378
|
+
hourSum += val;
|
|
25379
|
+
}
|
|
25380
|
+
}
|
|
25381
|
+
}
|
|
25382
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
25383
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
25384
|
+
if (Array.isArray(nextHourData)) {
|
|
25385
|
+
for (let i = 0; i < startMinute && i < nextHourData.length; i++) {
|
|
25386
|
+
const val = nextHourData[i];
|
|
25387
|
+
if (val !== "x" && typeof val === "number") {
|
|
25388
|
+
hourSum += val;
|
|
25389
|
+
}
|
|
25390
|
+
}
|
|
25391
|
+
}
|
|
25392
|
+
} else if (index < expectedHours.length - 1) {
|
|
25393
|
+
if (Array.isArray(hourData)) {
|
|
25394
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
25395
|
+
const val = hourData[i];
|
|
25396
|
+
if (val !== "x" && typeof val === "number") {
|
|
25397
|
+
hourSum += val;
|
|
25398
|
+
}
|
|
25399
|
+
}
|
|
25400
|
+
}
|
|
25401
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
25402
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
25403
|
+
if (Array.isArray(nextHourData)) {
|
|
25404
|
+
for (let i = 0; i < startMinute && i < nextHourData.length; i++) {
|
|
25405
|
+
const val = nextHourData[i];
|
|
25406
|
+
if (val !== "x" && typeof val === "number") {
|
|
25407
|
+
hourSum += val;
|
|
25408
|
+
}
|
|
25409
|
+
}
|
|
25410
|
+
}
|
|
25411
|
+
} else {
|
|
25412
|
+
if (hasPartialLastHour && endMinute > 0) {
|
|
25413
|
+
if (startMinute > 0) {
|
|
25414
|
+
if (Array.isArray(hourData)) {
|
|
25415
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
25416
|
+
const val = hourData[i];
|
|
25417
|
+
if (val !== "x" && typeof val === "number") {
|
|
25418
|
+
hourSum += val;
|
|
25419
|
+
}
|
|
25420
|
+
}
|
|
25421
|
+
}
|
|
25422
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
25423
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
25424
|
+
if (Array.isArray(nextHourData)) {
|
|
25425
|
+
for (let i = 0; i < endMinute && i < nextHourData.length; i++) {
|
|
25426
|
+
const val = nextHourData[i];
|
|
25427
|
+
if (val !== "x" && typeof val === "number") {
|
|
25428
|
+
hourSum += val;
|
|
25429
|
+
}
|
|
25430
|
+
}
|
|
25431
|
+
}
|
|
25432
|
+
} else {
|
|
25433
|
+
if (Array.isArray(hourData)) {
|
|
25434
|
+
for (let i = 0; i < endMinute && i < hourData.length; i++) {
|
|
25435
|
+
const val = hourData[i];
|
|
25436
|
+
if (val !== "x" && typeof val === "number") {
|
|
25437
|
+
hourSum += val;
|
|
25438
|
+
}
|
|
25439
|
+
}
|
|
25440
|
+
}
|
|
25441
|
+
}
|
|
25442
|
+
} else {
|
|
25443
|
+
if (Array.isArray(hourData)) {
|
|
25444
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
25445
|
+
const val = hourData[i];
|
|
25446
|
+
if (val !== "x" && typeof val === "number") {
|
|
25447
|
+
hourSum += val;
|
|
25448
|
+
}
|
|
25449
|
+
}
|
|
25450
|
+
}
|
|
25451
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
25452
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
25453
|
+
if (Array.isArray(nextHourData)) {
|
|
25454
|
+
for (let i = 0; i < startMinute && i < nextHourData.length; i++) {
|
|
25455
|
+
const val = nextHourData[i];
|
|
25456
|
+
if (val !== "x" && typeof val === "number") {
|
|
25457
|
+
hourSum += val;
|
|
25458
|
+
}
|
|
25459
|
+
}
|
|
25460
|
+
}
|
|
25461
|
+
}
|
|
25462
|
+
}
|
|
25463
|
+
} else {
|
|
25464
|
+
if (Array.isArray(hourData)) {
|
|
25465
|
+
hourData.forEach((val) => {
|
|
25466
|
+
if (val !== "x" && typeof val === "number") {
|
|
25467
|
+
hourSum += val;
|
|
25468
|
+
}
|
|
25469
|
+
});
|
|
25470
|
+
}
|
|
25471
|
+
if (index === expectedHours.length - 1 && hasPartialLastHour && endMinute > 0) {
|
|
25472
|
+
hourSum = 0;
|
|
25473
|
+
if (Array.isArray(hourData)) {
|
|
25474
|
+
for (let i = 0; i < endMinute && i < hourData.length; i++) {
|
|
25475
|
+
const val = hourData[i];
|
|
25476
|
+
if (val !== "x" && typeof val === "number") {
|
|
25477
|
+
hourSum += val;
|
|
25478
|
+
}
|
|
25479
|
+
}
|
|
25480
|
+
}
|
|
25481
|
+
}
|
|
24999
25482
|
}
|
|
25000
|
-
return
|
|
25483
|
+
return hourSum;
|
|
25001
25484
|
});
|
|
25002
25485
|
} else if (lineInfo.metrics.output_array && lineInfo.metrics.output_array.length > 0) {
|
|
25003
25486
|
hourlyActualOutput = lineInfo.metrics.output_array.reduce((acc, val, i) => {
|
|
@@ -34153,21 +34636,135 @@ var KPIDetailView = ({
|
|
|
34153
34636
|
const shiftStart = metrics2.shift_start || (isNightShift ? "22:00" : "06:00");
|
|
34154
34637
|
const shiftEnd = metrics2.shift_end || (isNightShift ? "06:00" : "14:00");
|
|
34155
34638
|
const startHour = parseInt(shiftStart.split(":")[0]);
|
|
34639
|
+
const startMinute = parseInt(shiftStart.split(":")[1] || "0");
|
|
34156
34640
|
const endHour = parseInt(shiftEnd.split(":")[0]);
|
|
34641
|
+
const endMinute = parseInt(shiftEnd.split(":")[1] || "0");
|
|
34157
34642
|
let shiftDuration = endHour - startHour;
|
|
34158
34643
|
if (shiftDuration <= 0) {
|
|
34159
34644
|
shiftDuration += 24;
|
|
34160
34645
|
}
|
|
34646
|
+
const hasPartialLastHour = endMinute > 0 && endMinute < 60;
|
|
34647
|
+
const hourCount = hasPartialLastHour ? Math.ceil(shiftDuration + endMinute / 60) : shiftDuration;
|
|
34161
34648
|
let expectedHours = [];
|
|
34162
|
-
for (let i = 0; i <
|
|
34649
|
+
for (let i = 0; i < hourCount; i++) {
|
|
34163
34650
|
expectedHours.push((startHour + i) % 24);
|
|
34164
34651
|
}
|
|
34165
|
-
return expectedHours.map((
|
|
34166
|
-
|
|
34167
|
-
|
|
34168
|
-
|
|
34652
|
+
return expectedHours.map((expectedHour, index) => {
|
|
34653
|
+
let hourSum = 0;
|
|
34654
|
+
const outputHourly = metrics2.output_hourly;
|
|
34655
|
+
const hourData = outputHourly[expectedHour.toString()] || [];
|
|
34656
|
+
if (startMinute > 0) {
|
|
34657
|
+
if (index === 0) {
|
|
34658
|
+
if (Array.isArray(hourData)) {
|
|
34659
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
34660
|
+
const val = hourData[i];
|
|
34661
|
+
if (val !== "x" && typeof val === "number") {
|
|
34662
|
+
hourSum += val;
|
|
34663
|
+
}
|
|
34664
|
+
}
|
|
34665
|
+
}
|
|
34666
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
34667
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
34668
|
+
if (Array.isArray(nextHourData)) {
|
|
34669
|
+
for (let i = 0; i < startMinute && i < nextHourData.length; i++) {
|
|
34670
|
+
const val = nextHourData[i];
|
|
34671
|
+
if (val !== "x" && typeof val === "number") {
|
|
34672
|
+
hourSum += val;
|
|
34673
|
+
}
|
|
34674
|
+
}
|
|
34675
|
+
}
|
|
34676
|
+
} else if (index < expectedHours.length - 1) {
|
|
34677
|
+
if (Array.isArray(hourData)) {
|
|
34678
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
34679
|
+
const val = hourData[i];
|
|
34680
|
+
if (val !== "x" && typeof val === "number") {
|
|
34681
|
+
hourSum += val;
|
|
34682
|
+
}
|
|
34683
|
+
}
|
|
34684
|
+
}
|
|
34685
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
34686
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
34687
|
+
if (Array.isArray(nextHourData)) {
|
|
34688
|
+
for (let i = 0; i < startMinute && i < nextHourData.length; i++) {
|
|
34689
|
+
const val = nextHourData[i];
|
|
34690
|
+
if (val !== "x" && typeof val === "number") {
|
|
34691
|
+
hourSum += val;
|
|
34692
|
+
}
|
|
34693
|
+
}
|
|
34694
|
+
}
|
|
34695
|
+
} else {
|
|
34696
|
+
if (hasPartialLastHour && endMinute > 0) {
|
|
34697
|
+
if (startMinute > 0) {
|
|
34698
|
+
if (Array.isArray(hourData)) {
|
|
34699
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
34700
|
+
const val = hourData[i];
|
|
34701
|
+
if (val !== "x" && typeof val === "number") {
|
|
34702
|
+
hourSum += val;
|
|
34703
|
+
}
|
|
34704
|
+
}
|
|
34705
|
+
}
|
|
34706
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
34707
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
34708
|
+
if (Array.isArray(nextHourData)) {
|
|
34709
|
+
for (let i = 0; i < endMinute && i < nextHourData.length; i++) {
|
|
34710
|
+
const val = nextHourData[i];
|
|
34711
|
+
if (val !== "x" && typeof val === "number") {
|
|
34712
|
+
hourSum += val;
|
|
34713
|
+
}
|
|
34714
|
+
}
|
|
34715
|
+
}
|
|
34716
|
+
} else {
|
|
34717
|
+
if (Array.isArray(hourData)) {
|
|
34718
|
+
for (let i = 0; i < endMinute && i < hourData.length; i++) {
|
|
34719
|
+
const val = hourData[i];
|
|
34720
|
+
if (val !== "x" && typeof val === "number") {
|
|
34721
|
+
hourSum += val;
|
|
34722
|
+
}
|
|
34723
|
+
}
|
|
34724
|
+
}
|
|
34725
|
+
}
|
|
34726
|
+
} else {
|
|
34727
|
+
if (Array.isArray(hourData)) {
|
|
34728
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
34729
|
+
const val = hourData[i];
|
|
34730
|
+
if (val !== "x" && typeof val === "number") {
|
|
34731
|
+
hourSum += val;
|
|
34732
|
+
}
|
|
34733
|
+
}
|
|
34734
|
+
}
|
|
34735
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
34736
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
34737
|
+
if (Array.isArray(nextHourData)) {
|
|
34738
|
+
for (let i = 0; i < startMinute && i < nextHourData.length; i++) {
|
|
34739
|
+
const val = nextHourData[i];
|
|
34740
|
+
if (val !== "x" && typeof val === "number") {
|
|
34741
|
+
hourSum += val;
|
|
34742
|
+
}
|
|
34743
|
+
}
|
|
34744
|
+
}
|
|
34745
|
+
}
|
|
34746
|
+
}
|
|
34747
|
+
} else {
|
|
34748
|
+
if (Array.isArray(hourData)) {
|
|
34749
|
+
hourData.forEach((val) => {
|
|
34750
|
+
if (val !== "x" && typeof val === "number") {
|
|
34751
|
+
hourSum += val;
|
|
34752
|
+
}
|
|
34753
|
+
});
|
|
34754
|
+
}
|
|
34755
|
+
if (index === expectedHours.length - 1 && hasPartialLastHour && endMinute > 0) {
|
|
34756
|
+
hourSum = 0;
|
|
34757
|
+
if (Array.isArray(hourData)) {
|
|
34758
|
+
for (let i = 0; i < endMinute && i < hourData.length; i++) {
|
|
34759
|
+
const val = hourData[i];
|
|
34760
|
+
if (val !== "x" && typeof val === "number") {
|
|
34761
|
+
hourSum += val;
|
|
34762
|
+
}
|
|
34763
|
+
}
|
|
34764
|
+
}
|
|
34765
|
+
}
|
|
34169
34766
|
}
|
|
34170
|
-
return
|
|
34767
|
+
return hourSum;
|
|
34171
34768
|
});
|
|
34172
34769
|
}
|
|
34173
34770
|
if (metrics2.output_array) {
|