@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.js
CHANGED
|
@@ -908,20 +908,121 @@ var dashboardService = {
|
|
|
908
908
|
}
|
|
909
909
|
console.log("Expected shift hours:", expectedHours);
|
|
910
910
|
console.log("Available data hours:", Object.keys(outputHourly));
|
|
911
|
-
hourlyActionCounts = expectedHours.map((expectedHour) => {
|
|
912
|
-
let
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
911
|
+
hourlyActionCounts = expectedHours.map((expectedHour, index) => {
|
|
912
|
+
let hourSum = 0;
|
|
913
|
+
const hourData = outputHourly[expectedHour.toString()] || [];
|
|
914
|
+
if (startMinute > 0) {
|
|
915
|
+
if (index === 0) {
|
|
916
|
+
if (Array.isArray(hourData)) {
|
|
917
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
918
|
+
const val = hourData[i];
|
|
919
|
+
if (val !== "x" && typeof val === "number") {
|
|
920
|
+
hourSum += val;
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
925
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
926
|
+
if (Array.isArray(nextHourData)) {
|
|
927
|
+
for (let i = 0; i < startMinute && i < nextHourData.length; i++) {
|
|
928
|
+
const val = nextHourData[i];
|
|
929
|
+
if (val !== "x" && typeof val === "number") {
|
|
930
|
+
hourSum += val;
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
} else if (index < expectedHours.length - 1) {
|
|
935
|
+
if (Array.isArray(hourData)) {
|
|
936
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
937
|
+
const val = hourData[i];
|
|
938
|
+
if (val !== "x" && typeof val === "number") {
|
|
939
|
+
hourSum += val;
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
944
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
945
|
+
if (Array.isArray(nextHourData)) {
|
|
946
|
+
for (let i = 0; i < startMinute && i < nextHourData.length; i++) {
|
|
947
|
+
const val = nextHourData[i];
|
|
948
|
+
if (val !== "x" && typeof val === "number") {
|
|
949
|
+
hourSum += val;
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
} else {
|
|
954
|
+
if (hasPartialLastHour && endMinute > 0) {
|
|
955
|
+
if (startMinute > 0) {
|
|
956
|
+
if (Array.isArray(hourData)) {
|
|
957
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
958
|
+
const val = hourData[i];
|
|
959
|
+
if (val !== "x" && typeof val === "number") {
|
|
960
|
+
hourSum += val;
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
965
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
966
|
+
if (Array.isArray(nextHourData)) {
|
|
967
|
+
for (let i = 0; i < endMinute && i < nextHourData.length; i++) {
|
|
968
|
+
const val = nextHourData[i];
|
|
969
|
+
if (val !== "x" && typeof val === "number") {
|
|
970
|
+
hourSum += val;
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
} else {
|
|
975
|
+
if (Array.isArray(hourData)) {
|
|
976
|
+
for (let i = 0; i < endMinute && i < hourData.length; i++) {
|
|
977
|
+
const val = hourData[i];
|
|
978
|
+
if (val !== "x" && typeof val === "number") {
|
|
979
|
+
hourSum += val;
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
} else {
|
|
985
|
+
if (Array.isArray(hourData)) {
|
|
986
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
987
|
+
const val = hourData[i];
|
|
988
|
+
if (val !== "x" && typeof val === "number") {
|
|
989
|
+
hourSum += val;
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
994
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
995
|
+
if (Array.isArray(nextHourData)) {
|
|
996
|
+
for (let i = 0; i < startMinute && i < nextHourData.length; i++) {
|
|
997
|
+
const val = nextHourData[i];
|
|
998
|
+
if (val !== "x" && typeof val === "number") {
|
|
999
|
+
hourSum += val;
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
} else {
|
|
1006
|
+
if (Array.isArray(hourData)) {
|
|
1007
|
+
hourData.forEach((val) => {
|
|
1008
|
+
if (val !== "x" && typeof val === "number") {
|
|
1009
|
+
hourSum += val;
|
|
1010
|
+
}
|
|
1011
|
+
});
|
|
1012
|
+
}
|
|
1013
|
+
if (index === expectedHours.length - 1 && hasPartialLastHour && endMinute > 0) {
|
|
1014
|
+
hourSum = 0;
|
|
1015
|
+
if (Array.isArray(hourData)) {
|
|
1016
|
+
for (let i = 0; i < endMinute && i < hourData.length; i++) {
|
|
1017
|
+
const val = hourData[i];
|
|
1018
|
+
if (val !== "x" && typeof val === "number") {
|
|
1019
|
+
hourSum += val;
|
|
1020
|
+
}
|
|
920
1021
|
}
|
|
921
1022
|
}
|
|
922
1023
|
}
|
|
923
1024
|
}
|
|
924
|
-
return
|
|
1025
|
+
return hourSum;
|
|
925
1026
|
});
|
|
926
1027
|
console.log("Final hourly action counts:", hourlyActionCounts);
|
|
927
1028
|
} else {
|
|
@@ -2122,136 +2223,142 @@ var WorkspaceHealthService = class _WorkspaceHealthService {
|
|
|
2122
2223
|
const now2 = /* @__PURE__ */ new Date();
|
|
2123
2224
|
const currentHour = now2.getHours();
|
|
2124
2225
|
const currentMinute = now2.getMinutes();
|
|
2125
|
-
|
|
2126
|
-
|
|
2226
|
+
const dayShiftStart = shiftConfig?.dayShift?.startTime || "08:00";
|
|
2227
|
+
const dayShiftEnd = shiftConfig?.dayShift?.endTime || "19:30";
|
|
2228
|
+
const nightShiftStart = shiftConfig?.nightShift?.startTime || "19:30";
|
|
2229
|
+
const nightShiftEnd = shiftConfig?.nightShift?.endTime || "06:00";
|
|
2230
|
+
const parseShiftTime = (timeStr) => {
|
|
2231
|
+
const [hour, minute] = timeStr.split(":").map(Number);
|
|
2232
|
+
return { hour, minute };
|
|
2233
|
+
};
|
|
2234
|
+
let shiftStart, shiftEnd;
|
|
2127
2235
|
if (currentShiftId === 0) {
|
|
2128
|
-
|
|
2129
|
-
|
|
2236
|
+
shiftStart = parseShiftTime(dayShiftStart);
|
|
2237
|
+
shiftEnd = parseShiftTime(dayShiftEnd);
|
|
2130
2238
|
} else {
|
|
2131
|
-
|
|
2132
|
-
|
|
2239
|
+
shiftStart = parseShiftTime(nightShiftStart);
|
|
2240
|
+
shiftEnd = parseShiftTime(nightShiftEnd);
|
|
2133
2241
|
}
|
|
2134
2242
|
let elapsedMinutes = 0;
|
|
2135
2243
|
if (currentShiftId === 0) {
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2244
|
+
const shiftStartTotalMinutes = shiftStart.hour * 60 + shiftStart.minute;
|
|
2245
|
+
const currentTotalMinutes = currentHour * 60 + currentMinute;
|
|
2246
|
+
const shiftEndTotalMinutes = shiftEnd.hour * 60 + shiftEnd.minute;
|
|
2247
|
+
if (currentTotalMinutes >= shiftStartTotalMinutes && currentTotalMinutes < shiftEndTotalMinutes) {
|
|
2248
|
+
elapsedMinutes = currentTotalMinutes - shiftStartTotalMinutes;
|
|
2249
|
+
} else if (currentTotalMinutes >= shiftEndTotalMinutes) {
|
|
2250
|
+
elapsedMinutes = shiftEndTotalMinutes - shiftStartTotalMinutes;
|
|
2140
2251
|
}
|
|
2141
2252
|
} else {
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2253
|
+
const shiftStartTotalMinutes = shiftStart.hour * 60 + shiftStart.minute;
|
|
2254
|
+
const currentTotalMinutes = currentHour * 60 + currentMinute;
|
|
2255
|
+
const shiftEndTotalMinutes = shiftEnd.hour * 60 + shiftEnd.minute;
|
|
2256
|
+
if (currentHour >= shiftStart.hour || currentHour < shiftEnd.hour) {
|
|
2257
|
+
if (currentHour >= shiftStart.hour) {
|
|
2258
|
+
elapsedMinutes = currentTotalMinutes - shiftStartTotalMinutes;
|
|
2259
|
+
} else {
|
|
2260
|
+
elapsedMinutes = 24 * 60 - shiftStartTotalMinutes + currentTotalMinutes;
|
|
2261
|
+
}
|
|
2262
|
+
if (currentHour >= shiftEnd.hour && currentTotalMinutes >= shiftEndTotalMinutes) {
|
|
2263
|
+
const totalShiftMinutes = 24 * 60 - shiftStartTotalMinutes + shiftEndTotalMinutes;
|
|
2264
|
+
elapsedMinutes = Math.min(elapsedMinutes, totalShiftMinutes);
|
|
2265
|
+
}
|
|
2146
2266
|
}
|
|
2147
2267
|
}
|
|
2148
2268
|
const tableName = `performance_metrics_${companyId.replace(/-/g, "_")}`;
|
|
2149
|
-
const query = `
|
|
2150
|
-
WITH workspace_uptime AS (
|
|
2151
|
-
SELECT
|
|
2152
|
-
workspace_id,
|
|
2153
|
-
workspace_display_name,
|
|
2154
|
-
idle_time_hourly,
|
|
2155
|
-
output_hourly,
|
|
2156
|
-
shift_start,
|
|
2157
|
-
shift_end
|
|
2158
|
-
FROM ${tableName}
|
|
2159
|
-
WHERE date = $1::date
|
|
2160
|
-
AND shift_id = $2
|
|
2161
|
-
),
|
|
2162
|
-
calculated_uptime AS (
|
|
2163
|
-
SELECT
|
|
2164
|
-
workspace_id,
|
|
2165
|
-
workspace_display_name,
|
|
2166
|
-
-- Calculate actual minutes from hourly data
|
|
2167
|
-
(
|
|
2168
|
-
SELECT COALESCE(SUM(
|
|
2169
|
-
CASE
|
|
2170
|
-
WHEN jsonb_array_length(idle_time_hourly->key::text) >= 58 THEN 60
|
|
2171
|
-
WHEN jsonb_array_length(idle_time_hourly->key::text) > 0 THEN jsonb_array_length(idle_time_hourly->key::text)
|
|
2172
|
-
ELSE 0
|
|
2173
|
-
END
|
|
2174
|
-
), 0)
|
|
2175
|
-
FROM jsonb_object_keys(idle_time_hourly) AS key
|
|
2176
|
-
WHERE key::int >= $3 AND key::int < $4
|
|
2177
|
-
) +
|
|
2178
|
-
-- Add current hour's data if applicable
|
|
2179
|
-
CASE
|
|
2180
|
-
WHEN $4::int >= $3 AND $4::int < $5 THEN
|
|
2181
|
-
LEAST($6::int,
|
|
2182
|
-
COALESCE(jsonb_array_length(idle_time_hourly->$4::text), 0))
|
|
2183
|
-
ELSE 0
|
|
2184
|
-
END as actual_minutes
|
|
2185
|
-
FROM workspace_uptime
|
|
2186
|
-
)
|
|
2187
|
-
SELECT
|
|
2188
|
-
workspace_id,
|
|
2189
|
-
workspace_display_name,
|
|
2190
|
-
actual_minutes,
|
|
2191
|
-
$7::int as expected_minutes,
|
|
2192
|
-
ROUND(
|
|
2193
|
-
CASE
|
|
2194
|
-
WHEN $7::int > 0 THEN (actual_minutes::numeric / $7::numeric) * 100
|
|
2195
|
-
ELSE 100
|
|
2196
|
-
END, 1
|
|
2197
|
-
) as uptime_percentage
|
|
2198
|
-
FROM calculated_uptime
|
|
2199
|
-
`;
|
|
2200
2269
|
try {
|
|
2201
|
-
const { data, error } = await supabase.
|
|
2202
|
-
query_text: query,
|
|
2203
|
-
params: [
|
|
2204
|
-
currentDate,
|
|
2205
|
-
currentShiftId,
|
|
2206
|
-
shiftStartHour,
|
|
2207
|
-
currentHour,
|
|
2208
|
-
shiftEndHour,
|
|
2209
|
-
currentMinute,
|
|
2210
|
-
elapsedMinutes
|
|
2211
|
-
]
|
|
2212
|
-
}).single();
|
|
2270
|
+
const { data: queryData, error } = await supabase.from(tableName).select("workspace_id, workspace_display_name, output_hourly").eq("date", currentDate).eq("shift_id", currentShiftId);
|
|
2213
2271
|
if (error) {
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2272
|
+
console.error("Error fetching performance metrics:", error);
|
|
2273
|
+
return /* @__PURE__ */ new Map();
|
|
2274
|
+
}
|
|
2275
|
+
const uptimeMap = /* @__PURE__ */ new Map();
|
|
2276
|
+
for (const record of queryData || []) {
|
|
2277
|
+
let actualMinutes = 0;
|
|
2278
|
+
let totalPossibleMinutes = 0;
|
|
2279
|
+
const outputHourly = record.output_hourly || {};
|
|
2280
|
+
const hoursElapsed = Math.ceil(elapsedMinutes / 60);
|
|
2281
|
+
for (let hourIndex = 0; hourIndex < hoursElapsed; hourIndex++) {
|
|
2282
|
+
const actualHour = (shiftStart.hour + hourIndex) % 24;
|
|
2283
|
+
let hourData = [];
|
|
2284
|
+
let minutesInThisHour = 60;
|
|
2285
|
+
if (shiftStart.minute > 0) {
|
|
2286
|
+
if (hourIndex === 0) {
|
|
2287
|
+
const firstHourData = outputHourly[actualHour.toString()] || [];
|
|
2288
|
+
const nextHour = (actualHour + 1) % 24;
|
|
2289
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
2290
|
+
hourData = [
|
|
2291
|
+
...Array.isArray(firstHourData) ? firstHourData.slice(shiftStart.minute) : [],
|
|
2292
|
+
...Array.isArray(nextHourData) ? nextHourData.slice(0, shiftStart.minute) : []
|
|
2293
|
+
];
|
|
2294
|
+
} else if (hourIndex < hoursElapsed - 1) {
|
|
2295
|
+
const currentHourData = outputHourly[actualHour.toString()] || [];
|
|
2296
|
+
const nextHour = (actualHour + 1) % 24;
|
|
2297
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
2298
|
+
hourData = [
|
|
2299
|
+
...Array.isArray(currentHourData) ? currentHourData.slice(shiftStart.minute) : [],
|
|
2300
|
+
...Array.isArray(nextHourData) ? nextHourData.slice(0, shiftStart.minute) : []
|
|
2301
|
+
];
|
|
2302
|
+
} else {
|
|
2303
|
+
const isLastHourPartial = hourIndex === hoursElapsed - 1 && elapsedMinutes % 60 > 0;
|
|
2304
|
+
if (isLastHourPartial) {
|
|
2305
|
+
minutesInThisHour = elapsedMinutes % 60;
|
|
2306
|
+
const currentHourData = outputHourly[actualHour.toString()] || [];
|
|
2307
|
+
if (shiftStart.minute > 0) {
|
|
2308
|
+
const nextHour = (actualHour + 1) % 24;
|
|
2309
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
2310
|
+
const firstPart = Array.isArray(currentHourData) ? currentHourData.slice(shiftStart.minute) : [];
|
|
2311
|
+
const secondPart = Array.isArray(nextHourData) ? nextHourData.slice(0, Math.min(shiftStart.minute, minutesInThisHour)) : [];
|
|
2312
|
+
hourData = [...firstPart, ...secondPart].slice(0, minutesInThisHour);
|
|
2313
|
+
} else {
|
|
2314
|
+
hourData = Array.isArray(currentHourData) ? currentHourData.slice(0, minutesInThisHour) : [];
|
|
2315
|
+
}
|
|
2316
|
+
} else {
|
|
2317
|
+
const currentHourData = outputHourly[actualHour.toString()] || [];
|
|
2318
|
+
const nextHour = (actualHour + 1) % 24;
|
|
2319
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
2320
|
+
hourData = [
|
|
2321
|
+
...Array.isArray(currentHourData) ? currentHourData.slice(shiftStart.minute) : [],
|
|
2322
|
+
...Array.isArray(nextHourData) ? nextHourData.slice(0, shiftStart.minute) : []
|
|
2323
|
+
];
|
|
2324
|
+
}
|
|
2325
|
+
}
|
|
2326
|
+
} else {
|
|
2327
|
+
hourData = outputHourly[actualHour.toString()] || [];
|
|
2328
|
+
if (hourIndex === hoursElapsed - 1) {
|
|
2329
|
+
const remainingMinutes = elapsedMinutes % 60;
|
|
2330
|
+
if (remainingMinutes > 0) {
|
|
2331
|
+
minutesInThisHour = remainingMinutes;
|
|
2332
|
+
hourData = Array.isArray(hourData) ? hourData.slice(0, minutesInThisHour) : [];
|
|
2232
2333
|
}
|
|
2233
2334
|
}
|
|
2234
2335
|
}
|
|
2235
|
-
const
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
});
|
|
2336
|
+
const hasXArchitecture = Array.isArray(hourData) && hourData.some((val) => val === "x");
|
|
2337
|
+
if (hasXArchitecture) {
|
|
2338
|
+
const xCount = hourData.filter((val) => val === "x").length;
|
|
2339
|
+
if (xCount <= 2) {
|
|
2340
|
+
actualMinutes += minutesInThisHour;
|
|
2341
|
+
} else {
|
|
2342
|
+
const uptimeCount = hourData.filter((val) => val !== "x").length;
|
|
2343
|
+
actualMinutes += Math.min(uptimeCount, minutesInThisHour);
|
|
2344
|
+
}
|
|
2345
|
+
} else {
|
|
2346
|
+
const arrayLength = Array.isArray(hourData) ? hourData.length : 0;
|
|
2347
|
+
if (arrayLength >= Math.min(58, minutesInThisHour - 2)) {
|
|
2348
|
+
actualMinutes += minutesInThisHour;
|
|
2349
|
+
} else {
|
|
2350
|
+
actualMinutes += Math.min(arrayLength, minutesInThisHour);
|
|
2351
|
+
}
|
|
2352
|
+
}
|
|
2353
|
+
totalPossibleMinutes += minutesInThisHour;
|
|
2254
2354
|
}
|
|
2355
|
+
const percentage = totalPossibleMinutes > 0 ? Math.round(actualMinutes / totalPossibleMinutes * 1e3) / 10 : 100;
|
|
2356
|
+
uptimeMap.set(record.workspace_id, {
|
|
2357
|
+
expectedMinutes: totalPossibleMinutes,
|
|
2358
|
+
actualMinutes,
|
|
2359
|
+
percentage,
|
|
2360
|
+
lastCalculated: (/* @__PURE__ */ new Date()).toISOString()
|
|
2361
|
+
});
|
|
2255
2362
|
}
|
|
2256
2363
|
return uptimeMap;
|
|
2257
2364
|
} catch (error) {
|
|
@@ -5720,20 +5827,121 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
|
|
|
5720
5827
|
}
|
|
5721
5828
|
console.log("Expected shift hours (fallback):", expectedHours);
|
|
5722
5829
|
console.log("Available data hours (fallback):", Object.keys(outputHourly2));
|
|
5723
|
-
hourlyActionCounts2 = expectedHours.map((expectedHour) => {
|
|
5724
|
-
let
|
|
5725
|
-
|
|
5726
|
-
|
|
5727
|
-
|
|
5728
|
-
|
|
5729
|
-
|
|
5730
|
-
|
|
5731
|
-
|
|
5830
|
+
hourlyActionCounts2 = expectedHours.map((expectedHour, index) => {
|
|
5831
|
+
let hourSum = 0;
|
|
5832
|
+
const hourData = outputHourly2[expectedHour.toString()] || [];
|
|
5833
|
+
if (startMinute > 0) {
|
|
5834
|
+
if (index === 0) {
|
|
5835
|
+
if (Array.isArray(hourData)) {
|
|
5836
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
5837
|
+
const val = hourData[i];
|
|
5838
|
+
if (val !== "x" && typeof val === "number") {
|
|
5839
|
+
hourSum += val;
|
|
5840
|
+
}
|
|
5841
|
+
}
|
|
5842
|
+
}
|
|
5843
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
5844
|
+
const nextHourData = outputHourly2[nextHour.toString()] || [];
|
|
5845
|
+
if (Array.isArray(nextHourData)) {
|
|
5846
|
+
for (let i = 0; i < startMinute && i < nextHourData.length; i++) {
|
|
5847
|
+
const val = nextHourData[i];
|
|
5848
|
+
if (val !== "x" && typeof val === "number") {
|
|
5849
|
+
hourSum += val;
|
|
5850
|
+
}
|
|
5851
|
+
}
|
|
5852
|
+
}
|
|
5853
|
+
} else if (index < expectedHours.length - 1) {
|
|
5854
|
+
if (Array.isArray(hourData)) {
|
|
5855
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
5856
|
+
const val = hourData[i];
|
|
5857
|
+
if (val !== "x" && typeof val === "number") {
|
|
5858
|
+
hourSum += val;
|
|
5859
|
+
}
|
|
5860
|
+
}
|
|
5861
|
+
}
|
|
5862
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
5863
|
+
const nextHourData = outputHourly2[nextHour.toString()] || [];
|
|
5864
|
+
if (Array.isArray(nextHourData)) {
|
|
5865
|
+
for (let i = 0; i < startMinute && i < nextHourData.length; i++) {
|
|
5866
|
+
const val = nextHourData[i];
|
|
5867
|
+
if (val !== "x" && typeof val === "number") {
|
|
5868
|
+
hourSum += val;
|
|
5869
|
+
}
|
|
5870
|
+
}
|
|
5871
|
+
}
|
|
5872
|
+
} else {
|
|
5873
|
+
if (hasPartialLastHour && endMinute > 0) {
|
|
5874
|
+
if (startMinute > 0) {
|
|
5875
|
+
if (Array.isArray(hourData)) {
|
|
5876
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
5877
|
+
const val = hourData[i];
|
|
5878
|
+
if (val !== "x" && typeof val === "number") {
|
|
5879
|
+
hourSum += val;
|
|
5880
|
+
}
|
|
5881
|
+
}
|
|
5882
|
+
}
|
|
5883
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
5884
|
+
const nextHourData = outputHourly2[nextHour.toString()] || [];
|
|
5885
|
+
if (Array.isArray(nextHourData)) {
|
|
5886
|
+
for (let i = 0; i < endMinute && i < nextHourData.length; i++) {
|
|
5887
|
+
const val = nextHourData[i];
|
|
5888
|
+
if (val !== "x" && typeof val === "number") {
|
|
5889
|
+
hourSum += val;
|
|
5890
|
+
}
|
|
5891
|
+
}
|
|
5892
|
+
}
|
|
5893
|
+
} else {
|
|
5894
|
+
if (Array.isArray(hourData)) {
|
|
5895
|
+
for (let i = 0; i < endMinute && i < hourData.length; i++) {
|
|
5896
|
+
const val = hourData[i];
|
|
5897
|
+
if (val !== "x" && typeof val === "number") {
|
|
5898
|
+
hourSum += val;
|
|
5899
|
+
}
|
|
5900
|
+
}
|
|
5901
|
+
}
|
|
5902
|
+
}
|
|
5903
|
+
} else {
|
|
5904
|
+
if (Array.isArray(hourData)) {
|
|
5905
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
5906
|
+
const val = hourData[i];
|
|
5907
|
+
if (val !== "x" && typeof val === "number") {
|
|
5908
|
+
hourSum += val;
|
|
5909
|
+
}
|
|
5910
|
+
}
|
|
5911
|
+
}
|
|
5912
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
5913
|
+
const nextHourData = outputHourly2[nextHour.toString()] || [];
|
|
5914
|
+
if (Array.isArray(nextHourData)) {
|
|
5915
|
+
for (let i = 0; i < startMinute && i < nextHourData.length; i++) {
|
|
5916
|
+
const val = nextHourData[i];
|
|
5917
|
+
if (val !== "x" && typeof val === "number") {
|
|
5918
|
+
hourSum += val;
|
|
5919
|
+
}
|
|
5920
|
+
}
|
|
5921
|
+
}
|
|
5922
|
+
}
|
|
5923
|
+
}
|
|
5924
|
+
} else {
|
|
5925
|
+
if (Array.isArray(hourData)) {
|
|
5926
|
+
hourData.forEach((val) => {
|
|
5927
|
+
if (val !== "x" && typeof val === "number") {
|
|
5928
|
+
hourSum += val;
|
|
5929
|
+
}
|
|
5930
|
+
});
|
|
5931
|
+
}
|
|
5932
|
+
if (index === expectedHours.length - 1 && hasPartialLastHour && endMinute > 0) {
|
|
5933
|
+
hourSum = 0;
|
|
5934
|
+
if (Array.isArray(hourData)) {
|
|
5935
|
+
for (let i = 0; i < endMinute && i < hourData.length; i++) {
|
|
5936
|
+
const val = hourData[i];
|
|
5937
|
+
if (val !== "x" && typeof val === "number") {
|
|
5938
|
+
hourSum += val;
|
|
5939
|
+
}
|
|
5732
5940
|
}
|
|
5733
5941
|
}
|
|
5734
5942
|
}
|
|
5735
5943
|
}
|
|
5736
|
-
return
|
|
5944
|
+
return hourSum;
|
|
5737
5945
|
});
|
|
5738
5946
|
console.log("Final hourly action counts (fallback):", hourlyActionCounts2);
|
|
5739
5947
|
} else {
|
|
@@ -5835,20 +6043,121 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
|
|
|
5835
6043
|
}
|
|
5836
6044
|
console.log("Expected shift hours:", expectedHours);
|
|
5837
6045
|
console.log("Available data hours:", Object.keys(outputHourly));
|
|
5838
|
-
hourlyActionCounts = expectedHours.map((expectedHour) => {
|
|
5839
|
-
let
|
|
5840
|
-
|
|
5841
|
-
|
|
5842
|
-
|
|
5843
|
-
|
|
5844
|
-
|
|
5845
|
-
|
|
5846
|
-
|
|
6046
|
+
hourlyActionCounts = expectedHours.map((expectedHour, index) => {
|
|
6047
|
+
let hourSum = 0;
|
|
6048
|
+
const hourData = outputHourly[expectedHour.toString()] || [];
|
|
6049
|
+
if (startMinute > 0) {
|
|
6050
|
+
if (index === 0) {
|
|
6051
|
+
if (Array.isArray(hourData)) {
|
|
6052
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
6053
|
+
const val = hourData[i];
|
|
6054
|
+
if (val !== "x" && typeof val === "number") {
|
|
6055
|
+
hourSum += val;
|
|
6056
|
+
}
|
|
6057
|
+
}
|
|
6058
|
+
}
|
|
6059
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
6060
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
6061
|
+
if (Array.isArray(nextHourData)) {
|
|
6062
|
+
for (let i = 0; i < startMinute && i < nextHourData.length; i++) {
|
|
6063
|
+
const val = nextHourData[i];
|
|
6064
|
+
if (val !== "x" && typeof val === "number") {
|
|
6065
|
+
hourSum += val;
|
|
6066
|
+
}
|
|
6067
|
+
}
|
|
6068
|
+
}
|
|
6069
|
+
} else if (index < expectedHours.length - 1) {
|
|
6070
|
+
if (Array.isArray(hourData)) {
|
|
6071
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
6072
|
+
const val = hourData[i];
|
|
6073
|
+
if (val !== "x" && typeof val === "number") {
|
|
6074
|
+
hourSum += val;
|
|
6075
|
+
}
|
|
6076
|
+
}
|
|
6077
|
+
}
|
|
6078
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
6079
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
6080
|
+
if (Array.isArray(nextHourData)) {
|
|
6081
|
+
for (let i = 0; i < startMinute && i < nextHourData.length; i++) {
|
|
6082
|
+
const val = nextHourData[i];
|
|
6083
|
+
if (val !== "x" && typeof val === "number") {
|
|
6084
|
+
hourSum += val;
|
|
6085
|
+
}
|
|
6086
|
+
}
|
|
6087
|
+
}
|
|
6088
|
+
} else {
|
|
6089
|
+
if (hasPartialLastHour && endMinute > 0) {
|
|
6090
|
+
if (startMinute > 0) {
|
|
6091
|
+
if (Array.isArray(hourData)) {
|
|
6092
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
6093
|
+
const val = hourData[i];
|
|
6094
|
+
if (val !== "x" && typeof val === "number") {
|
|
6095
|
+
hourSum += val;
|
|
6096
|
+
}
|
|
6097
|
+
}
|
|
6098
|
+
}
|
|
6099
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
6100
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
6101
|
+
if (Array.isArray(nextHourData)) {
|
|
6102
|
+
for (let i = 0; i < endMinute && i < nextHourData.length; i++) {
|
|
6103
|
+
const val = nextHourData[i];
|
|
6104
|
+
if (val !== "x" && typeof val === "number") {
|
|
6105
|
+
hourSum += val;
|
|
6106
|
+
}
|
|
6107
|
+
}
|
|
6108
|
+
}
|
|
6109
|
+
} else {
|
|
6110
|
+
if (Array.isArray(hourData)) {
|
|
6111
|
+
for (let i = 0; i < endMinute && i < hourData.length; i++) {
|
|
6112
|
+
const val = hourData[i];
|
|
6113
|
+
if (val !== "x" && typeof val === "number") {
|
|
6114
|
+
hourSum += val;
|
|
6115
|
+
}
|
|
6116
|
+
}
|
|
6117
|
+
}
|
|
6118
|
+
}
|
|
6119
|
+
} else {
|
|
6120
|
+
if (Array.isArray(hourData)) {
|
|
6121
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
6122
|
+
const val = hourData[i];
|
|
6123
|
+
if (val !== "x" && typeof val === "number") {
|
|
6124
|
+
hourSum += val;
|
|
6125
|
+
}
|
|
6126
|
+
}
|
|
6127
|
+
}
|
|
6128
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
6129
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
6130
|
+
if (Array.isArray(nextHourData)) {
|
|
6131
|
+
for (let i = 0; i < startMinute && i < nextHourData.length; i++) {
|
|
6132
|
+
const val = nextHourData[i];
|
|
6133
|
+
if (val !== "x" && typeof val === "number") {
|
|
6134
|
+
hourSum += val;
|
|
6135
|
+
}
|
|
6136
|
+
}
|
|
6137
|
+
}
|
|
6138
|
+
}
|
|
6139
|
+
}
|
|
6140
|
+
} else {
|
|
6141
|
+
if (Array.isArray(hourData)) {
|
|
6142
|
+
hourData.forEach((val) => {
|
|
6143
|
+
if (val !== "x" && typeof val === "number") {
|
|
6144
|
+
hourSum += val;
|
|
6145
|
+
}
|
|
6146
|
+
});
|
|
6147
|
+
}
|
|
6148
|
+
if (index === expectedHours.length - 1 && hasPartialLastHour && endMinute > 0) {
|
|
6149
|
+
hourSum = 0;
|
|
6150
|
+
if (Array.isArray(hourData)) {
|
|
6151
|
+
for (let i = 0; i < endMinute && i < hourData.length; i++) {
|
|
6152
|
+
const val = hourData[i];
|
|
6153
|
+
if (val !== "x" && typeof val === "number") {
|
|
6154
|
+
hourSum += val;
|
|
6155
|
+
}
|
|
5847
6156
|
}
|
|
5848
6157
|
}
|
|
5849
6158
|
}
|
|
5850
6159
|
}
|
|
5851
|
-
return
|
|
6160
|
+
return hourSum;
|
|
5852
6161
|
});
|
|
5853
6162
|
console.log("Final hourly action counts:", hourlyActionCounts);
|
|
5854
6163
|
} else {
|
|
@@ -21462,8 +21771,60 @@ var HourlyOutputChartComponent = ({
|
|
|
21462
21771
|
const chartData = React19__namespace.default.useMemo(() => {
|
|
21463
21772
|
return Array.from({ length: SHIFT_DURATION }, (_, i) => {
|
|
21464
21773
|
const actualHour = (shiftStartTime.hour + i) % 24;
|
|
21465
|
-
const
|
|
21466
|
-
|
|
21774
|
+
const startMinute = shiftStartTime.minute;
|
|
21775
|
+
let idleArray = [];
|
|
21776
|
+
let idleMinutes = 0;
|
|
21777
|
+
if (idleTimeHourly) {
|
|
21778
|
+
if (startMinute > 0) {
|
|
21779
|
+
if (i === 0) {
|
|
21780
|
+
const firstHourData = idleTimeHourly[actualHour.toString()] || [];
|
|
21781
|
+
const nextHour = (actualHour + 1) % 24;
|
|
21782
|
+
const nextHourData = idleTimeHourly[nextHour.toString()] || [];
|
|
21783
|
+
idleArray = [
|
|
21784
|
+
...firstHourData.slice(startMinute) || [],
|
|
21785
|
+
...nextHourData.slice(0, startMinute) || []
|
|
21786
|
+
];
|
|
21787
|
+
} else if (i < SHIFT_DURATION - 1) {
|
|
21788
|
+
const currentHourData = idleTimeHourly[actualHour.toString()] || [];
|
|
21789
|
+
const nextHour = (actualHour + 1) % 24;
|
|
21790
|
+
const nextHourData = idleTimeHourly[nextHour.toString()] || [];
|
|
21791
|
+
idleArray = [
|
|
21792
|
+
...currentHourData.slice(startMinute) || [],
|
|
21793
|
+
...nextHourData.slice(0, startMinute) || []
|
|
21794
|
+
];
|
|
21795
|
+
} else {
|
|
21796
|
+
const hasPartialLastHour2 = shiftEndTime && shiftEndTime.minute > 0 && shiftEndTime.minute < 60;
|
|
21797
|
+
if (hasPartialLastHour2) {
|
|
21798
|
+
const currentHourData = idleTimeHourly[actualHour.toString()] || [];
|
|
21799
|
+
const nextHour = (actualHour + 1) % 24;
|
|
21800
|
+
const nextHourData = idleTimeHourly[nextHour.toString()] || [];
|
|
21801
|
+
if (startMinute > 0) {
|
|
21802
|
+
const firstPart = currentHourData.slice(startMinute) || [];
|
|
21803
|
+
const secondPart = nextHourData.slice(0, shiftEndTime.minute) || [];
|
|
21804
|
+
idleArray = [...firstPart, ...secondPart];
|
|
21805
|
+
} else {
|
|
21806
|
+
idleArray = currentHourData.slice(0, shiftEndTime.minute) || [];
|
|
21807
|
+
}
|
|
21808
|
+
} else {
|
|
21809
|
+
const currentHourData = idleTimeHourly[actualHour.toString()] || [];
|
|
21810
|
+
const nextHour = (actualHour + 1) % 24;
|
|
21811
|
+
const nextHourData = idleTimeHourly[nextHour.toString()] || [];
|
|
21812
|
+
idleArray = [
|
|
21813
|
+
...currentHourData.slice(startMinute) || [],
|
|
21814
|
+
...nextHourData.slice(0, startMinute) || []
|
|
21815
|
+
];
|
|
21816
|
+
}
|
|
21817
|
+
}
|
|
21818
|
+
} else {
|
|
21819
|
+
const currentHourData = idleTimeHourly[actualHour.toString()] || [];
|
|
21820
|
+
if (i === SHIFT_DURATION - 1 && shiftEndTime && shiftEndTime.minute > 0 && shiftEndTime.minute < 60) {
|
|
21821
|
+
idleArray = currentHourData.slice(0, shiftEndTime.minute) || [];
|
|
21822
|
+
} else {
|
|
21823
|
+
idleArray = currentHourData || [];
|
|
21824
|
+
}
|
|
21825
|
+
}
|
|
21826
|
+
}
|
|
21827
|
+
idleMinutes = idleArray.filter((val) => val === "1" || val === 1).length;
|
|
21467
21828
|
return {
|
|
21468
21829
|
hour: formatHour(i),
|
|
21469
21830
|
timeRange: formatTimeRange(i),
|
|
@@ -21475,7 +21836,7 @@ var HourlyOutputChartComponent = ({
|
|
|
21475
21836
|
idleArray
|
|
21476
21837
|
};
|
|
21477
21838
|
});
|
|
21478
|
-
}, [animatedData, data, pphThreshold, idleTimeHourly, shiftStartTime.hour, formatHour, formatTimeRange]);
|
|
21839
|
+
}, [animatedData, data, pphThreshold, idleTimeHourly, shiftStartTime.hour, shiftStartTime.minute, shiftEndTime, formatHour, formatTimeRange, SHIFT_DURATION]);
|
|
21479
21840
|
const IdleBar = React19__namespace.default.useMemo(() => {
|
|
21480
21841
|
if (!idleBarState.visible) return null;
|
|
21481
21842
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -21635,13 +21996,13 @@ var HourlyOutputChartComponent = ({
|
|
|
21635
21996
|
if (showIdleTime && data2.idleArray) {
|
|
21636
21997
|
let currentRange = null;
|
|
21637
21998
|
data2.idleArray.forEach((val, idx) => {
|
|
21638
|
-
if (val === "1") {
|
|
21999
|
+
if (val === "1" || val === 1) {
|
|
21639
22000
|
if (!currentRange) {
|
|
21640
22001
|
currentRange = { start: idx, end: idx };
|
|
21641
22002
|
} else {
|
|
21642
22003
|
currentRange.end = idx;
|
|
21643
22004
|
}
|
|
21644
|
-
} else if (currentRange) {
|
|
22005
|
+
} else if (val !== "x" && currentRange) {
|
|
21645
22006
|
idleRanges.push(currentRange);
|
|
21646
22007
|
currentRange = null;
|
|
21647
22008
|
}
|
|
@@ -24978,29 +25339,36 @@ var LinePdfGenerator = ({
|
|
|
24978
25339
|
const startHour = parseInt(hours);
|
|
24979
25340
|
const startMinute = parseInt(minutes || "0");
|
|
24980
25341
|
let SHIFT_DURATION = 11;
|
|
25342
|
+
let endHour = startHour + 11;
|
|
25343
|
+
let endMinute = startMinute;
|
|
24981
25344
|
if (endTimeStr) {
|
|
24982
25345
|
const [endHours, endMinutes] = endTimeStr.split(":");
|
|
24983
|
-
|
|
24984
|
-
|
|
25346
|
+
endHour = parseInt(endHours);
|
|
25347
|
+
endMinute = parseInt(endMinutes || "0");
|
|
24985
25348
|
let duration = endHour - startHour;
|
|
24986
25349
|
if (duration <= 0) {
|
|
24987
25350
|
duration += 24;
|
|
24988
25351
|
}
|
|
24989
|
-
const
|
|
24990
|
-
|
|
24991
|
-
duration += minuteDiff / 60;
|
|
24992
|
-
}
|
|
24993
|
-
SHIFT_DURATION = Math.round(duration);
|
|
25352
|
+
const hasPartialLastHour = endMinute > 0 && endMinute < 60;
|
|
25353
|
+
SHIFT_DURATION = hasPartialLastHour ? Math.ceil(duration) : Math.round(duration);
|
|
24994
25354
|
}
|
|
24995
25355
|
return Array.from({ length: SHIFT_DURATION }, (_, i) => {
|
|
25356
|
+
const isLastHour = i === SHIFT_DURATION - 1;
|
|
24996
25357
|
const hourStartTime = /* @__PURE__ */ new Date();
|
|
24997
|
-
hourStartTime.setHours(startHour);
|
|
25358
|
+
hourStartTime.setHours((startHour + i) % 24);
|
|
24998
25359
|
hourStartTime.setMinutes(startMinute);
|
|
24999
25360
|
hourStartTime.setSeconds(0);
|
|
25000
25361
|
hourStartTime.setMilliseconds(0);
|
|
25001
|
-
|
|
25002
|
-
|
|
25003
|
-
|
|
25362
|
+
let hourEndTime = /* @__PURE__ */ new Date();
|
|
25363
|
+
if (isLastHour && endTimeStr) {
|
|
25364
|
+
hourEndTime.setHours(endHour % 24);
|
|
25365
|
+
hourEndTime.setMinutes(endMinute);
|
|
25366
|
+
} else {
|
|
25367
|
+
hourEndTime.setHours((startHour + i + 1) % 24);
|
|
25368
|
+
hourEndTime.setMinutes(startMinute);
|
|
25369
|
+
}
|
|
25370
|
+
hourEndTime.setSeconds(0);
|
|
25371
|
+
hourEndTime.setMilliseconds(0);
|
|
25004
25372
|
const formatTime3 = (date2) => {
|
|
25005
25373
|
return date2.toLocaleTimeString("en-IN", {
|
|
25006
25374
|
hour: "2-digit",
|
|
@@ -25017,17 +25385,132 @@ var LinePdfGenerator = ({
|
|
|
25017
25385
|
const targetOutputPerHour = Math.round(lineInfo.metrics.line_threshold / shiftDuration);
|
|
25018
25386
|
let hourlyActualOutput = [];
|
|
25019
25387
|
if (lineInfo.metrics.output_hourly && Object.keys(lineInfo.metrics.output_hourly).length > 0) {
|
|
25020
|
-
const
|
|
25388
|
+
const [startHourStr, startMinuteStr] = (lineInfo.metrics.shift_start || "6:00").split(":");
|
|
25389
|
+
const startHour = parseInt(startHourStr);
|
|
25390
|
+
const startMinute = parseInt(startMinuteStr || "0");
|
|
25391
|
+
const [endHourStr, endMinuteStr] = (lineInfo.metrics.shift_end || "18:00").split(":");
|
|
25392
|
+
const endMinute = parseInt(endMinuteStr || "0");
|
|
25393
|
+
const hasPartialLastHour = endMinute > 0 && endMinute < 60;
|
|
25021
25394
|
const expectedHours = [];
|
|
25022
25395
|
for (let i = 0; i < shiftDuration; i++) {
|
|
25023
25396
|
expectedHours.push((startHour + i) % 24);
|
|
25024
25397
|
}
|
|
25025
|
-
hourlyActualOutput = expectedHours.map((
|
|
25026
|
-
|
|
25027
|
-
|
|
25028
|
-
|
|
25398
|
+
hourlyActualOutput = expectedHours.map((expectedHour, index) => {
|
|
25399
|
+
let hourSum = 0;
|
|
25400
|
+
const outputHourly = lineInfo.metrics.output_hourly;
|
|
25401
|
+
const hourData = outputHourly[expectedHour.toString()] || [];
|
|
25402
|
+
if (startMinute > 0) {
|
|
25403
|
+
if (index === 0) {
|
|
25404
|
+
if (Array.isArray(hourData)) {
|
|
25405
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
25406
|
+
const val = hourData[i];
|
|
25407
|
+
if (val !== "x" && typeof val === "number") {
|
|
25408
|
+
hourSum += val;
|
|
25409
|
+
}
|
|
25410
|
+
}
|
|
25411
|
+
}
|
|
25412
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
25413
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
25414
|
+
if (Array.isArray(nextHourData)) {
|
|
25415
|
+
for (let i = 0; i < startMinute && i < nextHourData.length; i++) {
|
|
25416
|
+
const val = nextHourData[i];
|
|
25417
|
+
if (val !== "x" && typeof val === "number") {
|
|
25418
|
+
hourSum += val;
|
|
25419
|
+
}
|
|
25420
|
+
}
|
|
25421
|
+
}
|
|
25422
|
+
} else if (index < expectedHours.length - 1) {
|
|
25423
|
+
if (Array.isArray(hourData)) {
|
|
25424
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
25425
|
+
const val = hourData[i];
|
|
25426
|
+
if (val !== "x" && typeof val === "number") {
|
|
25427
|
+
hourSum += val;
|
|
25428
|
+
}
|
|
25429
|
+
}
|
|
25430
|
+
}
|
|
25431
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
25432
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
25433
|
+
if (Array.isArray(nextHourData)) {
|
|
25434
|
+
for (let i = 0; i < startMinute && i < nextHourData.length; i++) {
|
|
25435
|
+
const val = nextHourData[i];
|
|
25436
|
+
if (val !== "x" && typeof val === "number") {
|
|
25437
|
+
hourSum += val;
|
|
25438
|
+
}
|
|
25439
|
+
}
|
|
25440
|
+
}
|
|
25441
|
+
} else {
|
|
25442
|
+
if (hasPartialLastHour && endMinute > 0) {
|
|
25443
|
+
if (startMinute > 0) {
|
|
25444
|
+
if (Array.isArray(hourData)) {
|
|
25445
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
25446
|
+
const val = hourData[i];
|
|
25447
|
+
if (val !== "x" && typeof val === "number") {
|
|
25448
|
+
hourSum += val;
|
|
25449
|
+
}
|
|
25450
|
+
}
|
|
25451
|
+
}
|
|
25452
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
25453
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
25454
|
+
if (Array.isArray(nextHourData)) {
|
|
25455
|
+
for (let i = 0; i < endMinute && i < nextHourData.length; i++) {
|
|
25456
|
+
const val = nextHourData[i];
|
|
25457
|
+
if (val !== "x" && typeof val === "number") {
|
|
25458
|
+
hourSum += val;
|
|
25459
|
+
}
|
|
25460
|
+
}
|
|
25461
|
+
}
|
|
25462
|
+
} else {
|
|
25463
|
+
if (Array.isArray(hourData)) {
|
|
25464
|
+
for (let i = 0; i < endMinute && i < hourData.length; i++) {
|
|
25465
|
+
const val = hourData[i];
|
|
25466
|
+
if (val !== "x" && typeof val === "number") {
|
|
25467
|
+
hourSum += val;
|
|
25468
|
+
}
|
|
25469
|
+
}
|
|
25470
|
+
}
|
|
25471
|
+
}
|
|
25472
|
+
} else {
|
|
25473
|
+
if (Array.isArray(hourData)) {
|
|
25474
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
25475
|
+
const val = hourData[i];
|
|
25476
|
+
if (val !== "x" && typeof val === "number") {
|
|
25477
|
+
hourSum += val;
|
|
25478
|
+
}
|
|
25479
|
+
}
|
|
25480
|
+
}
|
|
25481
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
25482
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
25483
|
+
if (Array.isArray(nextHourData)) {
|
|
25484
|
+
for (let i = 0; i < startMinute && i < nextHourData.length; i++) {
|
|
25485
|
+
const val = nextHourData[i];
|
|
25486
|
+
if (val !== "x" && typeof val === "number") {
|
|
25487
|
+
hourSum += val;
|
|
25488
|
+
}
|
|
25489
|
+
}
|
|
25490
|
+
}
|
|
25491
|
+
}
|
|
25492
|
+
}
|
|
25493
|
+
} else {
|
|
25494
|
+
if (Array.isArray(hourData)) {
|
|
25495
|
+
hourData.forEach((val) => {
|
|
25496
|
+
if (val !== "x" && typeof val === "number") {
|
|
25497
|
+
hourSum += val;
|
|
25498
|
+
}
|
|
25499
|
+
});
|
|
25500
|
+
}
|
|
25501
|
+
if (index === expectedHours.length - 1 && hasPartialLastHour && endMinute > 0) {
|
|
25502
|
+
hourSum = 0;
|
|
25503
|
+
if (Array.isArray(hourData)) {
|
|
25504
|
+
for (let i = 0; i < endMinute && i < hourData.length; i++) {
|
|
25505
|
+
const val = hourData[i];
|
|
25506
|
+
if (val !== "x" && typeof val === "number") {
|
|
25507
|
+
hourSum += val;
|
|
25508
|
+
}
|
|
25509
|
+
}
|
|
25510
|
+
}
|
|
25511
|
+
}
|
|
25029
25512
|
}
|
|
25030
|
-
return
|
|
25513
|
+
return hourSum;
|
|
25031
25514
|
});
|
|
25032
25515
|
} else if (lineInfo.metrics.output_array && lineInfo.metrics.output_array.length > 0) {
|
|
25033
25516
|
hourlyActualOutput = lineInfo.metrics.output_array.reduce((acc, val, i) => {
|
|
@@ -34183,21 +34666,135 @@ var KPIDetailView = ({
|
|
|
34183
34666
|
const shiftStart = metrics2.shift_start || (isNightShift ? "22:00" : "06:00");
|
|
34184
34667
|
const shiftEnd = metrics2.shift_end || (isNightShift ? "06:00" : "14:00");
|
|
34185
34668
|
const startHour = parseInt(shiftStart.split(":")[0]);
|
|
34669
|
+
const startMinute = parseInt(shiftStart.split(":")[1] || "0");
|
|
34186
34670
|
const endHour = parseInt(shiftEnd.split(":")[0]);
|
|
34671
|
+
const endMinute = parseInt(shiftEnd.split(":")[1] || "0");
|
|
34187
34672
|
let shiftDuration = endHour - startHour;
|
|
34188
34673
|
if (shiftDuration <= 0) {
|
|
34189
34674
|
shiftDuration += 24;
|
|
34190
34675
|
}
|
|
34676
|
+
const hasPartialLastHour = endMinute > 0 && endMinute < 60;
|
|
34677
|
+
const hourCount = hasPartialLastHour ? Math.ceil(shiftDuration + endMinute / 60) : shiftDuration;
|
|
34191
34678
|
let expectedHours = [];
|
|
34192
|
-
for (let i = 0; i <
|
|
34679
|
+
for (let i = 0; i < hourCount; i++) {
|
|
34193
34680
|
expectedHours.push((startHour + i) % 24);
|
|
34194
34681
|
}
|
|
34195
|
-
return expectedHours.map((
|
|
34196
|
-
|
|
34197
|
-
|
|
34198
|
-
|
|
34682
|
+
return expectedHours.map((expectedHour, index) => {
|
|
34683
|
+
let hourSum = 0;
|
|
34684
|
+
const outputHourly = metrics2.output_hourly;
|
|
34685
|
+
const hourData = outputHourly[expectedHour.toString()] || [];
|
|
34686
|
+
if (startMinute > 0) {
|
|
34687
|
+
if (index === 0) {
|
|
34688
|
+
if (Array.isArray(hourData)) {
|
|
34689
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
34690
|
+
const val = hourData[i];
|
|
34691
|
+
if (val !== "x" && typeof val === "number") {
|
|
34692
|
+
hourSum += val;
|
|
34693
|
+
}
|
|
34694
|
+
}
|
|
34695
|
+
}
|
|
34696
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
34697
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
34698
|
+
if (Array.isArray(nextHourData)) {
|
|
34699
|
+
for (let i = 0; i < startMinute && i < nextHourData.length; i++) {
|
|
34700
|
+
const val = nextHourData[i];
|
|
34701
|
+
if (val !== "x" && typeof val === "number") {
|
|
34702
|
+
hourSum += val;
|
|
34703
|
+
}
|
|
34704
|
+
}
|
|
34705
|
+
}
|
|
34706
|
+
} else if (index < expectedHours.length - 1) {
|
|
34707
|
+
if (Array.isArray(hourData)) {
|
|
34708
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
34709
|
+
const val = hourData[i];
|
|
34710
|
+
if (val !== "x" && typeof val === "number") {
|
|
34711
|
+
hourSum += val;
|
|
34712
|
+
}
|
|
34713
|
+
}
|
|
34714
|
+
}
|
|
34715
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
34716
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
34717
|
+
if (Array.isArray(nextHourData)) {
|
|
34718
|
+
for (let i = 0; i < startMinute && i < nextHourData.length; i++) {
|
|
34719
|
+
const val = nextHourData[i];
|
|
34720
|
+
if (val !== "x" && typeof val === "number") {
|
|
34721
|
+
hourSum += val;
|
|
34722
|
+
}
|
|
34723
|
+
}
|
|
34724
|
+
}
|
|
34725
|
+
} else {
|
|
34726
|
+
if (hasPartialLastHour && endMinute > 0) {
|
|
34727
|
+
if (startMinute > 0) {
|
|
34728
|
+
if (Array.isArray(hourData)) {
|
|
34729
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
34730
|
+
const val = hourData[i];
|
|
34731
|
+
if (val !== "x" && typeof val === "number") {
|
|
34732
|
+
hourSum += val;
|
|
34733
|
+
}
|
|
34734
|
+
}
|
|
34735
|
+
}
|
|
34736
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
34737
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
34738
|
+
if (Array.isArray(nextHourData)) {
|
|
34739
|
+
for (let i = 0; i < endMinute && i < nextHourData.length; i++) {
|
|
34740
|
+
const val = nextHourData[i];
|
|
34741
|
+
if (val !== "x" && typeof val === "number") {
|
|
34742
|
+
hourSum += val;
|
|
34743
|
+
}
|
|
34744
|
+
}
|
|
34745
|
+
}
|
|
34746
|
+
} else {
|
|
34747
|
+
if (Array.isArray(hourData)) {
|
|
34748
|
+
for (let i = 0; i < endMinute && i < hourData.length; i++) {
|
|
34749
|
+
const val = hourData[i];
|
|
34750
|
+
if (val !== "x" && typeof val === "number") {
|
|
34751
|
+
hourSum += val;
|
|
34752
|
+
}
|
|
34753
|
+
}
|
|
34754
|
+
}
|
|
34755
|
+
}
|
|
34756
|
+
} else {
|
|
34757
|
+
if (Array.isArray(hourData)) {
|
|
34758
|
+
for (let i = startMinute; i < hourData.length; i++) {
|
|
34759
|
+
const val = hourData[i];
|
|
34760
|
+
if (val !== "x" && typeof val === "number") {
|
|
34761
|
+
hourSum += val;
|
|
34762
|
+
}
|
|
34763
|
+
}
|
|
34764
|
+
}
|
|
34765
|
+
const nextHour = (expectedHour + 1) % 24;
|
|
34766
|
+
const nextHourData = outputHourly[nextHour.toString()] || [];
|
|
34767
|
+
if (Array.isArray(nextHourData)) {
|
|
34768
|
+
for (let i = 0; i < startMinute && i < nextHourData.length; i++) {
|
|
34769
|
+
const val = nextHourData[i];
|
|
34770
|
+
if (val !== "x" && typeof val === "number") {
|
|
34771
|
+
hourSum += val;
|
|
34772
|
+
}
|
|
34773
|
+
}
|
|
34774
|
+
}
|
|
34775
|
+
}
|
|
34776
|
+
}
|
|
34777
|
+
} else {
|
|
34778
|
+
if (Array.isArray(hourData)) {
|
|
34779
|
+
hourData.forEach((val) => {
|
|
34780
|
+
if (val !== "x" && typeof val === "number") {
|
|
34781
|
+
hourSum += val;
|
|
34782
|
+
}
|
|
34783
|
+
});
|
|
34784
|
+
}
|
|
34785
|
+
if (index === expectedHours.length - 1 && hasPartialLastHour && endMinute > 0) {
|
|
34786
|
+
hourSum = 0;
|
|
34787
|
+
if (Array.isArray(hourData)) {
|
|
34788
|
+
for (let i = 0; i < endMinute && i < hourData.length; i++) {
|
|
34789
|
+
const val = hourData[i];
|
|
34790
|
+
if (val !== "x" && typeof val === "number") {
|
|
34791
|
+
hourSum += val;
|
|
34792
|
+
}
|
|
34793
|
+
}
|
|
34794
|
+
}
|
|
34795
|
+
}
|
|
34199
34796
|
}
|
|
34200
|
-
return
|
|
34797
|
+
return hourSum;
|
|
34201
34798
|
});
|
|
34202
34799
|
}
|
|
34203
34800
|
if (metrics2.output_array) {
|