@optifye/dashboard-core 6.12.25 → 6.12.27
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/{automation-C3vudVDH.d.mts → automation-pIVo1XWk.d.mts} +23 -1
- package/dist/{automation-C3vudVDH.d.ts → automation-pIVo1XWk.d.ts} +23 -1
- package/dist/automation.d.mts +1 -1
- package/dist/automation.d.ts +1 -1
- package/dist/index.css +0 -15
- package/dist/index.d.mts +13 -4
- package/dist/index.d.ts +13 -4
- package/dist/index.js +406 -192
- package/dist/index.mjs +404 -194
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -22075,14 +22075,87 @@ var toNumber = (value) => {
|
|
|
22075
22075
|
}
|
|
22076
22076
|
return 0;
|
|
22077
22077
|
};
|
|
22078
|
+
var toOptionalNumber = (value) => {
|
|
22079
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
22080
|
+
if (typeof value === "string" && value.trim() !== "") {
|
|
22081
|
+
const parsed = Number(value);
|
|
22082
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
22083
|
+
}
|
|
22084
|
+
return null;
|
|
22085
|
+
};
|
|
22078
22086
|
var EFFICIENCY_ON_TRACK_THRESHOLD = 100;
|
|
22079
22087
|
var isEfficiencyOnTrack = (efficiency) => toNumber(efficiency) >= EFFICIENCY_ON_TRACK_THRESHOLD;
|
|
22088
|
+
var KPI_SIGNAL_LABELS = {
|
|
22089
|
+
stable: "Stable",
|
|
22090
|
+
warning: "Warning",
|
|
22091
|
+
attention: "Attention"
|
|
22092
|
+
};
|
|
22093
|
+
var normalizeLineSignalSource = (source) => source === "recent_flow" ? "recent_flow" : "efficiency";
|
|
22094
|
+
var normalizeLineSignal = (lineSignal, fallbackEfficiency, fallbackWeight) => {
|
|
22095
|
+
if (lineSignal && typeof lineSignal === "object") {
|
|
22096
|
+
const raw = lineSignal;
|
|
22097
|
+
return {
|
|
22098
|
+
source: normalizeLineSignalSource(raw.source),
|
|
22099
|
+
percent: toOptionalNumber(raw.percent),
|
|
22100
|
+
weight: toOptionalNumber(raw.weight),
|
|
22101
|
+
mode: raw.mode === "unavailable" ? "unavailable" : "computed",
|
|
22102
|
+
reason: typeof raw.reason === "string" ? raw.reason : raw.reason ?? null,
|
|
22103
|
+
effectiveEndAt: raw.effective_end_at ?? raw.effectiveEndAt ?? null,
|
|
22104
|
+
computedAt: raw.computed_at ?? raw.computedAt ?? null
|
|
22105
|
+
};
|
|
22106
|
+
}
|
|
22107
|
+
const percent2 = toOptionalNumber(fallbackEfficiency);
|
|
22108
|
+
if (percent2 === null) return null;
|
|
22109
|
+
return {
|
|
22110
|
+
source: "efficiency",
|
|
22111
|
+
percent: percent2,
|
|
22112
|
+
weight: toOptionalNumber(fallbackWeight),
|
|
22113
|
+
mode: "computed",
|
|
22114
|
+
reason: "fallback_efficiency",
|
|
22115
|
+
effectiveEndAt: null,
|
|
22116
|
+
computedAt: null
|
|
22117
|
+
};
|
|
22118
|
+
};
|
|
22119
|
+
var getKpiSignalStatus = (signal, legend = DEFAULT_EFFICIENCY_LEGEND) => {
|
|
22120
|
+
const percent2 = toOptionalNumber(signal?.percent);
|
|
22121
|
+
if (percent2 === null) return null;
|
|
22122
|
+
const color2 = getEfficiencyColor(percent2, legend);
|
|
22123
|
+
if (color2 === "green") return "stable";
|
|
22124
|
+
if (color2 === "yellow") return "warning";
|
|
22125
|
+
return "attention";
|
|
22126
|
+
};
|
|
22127
|
+
var getKpiSignalLabel = (signal, legend = DEFAULT_EFFICIENCY_LEGEND) => {
|
|
22128
|
+
const status = getKpiSignalStatus(signal, legend);
|
|
22129
|
+
return status ? KPI_SIGNAL_LABELS[status] : null;
|
|
22130
|
+
};
|
|
22131
|
+
var aggregateLineSignals = (signals) => {
|
|
22132
|
+
const numericSignals = signals.filter(
|
|
22133
|
+
(signal) => signal !== null && signal !== void 0 && toOptionalNumber(signal.percent) !== null
|
|
22134
|
+
);
|
|
22135
|
+
if (numericSignals.length === 0) return null;
|
|
22136
|
+
const percent2 = numericSignals.reduce(
|
|
22137
|
+
(sum, signal) => sum + (toOptionalNumber(signal.percent) ?? 0),
|
|
22138
|
+
0
|
|
22139
|
+
) / numericSignals.length;
|
|
22140
|
+
const signalSources = new Set(numericSignals.map((signal) => signal.source));
|
|
22141
|
+
const source = signalSources.size === 1 ? numericSignals[0].source : "mixed";
|
|
22142
|
+
return {
|
|
22143
|
+
source,
|
|
22144
|
+
percent: percent2,
|
|
22145
|
+
weight: null,
|
|
22146
|
+
mode: "computed",
|
|
22147
|
+
reason: "average",
|
|
22148
|
+
effectiveEndAt: null,
|
|
22149
|
+
computedAt: null
|
|
22150
|
+
};
|
|
22151
|
+
};
|
|
22080
22152
|
var createDefaultKPIs = () => ({
|
|
22081
22153
|
underperformingWorkers: { current: 0, total: 0, change: 0 },
|
|
22082
22154
|
efficiency: { value: 0, change: 0 },
|
|
22083
22155
|
outputProgress: { current: 0, target: 0, idealOutput: 0, change: 0 },
|
|
22084
22156
|
avgCycleTime: { value: 0, change: 0 },
|
|
22085
|
-
qualityCompliance: { value: 95, change: 0 }
|
|
22157
|
+
qualityCompliance: { value: 95, change: 0 },
|
|
22158
|
+
lineSignal: null
|
|
22086
22159
|
});
|
|
22087
22160
|
var buildKPIsFromLineMetricsRow = (row) => {
|
|
22088
22161
|
if (!row) return createDefaultKPIs();
|
|
@@ -22116,15 +22189,28 @@ var buildKPIsFromLineMetricsRow = (row) => {
|
|
|
22116
22189
|
qualityCompliance: {
|
|
22117
22190
|
value: 95,
|
|
22118
22191
|
change: 0
|
|
22119
|
-
}
|
|
22192
|
+
},
|
|
22193
|
+
lineSignal: normalizeLineSignal(row.line_signal, avgEfficiency, idealOutput || lineThreshold)
|
|
22120
22194
|
};
|
|
22121
22195
|
};
|
|
22122
22196
|
var aggregateKPIsFromLineMetricsRows = (rows) => {
|
|
22123
22197
|
if (!rows || rows.length === 0) return createDefaultKPIs();
|
|
22198
|
+
const lineSignal = aggregateLineSignals(
|
|
22199
|
+
rows.map((row) => normalizeLineSignal(
|
|
22200
|
+
row?.line_signal,
|
|
22201
|
+
row?.avg_efficiency,
|
|
22202
|
+
row?.ideal_output ?? row?.line_threshold
|
|
22203
|
+
))
|
|
22204
|
+
);
|
|
22124
22205
|
const eligibleRows = rows.filter(
|
|
22125
22206
|
(row) => isValidAggregateEfficiency(row?.monitoring_mode ?? row?.monitoringMode, row?.avg_efficiency)
|
|
22126
22207
|
);
|
|
22127
|
-
if (eligibleRows.length === 0)
|
|
22208
|
+
if (eligibleRows.length === 0) {
|
|
22209
|
+
return {
|
|
22210
|
+
...createDefaultKPIs(),
|
|
22211
|
+
lineSignal
|
|
22212
|
+
};
|
|
22213
|
+
}
|
|
22128
22214
|
const currentOutputSum = eligibleRows.reduce((sum, row) => sum + toNumber(row.current_output), 0);
|
|
22129
22215
|
const lineThresholdSum = eligibleRows.reduce(
|
|
22130
22216
|
(sum, row) => sum + (row?.output_target_recalculated !== void 0 && row?.output_target_recalculated !== null ? toNumber(row.output_target_recalculated) : toNumber(row.line_threshold)),
|
|
@@ -22171,7 +22257,8 @@ var aggregateKPIsFromLineMetricsRows = (rows) => {
|
|
|
22171
22257
|
qualityCompliance: {
|
|
22172
22258
|
value: 95,
|
|
22173
22259
|
change: 0
|
|
22174
|
-
}
|
|
22260
|
+
},
|
|
22261
|
+
lineSignal
|
|
22175
22262
|
};
|
|
22176
22263
|
};
|
|
22177
22264
|
|
|
@@ -34725,19 +34812,19 @@ var SkuRow = ({ sku, isSelected, isLive, onSelect }) => {
|
|
|
34725
34812
|
onClick: () => onSelect?.(isSelected ? null : sku.sku_id),
|
|
34726
34813
|
"data-testid": `sku-progress-row-${sku.sku_id}`,
|
|
34727
34814
|
children: [
|
|
34728
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-
|
|
34729
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-
|
|
34815
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-3", children: [
|
|
34816
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2 flex-1 min-w-0", children: [
|
|
34730
34817
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
34731
34818
|
"span",
|
|
34732
34819
|
{
|
|
34733
|
-
className: "text-sm font-semibold text-gray-800
|
|
34820
|
+
className: "text-xs sm:text-sm font-semibold text-gray-800 break-words line-clamp-2",
|
|
34734
34821
|
title: skuLabel,
|
|
34735
34822
|
children: skuLabel
|
|
34736
34823
|
}
|
|
34737
34824
|
),
|
|
34738
|
-
isLive && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-2 h-2 rounded-full bg-green-500 shrink-0 shadow-[0_0_4px_rgba(34,197,94,0.6)]", title: "Currently running" })
|
|
34825
|
+
isLive && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-2 h-2 rounded-full bg-green-500 shrink-0 shadow-[0_0_4px_rgba(34,197,94,0.6)] mt-1.5", title: "Currently running" })
|
|
34739
34826
|
] }),
|
|
34740
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-gray-500 font-medium tabular-nums shrink-0", children: [
|
|
34827
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-gray-500 font-medium tabular-nums shrink-0 pt-0.5", children: [
|
|
34741
34828
|
Math.round(current),
|
|
34742
34829
|
" / ",
|
|
34743
34830
|
Math.round(target)
|
|
@@ -36146,6 +36233,37 @@ var interpretIdleValue = (value) => {
|
|
|
36146
36233
|
if (value === "x" || value === null || value === void 0) return "unknown";
|
|
36147
36234
|
return "unknown";
|
|
36148
36235
|
};
|
|
36236
|
+
var timeToMinutes = (value) => {
|
|
36237
|
+
const parsed = parseTime(value);
|
|
36238
|
+
if (!parsed) return null;
|
|
36239
|
+
return parsed.hour * 60 + parsed.minute;
|
|
36240
|
+
};
|
|
36241
|
+
var normalizeBreaksOnShiftTimeline2 = (shiftStart, shiftBreaks) => {
|
|
36242
|
+
const shiftStartMinutes = timeToMinutes(shiftStart);
|
|
36243
|
+
if (shiftStartMinutes === null || !Array.isArray(shiftBreaks)) {
|
|
36244
|
+
return [];
|
|
36245
|
+
}
|
|
36246
|
+
return shiftBreaks.flatMap((entry) => {
|
|
36247
|
+
const startRaw = timeToMinutes(entry?.startTime ?? entry?.start);
|
|
36248
|
+
const endRaw = timeToMinutes(entry?.endTime ?? entry?.end);
|
|
36249
|
+
if (startRaw === null || endRaw === null) return [];
|
|
36250
|
+
let start = startRaw;
|
|
36251
|
+
let end = endRaw;
|
|
36252
|
+
if (end <= start) {
|
|
36253
|
+
end += 24 * 60;
|
|
36254
|
+
}
|
|
36255
|
+
if (start < shiftStartMinutes) {
|
|
36256
|
+
start += 24 * 60;
|
|
36257
|
+
end += 24 * 60;
|
|
36258
|
+
}
|
|
36259
|
+
return [{ start, end }];
|
|
36260
|
+
});
|
|
36261
|
+
};
|
|
36262
|
+
var isBreakMinute = (minuteIndex, shiftStartMinutes, normalizedBreaks) => {
|
|
36263
|
+
if (!normalizedBreaks.length) return false;
|
|
36264
|
+
const absoluteMinute = shiftStartMinutes + minuteIndex;
|
|
36265
|
+
return normalizedBreaks.some((entry) => entry.start <= absoluteMinute && absoluteMinute < entry.end);
|
|
36266
|
+
};
|
|
36149
36267
|
var getShiftDurationMinutes = (shiftStart, shiftEnd) => {
|
|
36150
36268
|
const start = parseTime(shiftStart);
|
|
36151
36269
|
const end = parseTime(shiftEnd);
|
|
@@ -36156,6 +36274,29 @@ var getShiftDurationMinutes = (shiftStart, shiftEnd) => {
|
|
|
36156
36274
|
}
|
|
36157
36275
|
return duration > 0 ? duration : null;
|
|
36158
36276
|
};
|
|
36277
|
+
var getBreakExcludedShiftMinutes = ({
|
|
36278
|
+
shiftStart,
|
|
36279
|
+
shiftEnd,
|
|
36280
|
+
elapsedMinutes,
|
|
36281
|
+
shiftBreaks
|
|
36282
|
+
}) => {
|
|
36283
|
+
const shiftMinutes = getShiftDurationMinutes(shiftStart, shiftEnd);
|
|
36284
|
+
if (shiftMinutes === null) return null;
|
|
36285
|
+
const elapsedLimit = Number.isFinite(elapsedMinutes) ? Math.min(Math.max(Math.floor(elapsedMinutes ?? 0), 0), shiftMinutes) : shiftMinutes;
|
|
36286
|
+
if (elapsedLimit <= 0) return 0;
|
|
36287
|
+
const startTime = parseTime(shiftStart);
|
|
36288
|
+
if (!startTime) return elapsedLimit;
|
|
36289
|
+
const shiftStartMinutes = startTime.hour * 60 + startTime.minute;
|
|
36290
|
+
const normalizedBreaks = normalizeBreaksOnShiftTimeline2(shiftStart, shiftBreaks);
|
|
36291
|
+
if (!normalizedBreaks.length) return elapsedLimit;
|
|
36292
|
+
let workingMinutes = 0;
|
|
36293
|
+
for (let minuteIndex = 0; minuteIndex < elapsedLimit; minuteIndex += 1) {
|
|
36294
|
+
if (!isBreakMinute(minuteIndex, shiftStartMinutes, normalizedBreaks)) {
|
|
36295
|
+
workingMinutes += 1;
|
|
36296
|
+
}
|
|
36297
|
+
}
|
|
36298
|
+
return workingMinutes;
|
|
36299
|
+
};
|
|
36159
36300
|
var getShiftElapsedMinutes = ({
|
|
36160
36301
|
shiftStart,
|
|
36161
36302
|
shiftEnd,
|
|
@@ -36220,7 +36361,8 @@ var buildUptimeSeries = ({
|
|
|
36220
36361
|
shiftEnd,
|
|
36221
36362
|
shiftDate,
|
|
36222
36363
|
timezone,
|
|
36223
|
-
elapsedMinutes
|
|
36364
|
+
elapsedMinutes,
|
|
36365
|
+
shiftBreaks
|
|
36224
36366
|
}) => {
|
|
36225
36367
|
const normalizedIdle = normalizeIdleTimeHourly(idleTimeHourly || {});
|
|
36226
36368
|
const hasIdleData = Object.keys(normalizedIdle).length > 0;
|
|
@@ -36275,6 +36417,8 @@ var buildUptimeSeries = ({
|
|
|
36275
36417
|
const points = [];
|
|
36276
36418
|
let activeMinutes = 0;
|
|
36277
36419
|
let idleMinutes = 0;
|
|
36420
|
+
const shiftStartMinutes = startTime.hour * 60 + startTime.minute;
|
|
36421
|
+
const normalizedBreaks = normalizeBreaksOnShiftTimeline2(shiftStart, shiftBreaks);
|
|
36278
36422
|
for (let minuteIndex = 0; minuteIndex < shiftMinutes; minuteIndex += 1) {
|
|
36279
36423
|
const minuteDate = dateFns.addMinutes(shiftStartDate, minuteIndex);
|
|
36280
36424
|
const timeLabel = dateFnsTz.formatInTimeZone(minuteDate, timezone, "h:mm a");
|
|
@@ -36287,6 +36431,15 @@ var buildUptimeSeries = ({
|
|
|
36287
36431
|
});
|
|
36288
36432
|
continue;
|
|
36289
36433
|
}
|
|
36434
|
+
if (isBreakMinute(minuteIndex, shiftStartMinutes, normalizedBreaks)) {
|
|
36435
|
+
points.push({
|
|
36436
|
+
minuteIndex,
|
|
36437
|
+
timeLabel,
|
|
36438
|
+
uptime: null,
|
|
36439
|
+
status: "break"
|
|
36440
|
+
});
|
|
36441
|
+
continue;
|
|
36442
|
+
}
|
|
36290
36443
|
const hourKey = dateFnsTz.formatInTimeZone(minuteDate, timezone, "H");
|
|
36291
36444
|
const minuteKey = Number.parseInt(dateFnsTz.formatInTimeZone(minuteDate, timezone, "m"), 10);
|
|
36292
36445
|
const hourBucket = normalizedIdle[hourKey] || [];
|
|
@@ -39447,6 +39600,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
39447
39600
|
shiftDate,
|
|
39448
39601
|
timezone,
|
|
39449
39602
|
elapsedMinutes,
|
|
39603
|
+
shiftBreaks,
|
|
39450
39604
|
className = ""
|
|
39451
39605
|
}) => {
|
|
39452
39606
|
const containerRef = React144__namespace.default.useRef(null);
|
|
@@ -39458,8 +39612,9 @@ var HourlyUptimeChartComponent = ({
|
|
|
39458
39612
|
shiftEnd,
|
|
39459
39613
|
shiftDate,
|
|
39460
39614
|
timezone,
|
|
39461
|
-
elapsedMinutes
|
|
39462
|
-
|
|
39615
|
+
elapsedMinutes,
|
|
39616
|
+
shiftBreaks
|
|
39617
|
+
}), [idleTimeHourly, shiftStart, shiftEnd, shiftDate, timezone, elapsedMinutes, shiftBreaks]);
|
|
39463
39618
|
const hasAggregateData = Boolean(hourlyAggregates && hourlyAggregates.length > 0);
|
|
39464
39619
|
const shiftStartTime = React144__namespace.default.useMemo(
|
|
39465
39620
|
() => getTimeFromTimeString(shiftStart),
|
|
@@ -45007,7 +45162,7 @@ var FileManagerFilters = ({
|
|
|
45007
45162
|
onClick: () => {
|
|
45008
45163
|
onIdleClipSortChange?.(idleClipSort === "latest" ? "idle_duration_desc" : "latest");
|
|
45009
45164
|
},
|
|
45010
|
-
className: `p-2 rounded-xl transition-all duration-200 ${idleClipSort === "idle_duration_desc" ? "bg-
|
|
45165
|
+
className: `p-2 rounded-xl transition-all duration-200 ${idleClipSort === "idle_duration_desc" ? "bg-blue-100 text-blue-600 hover:bg-blue-200 shadow-sm" : "bg-slate-100 text-slate-600 hover:bg-slate-200"}`,
|
|
45011
45166
|
title: idleClipSort === "idle_duration_desc" ? "Sort by newest first" : "Sort by longest idle first",
|
|
45012
45167
|
"aria-label": idleClipSort === "idle_duration_desc" ? "Sort idle clips by newest first" : "Sort idle clips by longest idle first",
|
|
45013
45168
|
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowDownWideNarrow, { className: "h-5 w-5" })
|
|
@@ -45074,7 +45229,7 @@ var FileManagerFilters = ({
|
|
|
45074
45229
|
}
|
|
45075
45230
|
)
|
|
45076
45231
|
] }),
|
|
45077
|
-
activeFilter === "idle_time" && idleClipSort === "idle_duration_desc" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "inline-flex w-fit items-center gap-2 rounded-full border border-
|
|
45232
|
+
activeFilter === "idle_time" && idleClipSort === "idle_duration_desc" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "inline-flex w-fit items-center gap-2 rounded-full border border-blue-100 bg-blue-50/70 px-2.5 py-1 text-xs text-blue-700 shadow-sm", children: [
|
|
45078
45233
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowDownWideNarrow, { className: "h-3.5 w-3.5" }),
|
|
45079
45234
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: "Longest idle first" }),
|
|
45080
45235
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -45084,7 +45239,7 @@ var FileManagerFilters = ({
|
|
|
45084
45239
|
e.stopPropagation();
|
|
45085
45240
|
onIdleClipSortChange?.("latest");
|
|
45086
45241
|
},
|
|
45087
|
-
className: "rounded-full p-0.5 transition-colors hover:bg-
|
|
45242
|
+
className: "rounded-full p-0.5 transition-colors hover:bg-blue-100",
|
|
45088
45243
|
title: "Clear idle sort",
|
|
45089
45244
|
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-3.5 w-3.5" })
|
|
45090
45245
|
}
|
|
@@ -51651,7 +51806,8 @@ var LineMonthlyPdfGenerator = ({
|
|
|
51651
51806
|
};
|
|
51652
51807
|
var LineWhatsAppShareButton = ({
|
|
51653
51808
|
lineInfo,
|
|
51654
|
-
className
|
|
51809
|
+
className,
|
|
51810
|
+
shiftBreaks = []
|
|
51655
51811
|
}) => {
|
|
51656
51812
|
const handleShare = () => {
|
|
51657
51813
|
trackCoreEvent("Line WhatsApp Share Clicked", {
|
|
@@ -51665,7 +51821,8 @@ var LineWhatsAppShareButton = ({
|
|
|
51665
51821
|
shiftStart: lineInfo.metrics.shift_start,
|
|
51666
51822
|
shiftEnd: lineInfo.metrics.shift_end,
|
|
51667
51823
|
shiftDate: lineInfo.date,
|
|
51668
|
-
timezone: "Asia/Kolkata"
|
|
51824
|
+
timezone: "Asia/Kolkata",
|
|
51825
|
+
shiftBreaks
|
|
51669
51826
|
}) : null;
|
|
51670
51827
|
const efficiencyValue = Number.isFinite(lineInfo.metrics.avg_efficiency) ? Number(lineInfo.metrics.avg_efficiency) : null;
|
|
51671
51828
|
const utilization = efficiencyValue !== null ? efficiencyValue : uptimeSeries && uptimeSeries.availableMinutes > 0 ? uptimeSeries.activeMinutes / uptimeSeries.availableMinutes * 100 : 0;
|
|
@@ -51834,16 +51991,24 @@ var LinePdfGenerator = ({
|
|
|
51834
51991
|
shiftStart,
|
|
51835
51992
|
shiftEnd,
|
|
51836
51993
|
shiftDate,
|
|
51837
|
-
timezone: effectiveUptimeTimezone
|
|
51994
|
+
timezone: effectiveUptimeTimezone,
|
|
51995
|
+
shiftBreaks
|
|
51838
51996
|
});
|
|
51839
51997
|
let activeMinutes = uptimeSeries.activeMinutes;
|
|
51840
51998
|
let idleMinutes = uptimeSeries.idleMinutes;
|
|
51841
51999
|
let availableMinutes = uptimeSeries.availableMinutes;
|
|
51842
52000
|
let hasData = uptimeSeries.hasData;
|
|
51843
|
-
|
|
52001
|
+
const hasIdleHourlyPayload = Boolean(
|
|
52002
|
+
workspace.idle_time_hourly && typeof workspace.idle_time_hourly === "object" && Object.keys(workspace.idle_time_hourly).length > 0
|
|
52003
|
+
);
|
|
52004
|
+
if (!hasData && !hasIdleHourlyPayload) {
|
|
51844
52005
|
const idleTimeValue = workspace.idle_time;
|
|
51845
52006
|
const hasIdleTimeValue = Number.isFinite(idleTimeValue);
|
|
51846
|
-
const fallbackDuration =
|
|
52007
|
+
const fallbackDuration = getBreakExcludedShiftMinutes({
|
|
52008
|
+
shiftStart,
|
|
52009
|
+
shiftEnd,
|
|
52010
|
+
shiftBreaks
|
|
52011
|
+
}) ?? shiftDurationMinutes;
|
|
51847
52012
|
if (hasIdleTimeValue && idleTimeValue > 0 && fallbackDuration > 0) {
|
|
51848
52013
|
const idleFromAggregate = Math.min(Math.max(Number(idleTimeValue) / 60, 0), fallbackDuration);
|
|
51849
52014
|
idleMinutes = idleFromAggregate;
|
|
@@ -51915,7 +52080,8 @@ var LinePdfGenerator = ({
|
|
|
51915
52080
|
shiftStart: lineShiftStart,
|
|
51916
52081
|
shiftEnd: lineShiftEnd,
|
|
51917
52082
|
shiftDate: lineInfo.date,
|
|
51918
|
-
timezone: effectiveUptimeTimezone
|
|
52083
|
+
timezone: effectiveUptimeTimezone,
|
|
52084
|
+
shiftBreaks
|
|
51919
52085
|
});
|
|
51920
52086
|
hourlyData = buildHourlyFromSeries(lineUptimeSeries);
|
|
51921
52087
|
}
|
|
@@ -53854,7 +54020,8 @@ var WorkspaceMonthlyHistory = ({
|
|
|
53854
54020
|
};
|
|
53855
54021
|
var WorkspaceWhatsAppShareButton = ({
|
|
53856
54022
|
workspace,
|
|
53857
|
-
className
|
|
54023
|
+
className,
|
|
54024
|
+
shiftBreaks = []
|
|
53858
54025
|
}) => {
|
|
53859
54026
|
const handleShare = () => {
|
|
53860
54027
|
trackCoreEvent("Workspace WhatsApp Share Clicked", {
|
|
@@ -53870,7 +54037,11 @@ var WorkspaceWhatsAppShareButton = ({
|
|
|
53870
54037
|
timeZone: "Asia/Kolkata"
|
|
53871
54038
|
});
|
|
53872
54039
|
const isUptimeMode = workspace.monitoring_mode === "uptime";
|
|
53873
|
-
const shiftMinutes =
|
|
54040
|
+
const shiftMinutes = getBreakExcludedShiftMinutes({
|
|
54041
|
+
shiftStart: workspace.shift_start,
|
|
54042
|
+
shiftEnd: workspace.shift_end,
|
|
54043
|
+
shiftBreaks
|
|
54044
|
+
}) ?? getShiftDurationMinutes(workspace.shift_start, workspace.shift_end);
|
|
53874
54045
|
const shiftSeconds = shiftMinutes ? shiftMinutes * 60 : 0;
|
|
53875
54046
|
const idleSeconds = Math.max(workspace.idle_time || 0, 0);
|
|
53876
54047
|
const clampedIdleSeconds = shiftSeconds > 0 ? Math.min(idleSeconds, shiftSeconds) : idleSeconds;
|
|
@@ -53960,7 +54131,11 @@ var WorkspacePdfGenerator = ({
|
|
|
53960
54131
|
try {
|
|
53961
54132
|
const isUptimeMode = workspace.monitoring_mode === "uptime";
|
|
53962
54133
|
const isAssemblyCycleMode = !isUptimeMode && shouldUseAssemblyCycleTimeLayout(workspace);
|
|
53963
|
-
const shiftMinutes =
|
|
54134
|
+
const shiftMinutes = getBreakExcludedShiftMinutes({
|
|
54135
|
+
shiftStart: workspace.shift_start,
|
|
54136
|
+
shiftEnd: workspace.shift_end,
|
|
54137
|
+
shiftBreaks
|
|
54138
|
+
}) ?? getShiftDurationMinutes(workspace.shift_start, workspace.shift_end);
|
|
53964
54139
|
const shiftSeconds = shiftMinutes ? shiftMinutes * 60 : 0;
|
|
53965
54140
|
const idleSeconds = Math.max(workspace.idle_time || 0, 0);
|
|
53966
54141
|
const clampedIdleSeconds = shiftSeconds > 0 ? Math.min(idleSeconds, shiftSeconds) : idleSeconds;
|
|
@@ -54130,7 +54305,8 @@ var WorkspacePdfGenerator = ({
|
|
|
54130
54305
|
shiftStart: workspace.shift_start,
|
|
54131
54306
|
shiftEnd: workspace.shift_end,
|
|
54132
54307
|
shiftDate: workspace.date,
|
|
54133
|
-
timezone: reportTimezone
|
|
54308
|
+
timezone: reportTimezone,
|
|
54309
|
+
shiftBreaks
|
|
54134
54310
|
}) : null;
|
|
54135
54311
|
const hourlyUptime = uptimeSeries?.points?.length ? Array.from({ length: Math.ceil(uptimeSeries.shiftMinutes / 60) }, (_, index) => {
|
|
54136
54312
|
const start = index * 60;
|
|
@@ -57525,7 +57701,7 @@ var SideNavBar = React144.memo(({
|
|
|
57525
57701
|
const role = user?.role_level;
|
|
57526
57702
|
const roleNavPaths = React144.useMemo(() => getRoleNavPaths(role), [role]);
|
|
57527
57703
|
const showLiveMonitorLink = roleNavPaths.includes("/live-monitor");
|
|
57528
|
-
const rootDashboardSurface = React144.useMemo(() =>
|
|
57704
|
+
const rootDashboardSurface = React144.useMemo(() => "monitor", []);
|
|
57529
57705
|
const getBasePath = React144.useCallback((path) => {
|
|
57530
57706
|
const firstSegment = path.split("?")[0].split("/").filter(Boolean)[0];
|
|
57531
57707
|
return firstSegment ? `/${firstSegment}` : "/";
|
|
@@ -57576,12 +57752,6 @@ var SideNavBar = React144.memo(({
|
|
|
57576
57752
|
dashboard_surface: dashboardSurface
|
|
57577
57753
|
}
|
|
57578
57754
|
}), []);
|
|
57579
|
-
const handleHomeClick = React144.useCallback(() => {
|
|
57580
|
-
navigate("/", {
|
|
57581
|
-
trackingEvent: buildDashboardSurfaceTrackingEvent("side_nav", "/", rootDashboardSurface)
|
|
57582
|
-
});
|
|
57583
|
-
onMobileMenuClose?.();
|
|
57584
|
-
}, [navigate, onMobileMenuClose, buildDashboardSurfaceTrackingEvent, rootDashboardSurface]);
|
|
57585
57755
|
const handleLeaderboardClick = React144.useCallback(() => {
|
|
57586
57756
|
navigate(`/leaderboard`, {
|
|
57587
57757
|
trackingEvent: {
|
|
@@ -57887,7 +58057,6 @@ var SideNavBar = React144.memo(({
|
|
|
57887
58057
|
});
|
|
57888
58058
|
onMobileMenuClose?.();
|
|
57889
58059
|
}, [navigate, onMobileMenuClose, buildDashboardSurfaceTrackingEvent, rootDashboardSurface]);
|
|
57890
|
-
const homeButtonClasses = React144.useMemo(() => getButtonClasses("/"), [getButtonClasses]);
|
|
57891
58060
|
const liveButtonClasses = React144.useMemo(() => getButtonClasses("/live-monitor"), [getButtonClasses]);
|
|
57892
58061
|
const leaderboardButtonClasses = React144.useMemo(() => getButtonClasses("/leaderboard"), [getButtonClasses]);
|
|
57893
58062
|
const kpisButtonClasses = React144.useMemo(() => getButtonClasses("/kpis"), [getButtonClasses]);
|
|
@@ -57918,118 +58087,99 @@ var SideNavBar = React144.memo(({
|
|
|
57918
58087
|
children: /* @__PURE__ */ jsxRuntime.jsx(Logo, { className: "w-12 h-12 object-contain cursor-pointer" })
|
|
57919
58088
|
}
|
|
57920
58089
|
) }),
|
|
57921
|
-
/* @__PURE__ */ jsxRuntime.
|
|
57922
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
57923
|
-
|
|
57924
|
-
|
|
57925
|
-
|
|
57926
|
-
|
|
57927
|
-
|
|
57928
|
-
|
|
57929
|
-
|
|
57930
|
-
|
|
57931
|
-
|
|
57932
|
-
|
|
57933
|
-
|
|
57934
|
-
|
|
57935
|
-
|
|
57936
|
-
|
|
57937
|
-
|
|
57938
|
-
|
|
57939
|
-
|
|
57940
|
-
|
|
57941
|
-
|
|
57942
|
-
|
|
57943
|
-
|
|
57944
|
-
|
|
57945
|
-
|
|
57946
|
-
|
|
57947
|
-
|
|
57948
|
-
|
|
57949
|
-
|
|
57950
|
-
|
|
57951
|
-
|
|
57952
|
-
|
|
57953
|
-
|
|
57954
|
-
|
|
57955
|
-
|
|
57956
|
-
|
|
57957
|
-
|
|
57958
|
-
|
|
57959
|
-
|
|
57960
|
-
|
|
57961
|
-
|
|
57962
|
-
|
|
57963
|
-
"
|
|
57964
|
-
|
|
57965
|
-
|
|
57966
|
-
|
|
57967
|
-
|
|
57968
|
-
|
|
57969
|
-
|
|
57970
|
-
|
|
57971
|
-
|
|
57972
|
-
|
|
57973
|
-
|
|
57974
|
-
|
|
57975
|
-
|
|
57976
|
-
|
|
57977
|
-
|
|
57978
|
-
"
|
|
57979
|
-
|
|
57980
|
-
|
|
57981
|
-
|
|
57982
|
-
|
|
57983
|
-
|
|
57984
|
-
|
|
57985
|
-
|
|
57986
|
-
|
|
57987
|
-
|
|
57988
|
-
|
|
57989
|
-
|
|
57990
|
-
|
|
57991
|
-
|
|
57992
|
-
|
|
57993
|
-
|
|
57994
|
-
children:
|
|
57995
|
-
|
|
57996
|
-
|
|
57997
|
-
|
|
57998
|
-
|
|
57999
|
-
|
|
58000
|
-
|
|
58001
|
-
|
|
58002
|
-
|
|
58003
|
-
|
|
58004
|
-
|
|
58005
|
-
|
|
58006
|
-
|
|
58007
|
-
|
|
58008
|
-
|
|
58009
|
-
"
|
|
58010
|
-
|
|
58011
|
-
|
|
58012
|
-
|
|
58013
|
-
|
|
58014
|
-
}
|
|
58015
|
-
),
|
|
58016
|
-
canAccessPath("/health") && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
58017
|
-
"button",
|
|
58018
|
-
{
|
|
58019
|
-
onClick: handleHealthClick,
|
|
58020
|
-
className: healthButtonClasses,
|
|
58021
|
-
"aria-label": "System Health",
|
|
58022
|
-
tabIndex: 0,
|
|
58023
|
-
role: "tab",
|
|
58024
|
-
"aria-selected": isPathActive("/health"),
|
|
58025
|
-
children: [
|
|
58026
|
-
/* @__PURE__ */ jsxRuntime.jsx(outline.HeartIcon, { className: "w-5 h-5 mb-1" }),
|
|
58027
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs sm:text-[10px] font-medium leading-tight", children: "Health" })
|
|
58028
|
-
]
|
|
58029
|
-
}
|
|
58030
|
-
)
|
|
58031
|
-
] })
|
|
58032
|
-
] }),
|
|
58090
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 w-full py-6 px-4 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
|
|
58091
|
+
showLiveMonitorLink && canAccessPath("/live-monitor") && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
58092
|
+
"button",
|
|
58093
|
+
{
|
|
58094
|
+
onClick: handleLiveClick,
|
|
58095
|
+
className: liveButtonClasses,
|
|
58096
|
+
"aria-label": "Monitor",
|
|
58097
|
+
tabIndex: 0,
|
|
58098
|
+
role: "tab",
|
|
58099
|
+
"aria-selected": isPathActive("/live-monitor"),
|
|
58100
|
+
children: [
|
|
58101
|
+
/* @__PURE__ */ jsxRuntime.jsx(outline.VideoCameraIcon, { className: "w-5 h-5 mb-1" }),
|
|
58102
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs sm:text-[10px] font-medium leading-tight", children: "Monitor" })
|
|
58103
|
+
]
|
|
58104
|
+
}
|
|
58105
|
+
),
|
|
58106
|
+
canAccessPath("/leaderboard") && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
58107
|
+
"button",
|
|
58108
|
+
{
|
|
58109
|
+
onClick: handleLeaderboardClick,
|
|
58110
|
+
className: leaderboardButtonClasses,
|
|
58111
|
+
"aria-label": "Leaderboard",
|
|
58112
|
+
tabIndex: 0,
|
|
58113
|
+
role: "tab",
|
|
58114
|
+
"aria-selected": isPathActive("/leaderboard"),
|
|
58115
|
+
children: [
|
|
58116
|
+
/* @__PURE__ */ jsxRuntime.jsx(outline.TrophyIcon, { className: "w-5 h-5 mb-1" }),
|
|
58117
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs sm:text-[10px] font-medium leading-tight", children: "Leaders" })
|
|
58118
|
+
]
|
|
58119
|
+
}
|
|
58120
|
+
),
|
|
58121
|
+
canAccessPath("/kpis") && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
58122
|
+
"button",
|
|
58123
|
+
{
|
|
58124
|
+
onClick: handleKPIsClick,
|
|
58125
|
+
className: kpisButtonClasses,
|
|
58126
|
+
"aria-label": "Lines",
|
|
58127
|
+
tabIndex: 0,
|
|
58128
|
+
role: "tab",
|
|
58129
|
+
"aria-selected": isPathActive("/kpis"),
|
|
58130
|
+
children: [
|
|
58131
|
+
/* @__PURE__ */ jsxRuntime.jsx(outline.ChartBarIcon, { className: "w-5 h-5 mb-1" }),
|
|
58132
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs sm:text-[10px] font-medium leading-tight", children: "Lines" })
|
|
58133
|
+
]
|
|
58134
|
+
}
|
|
58135
|
+
),
|
|
58136
|
+
canAccessPath("/improvement-center") && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
58137
|
+
"button",
|
|
58138
|
+
{
|
|
58139
|
+
onClick: handleImprovementClick,
|
|
58140
|
+
className: improvementButtonClasses,
|
|
58141
|
+
"aria-label": "Improvement Center",
|
|
58142
|
+
tabIndex: 0,
|
|
58143
|
+
role: "tab",
|
|
58144
|
+
"aria-selected": isPathActive("/improvement-center"),
|
|
58145
|
+
children: [
|
|
58146
|
+
/* @__PURE__ */ jsxRuntime.jsx(outline.LightBulbIcon, { className: "w-5 h-5 mb-1" }),
|
|
58147
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs sm:text-[10px] font-medium leading-tight text-center", children: "Improve" })
|
|
58148
|
+
]
|
|
58149
|
+
}
|
|
58150
|
+
),
|
|
58151
|
+
showSupervisorManagement,
|
|
58152
|
+
skuEnabled && canAccessPath("/skus") && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
58153
|
+
"button",
|
|
58154
|
+
{
|
|
58155
|
+
onClick: handleSKUsClick,
|
|
58156
|
+
className: skusButtonClasses,
|
|
58157
|
+
"aria-label": "SKU Management",
|
|
58158
|
+
tabIndex: 0,
|
|
58159
|
+
role: "tab",
|
|
58160
|
+
"aria-selected": isPathActive("/skus"),
|
|
58161
|
+
children: [
|
|
58162
|
+
/* @__PURE__ */ jsxRuntime.jsx(outline.CubeIcon, { className: "w-5 h-5 mb-1" }),
|
|
58163
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs sm:text-[10px] font-medium leading-tight", children: "SKUs" })
|
|
58164
|
+
]
|
|
58165
|
+
}
|
|
58166
|
+
),
|
|
58167
|
+
canAccessPath("/health") && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
58168
|
+
"button",
|
|
58169
|
+
{
|
|
58170
|
+
onClick: handleHealthClick,
|
|
58171
|
+
className: healthButtonClasses,
|
|
58172
|
+
"aria-label": "System Health",
|
|
58173
|
+
tabIndex: 0,
|
|
58174
|
+
role: "tab",
|
|
58175
|
+
"aria-selected": isPathActive("/health"),
|
|
58176
|
+
children: [
|
|
58177
|
+
/* @__PURE__ */ jsxRuntime.jsx(outline.HeartIcon, { className: "w-5 h-5 mb-1" }),
|
|
58178
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs sm:text-[10px] font-medium leading-tight", children: "Health" })
|
|
58179
|
+
]
|
|
58180
|
+
}
|
|
58181
|
+
)
|
|
58182
|
+
] }) }),
|
|
58033
58183
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full py-4 px-4 border-t border-gray-100 flex-shrink-0 flex flex-col gap-2", children: settingsItems.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
58034
58184
|
"button",
|
|
58035
58185
|
{
|
|
@@ -58066,23 +58216,11 @@ var SideNavBar = React144.memo(({
|
|
|
58066
58216
|
};
|
|
58067
58217
|
};
|
|
58068
58218
|
return /* @__PURE__ */ jsxRuntime.jsxs("nav", { className: "px-5 py-6", children: [
|
|
58069
|
-
canAccessPath("/") && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
58070
|
-
"button",
|
|
58071
|
-
{
|
|
58072
|
-
onClick: handleMobileNavClick(handleHomeClick),
|
|
58073
|
-
className: getMobileButtonClass("/"),
|
|
58074
|
-
"aria-label": "Home",
|
|
58075
|
-
children: [
|
|
58076
|
-
/* @__PURE__ */ jsxRuntime.jsx(outline.HomeIcon, { className: getIconClass("/") }),
|
|
58077
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-base font-medium", children: "Home" })
|
|
58078
|
-
]
|
|
58079
|
-
}
|
|
58080
|
-
),
|
|
58081
58219
|
showLiveMonitorLink && canAccessPath("/live-monitor") && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
58082
58220
|
"button",
|
|
58083
58221
|
{
|
|
58084
58222
|
onClick: handleMobileNavClick(handleLiveClick),
|
|
58085
|
-
className:
|
|
58223
|
+
className: getMobileButtonClass("/live-monitor"),
|
|
58086
58224
|
"aria-label": "Monitor",
|
|
58087
58225
|
children: [
|
|
58088
58226
|
/* @__PURE__ */ jsxRuntime.jsx(outline.VideoCameraIcon, { className: getIconClass("/live-monitor") }),
|
|
@@ -67925,6 +68063,7 @@ var UptimeBottomSection = React144.memo(({
|
|
|
67925
68063
|
shiftDate,
|
|
67926
68064
|
timezone,
|
|
67927
68065
|
elapsedMinutes,
|
|
68066
|
+
shiftBreaks,
|
|
67928
68067
|
urlDate,
|
|
67929
68068
|
urlShift,
|
|
67930
68069
|
navigate
|
|
@@ -68012,7 +68151,8 @@ var UptimeBottomSection = React144.memo(({
|
|
|
68012
68151
|
shiftEnd,
|
|
68013
68152
|
shiftDate,
|
|
68014
68153
|
timezone,
|
|
68015
|
-
elapsedMinutes
|
|
68154
|
+
elapsedMinutes,
|
|
68155
|
+
shiftBreaks
|
|
68016
68156
|
}
|
|
68017
68157
|
) })
|
|
68018
68158
|
] })
|
|
@@ -68330,7 +68470,8 @@ var KPIDetailView = ({
|
|
|
68330
68470
|
shiftStart: resolvedShiftStart || void 0,
|
|
68331
68471
|
shiftEnd: resolvedShiftEnd || void 0,
|
|
68332
68472
|
shiftDate: metric.date,
|
|
68333
|
-
timezone: configuredTimezone
|
|
68473
|
+
timezone: configuredTimezone,
|
|
68474
|
+
shiftBreaks: shiftConfig?.shifts?.find((shift) => shift.shiftId === metric.shift_id)?.breaks || []
|
|
68334
68475
|
}) : null;
|
|
68335
68476
|
const idleTimeSeconds = isUptimeMode ? hasBackendUptimeSeconds ? metricIdleTimeSeconds ?? 0 : (uptimeSeries2?.idleMinutes || 0) * 60 : 0;
|
|
68336
68477
|
const activeTimeSeconds = isUptimeMode ? hasBackendUptimeSeconds ? metricActiveTimeSeconds ?? 0 : (uptimeSeries2?.activeMinutes || 0) * 60 : 0;
|
|
@@ -68510,6 +68651,10 @@ var KPIDetailView = ({
|
|
|
68510
68651
|
end: chartMetrics.shift_end || fallback.end
|
|
68511
68652
|
};
|
|
68512
68653
|
}, [chartMetrics?.shift_start, chartMetrics?.shift_end, chartMetrics?.shift_id, resolveShiftTimes]);
|
|
68654
|
+
const resolvedShiftBreaks = React144.useMemo(
|
|
68655
|
+
() => shiftConfig?.shifts?.find((shift) => shift.shiftId === chartMetrics?.shift_id)?.breaks || [],
|
|
68656
|
+
[shiftConfig?.shifts, chartMetrics?.shift_id]
|
|
68657
|
+
);
|
|
68513
68658
|
const lineSkuBreakdown = React144.useMemo(
|
|
68514
68659
|
() => resolvedLineInfo?.metrics.sku_breakdown ?? [],
|
|
68515
68660
|
[resolvedLineInfo]
|
|
@@ -68643,7 +68788,8 @@ var KPIDetailView = ({
|
|
|
68643
68788
|
shiftEnd: null,
|
|
68644
68789
|
shiftDate: null,
|
|
68645
68790
|
timezone: configuredTimezone,
|
|
68646
|
-
elapsedMinutes: null
|
|
68791
|
+
elapsedMinutes: null,
|
|
68792
|
+
shiftBreaks: resolvedShiftBreaks
|
|
68647
68793
|
});
|
|
68648
68794
|
}
|
|
68649
68795
|
return buildUptimeSeries({
|
|
@@ -68652,9 +68798,10 @@ var KPIDetailView = ({
|
|
|
68652
68798
|
shiftEnd: resolvedShiftTimes.end,
|
|
68653
68799
|
shiftDate: chartMetrics.date,
|
|
68654
68800
|
timezone: configuredTimezone,
|
|
68655
|
-
elapsedMinutes: elapsedShiftMinutes
|
|
68801
|
+
elapsedMinutes: elapsedShiftMinutes,
|
|
68802
|
+
shiftBreaks: resolvedShiftBreaks
|
|
68656
68803
|
});
|
|
68657
|
-
}, [chartMetrics, resolvedShiftTimes.start, resolvedShiftTimes.end, configuredTimezone, elapsedShiftMinutes]);
|
|
68804
|
+
}, [chartMetrics, resolvedShiftTimes.start, resolvedShiftTimes.end, configuredTimezone, elapsedShiftMinutes, resolvedShiftBreaks]);
|
|
68658
68805
|
const lineUtilizationFromLine = React144.useMemo(() => {
|
|
68659
68806
|
const efficiencyValue = Number.isFinite(chartMetrics?.avg_efficiency) ? Number(chartMetrics?.avg_efficiency) : null;
|
|
68660
68807
|
if (efficiencyValue !== null) return efficiencyValue;
|
|
@@ -68681,7 +68828,8 @@ var KPIDetailView = ({
|
|
|
68681
68828
|
shiftEnd,
|
|
68682
68829
|
shiftDate,
|
|
68683
68830
|
timezone: configuredTimezone,
|
|
68684
|
-
elapsedMinutes: workspaceElapsedMinutes
|
|
68831
|
+
elapsedMinutes: workspaceElapsedMinutes,
|
|
68832
|
+
shiftBreaks: resolvedShiftBreaks
|
|
68685
68833
|
});
|
|
68686
68834
|
let activeMinutes = uptimeSeries2.activeMinutes;
|
|
68687
68835
|
let idleMinutes = uptimeSeries2.idleMinutes;
|
|
@@ -68693,7 +68841,12 @@ var KPIDetailView = ({
|
|
|
68693
68841
|
);
|
|
68694
68842
|
const idleTimeValue = workspace.idle_time;
|
|
68695
68843
|
const hasIdleTimeValue = Number.isFinite(idleTimeValue);
|
|
68696
|
-
const fallbackDuration =
|
|
68844
|
+
const fallbackDuration = getBreakExcludedShiftMinutes({
|
|
68845
|
+
shiftStart,
|
|
68846
|
+
shiftEnd,
|
|
68847
|
+
elapsedMinutes: workspaceElapsedMinutes,
|
|
68848
|
+
shiftBreaks: resolvedShiftBreaks
|
|
68849
|
+
}) ?? workspaceElapsedMinutes ?? shiftMinutes;
|
|
68697
68850
|
if (!hasIdleHourlyPayload && hasIdleTimeValue && idleTimeValue > 0 && fallbackDuration > 0) {
|
|
68698
68851
|
const idleSeconds = Number(idleTimeValue);
|
|
68699
68852
|
const idleFromAggregate = Math.min(Math.max(idleSeconds / 60, 0), fallbackDuration);
|
|
@@ -68723,7 +68876,8 @@ var KPIDetailView = ({
|
|
|
68723
68876
|
resolvedShiftTimes.end,
|
|
68724
68877
|
chartMetrics?.date,
|
|
68725
68878
|
configuredTimezone,
|
|
68726
|
-
isCurrentShiftView
|
|
68879
|
+
isCurrentShiftView,
|
|
68880
|
+
resolvedShiftBreaks
|
|
68727
68881
|
]);
|
|
68728
68882
|
const lineUptimeStats = React144.useMemo(() => {
|
|
68729
68883
|
if (!isUptimeMode) {
|
|
@@ -69410,6 +69564,7 @@ var KPIDetailView = ({
|
|
|
69410
69564
|
shiftDate: chartMetrics?.date,
|
|
69411
69565
|
timezone: configuredTimezone,
|
|
69412
69566
|
elapsedMinutes: elapsedShiftMinutes,
|
|
69567
|
+
shiftBreaks: resolvedShiftBreaks,
|
|
69413
69568
|
urlDate,
|
|
69414
69569
|
urlShift,
|
|
69415
69570
|
navigate
|
|
@@ -69524,6 +69679,7 @@ var KPIDetailView = ({
|
|
|
69524
69679
|
shiftDate: chartMetrics?.date,
|
|
69525
69680
|
timezone: configuredTimezone,
|
|
69526
69681
|
elapsedMinutes: elapsedShiftMinutes,
|
|
69682
|
+
shiftBreaks: resolvedShiftBreaks,
|
|
69527
69683
|
urlDate,
|
|
69528
69684
|
urlShift,
|
|
69529
69685
|
navigate
|
|
@@ -69630,6 +69786,19 @@ var formatDateKey2 = (dateKey, timezone, options) => {
|
|
|
69630
69786
|
return dateKey;
|
|
69631
69787
|
}
|
|
69632
69788
|
};
|
|
69789
|
+
var getFirstName = (displayName) => {
|
|
69790
|
+
const trimmedName = displayName.trim();
|
|
69791
|
+
if (!trimmedName) return "";
|
|
69792
|
+
return trimmedName.split(/\s+/)[0];
|
|
69793
|
+
};
|
|
69794
|
+
var formatSupervisorFirstNames = (supervisors, fallbackSupervisorNames) => {
|
|
69795
|
+
const firstNames = supervisors.map((supervisor) => getFirstName(supervisor.displayName)).filter((name) => name.length > 0);
|
|
69796
|
+
if (firstNames.length > 0) {
|
|
69797
|
+
return Array.from(new Set(firstNames)).join(", ");
|
|
69798
|
+
}
|
|
69799
|
+
const fallbackFirstNames = fallbackSupervisorNames.flatMap((names) => names.split(",")).map(getFirstName).filter((name) => name.length > 0);
|
|
69800
|
+
return fallbackFirstNames.length > 0 ? Array.from(new Set(fallbackFirstNames)).join(", ") : "Unassigned";
|
|
69801
|
+
};
|
|
69633
69802
|
var LeaderboardCountdown = ({ targetDate, format: format10, finishedLabel = "Finished", placeholder = "--", onFinished }) => {
|
|
69634
69803
|
const [time2, setTime] = React144.useState("");
|
|
69635
69804
|
const hasFinishedRef = React144.useRef(false);
|
|
@@ -69755,7 +69924,7 @@ var LinesLeaderboard = ({
|
|
|
69755
69924
|
});
|
|
69756
69925
|
const supervisors = Array.from(supervisorByUserId.values());
|
|
69757
69926
|
const primarySupervisor = supervisors[0];
|
|
69758
|
-
const supervisorName = supervisors
|
|
69927
|
+
const supervisorName = formatSupervisorFirstNames(supervisors, fallbackSupervisorNames);
|
|
69759
69928
|
const supervisorImage = primarySupervisor?.profilePhotoUrl || null;
|
|
69760
69929
|
return {
|
|
69761
69930
|
...row,
|
|
@@ -70015,21 +70184,49 @@ var LinesLeaderboard = ({
|
|
|
70015
70184
|
] }) }) }) })
|
|
70016
70185
|
] });
|
|
70017
70186
|
};
|
|
70187
|
+
var SIGNAL_PILL_STYLES = {
|
|
70188
|
+
stable: {
|
|
70189
|
+
container: "bg-emerald-100 text-emerald-700 border border-emerald-200",
|
|
70190
|
+
dot: "bg-emerald-500"
|
|
70191
|
+
},
|
|
70192
|
+
warning: {
|
|
70193
|
+
container: "bg-amber-100 text-amber-700 border border-amber-200",
|
|
70194
|
+
dot: "bg-amber-500"
|
|
70195
|
+
},
|
|
70196
|
+
attention: {
|
|
70197
|
+
container: "bg-red-100 text-red-700 border border-red-200",
|
|
70198
|
+
dot: "bg-red-500"
|
|
70199
|
+
}
|
|
70200
|
+
};
|
|
70201
|
+
var KpiSignalPill = ({ signal, efficiencyLegend }) => {
|
|
70202
|
+
const status = getKpiSignalStatus(signal, efficiencyLegend);
|
|
70203
|
+
const label = getKpiSignalLabel(signal, efficiencyLegend);
|
|
70204
|
+
if (!status || !label) return null;
|
|
70205
|
+
const styles2 = SIGNAL_PILL_STYLES[status];
|
|
70206
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
70207
|
+
"div",
|
|
70208
|
+
{
|
|
70209
|
+
className: `flex items-center gap-1.5 px-2.5 sm:px-3 py-1 sm:py-1.5 rounded-full text-xs font-medium flex-shrink-0 ${styles2.container}`,
|
|
70210
|
+
style: { minWidth: "fit-content" },
|
|
70211
|
+
children: [
|
|
70212
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: `w-2 h-2 rounded-full ${styles2.dot} animate-pulse` }),
|
|
70213
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: label })
|
|
70214
|
+
]
|
|
70215
|
+
}
|
|
70216
|
+
);
|
|
70217
|
+
};
|
|
70018
70218
|
var LineCard = ({
|
|
70019
70219
|
line,
|
|
70020
70220
|
kpis,
|
|
70021
70221
|
isLoading,
|
|
70022
70222
|
error,
|
|
70023
70223
|
onClick,
|
|
70224
|
+
efficiencyLegend,
|
|
70024
70225
|
supervisorEnabled = false,
|
|
70025
70226
|
supervisorName,
|
|
70026
70227
|
supervisors
|
|
70027
70228
|
}) => {
|
|
70028
70229
|
const isUptimeLine = (line.monitoring_mode ?? "output") === "uptime";
|
|
70029
|
-
const isOnTrack = React144__namespace.default.useMemo(() => {
|
|
70030
|
-
if (!kpis) return null;
|
|
70031
|
-
return isEfficiencyOnTrack(kpis.efficiency.value);
|
|
70032
|
-
}, [kpis]);
|
|
70033
70230
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
70034
70231
|
motion.div,
|
|
70035
70232
|
{
|
|
@@ -70101,10 +70298,7 @@ var LineCard = ({
|
|
|
70101
70298
|
] })
|
|
70102
70299
|
] })
|
|
70103
70300
|
] }),
|
|
70104
|
-
!isUptimeLine && kpis &&
|
|
70105
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: `w-2 h-2 rounded-full ${isOnTrack ? "bg-emerald-500" : "bg-red-500"} animate-pulse` }),
|
|
70106
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: isOnTrack ? "On Track" : "Behind" })
|
|
70107
|
-
] })
|
|
70301
|
+
!isUptimeLine && kpis && /* @__PURE__ */ jsxRuntime.jsx(KpiSignalPill, { signal: kpis.lineSignal, efficiencyLegend })
|
|
70108
70302
|
] }) }),
|
|
70109
70303
|
isLoading && !kpis && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
|
|
70110
70304
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "animate-pulse", children: [
|
|
@@ -70172,12 +70366,9 @@ var KpiGroupCard = ({
|
|
|
70172
70366
|
isLoading,
|
|
70173
70367
|
error,
|
|
70174
70368
|
isUptimeMode,
|
|
70369
|
+
efficiencyLegend,
|
|
70175
70370
|
onClick
|
|
70176
70371
|
}) => {
|
|
70177
|
-
const isOnTrack = React144__namespace.default.useMemo(() => {
|
|
70178
|
-
if (!kpis) return null;
|
|
70179
|
-
return isEfficiencyOnTrack(kpis.efficiency.value);
|
|
70180
|
-
}, [kpis]);
|
|
70181
70372
|
const outputTarget = Number(kpis?.outputProgress?.target ?? 0);
|
|
70182
70373
|
const outputCurrent = Number(kpis?.outputProgress?.current ?? 0);
|
|
70183
70374
|
const progressPercent = outputTarget > 0 ? Math.min(outputCurrent / outputTarget * 100, 100) : 0;
|
|
@@ -70201,10 +70392,7 @@ var KpiGroupCard = ({
|
|
|
70201
70392
|
),
|
|
70202
70393
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-xs font-medium text-gray-500", children: subtitle })
|
|
70203
70394
|
] }),
|
|
70204
|
-
!isUptimeMode && kpis &&
|
|
70205
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: `w-2 h-2 rounded-full ${isOnTrack ? "bg-emerald-500" : "bg-red-500"} animate-pulse` }),
|
|
70206
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: isOnTrack ? "On Track" : "Behind" })
|
|
70207
|
-
] })
|
|
70395
|
+
!isUptimeMode && kpis && /* @__PURE__ */ jsxRuntime.jsx(KpiSignalPill, { signal: kpis.lineSignal, efficiencyLegend })
|
|
70208
70396
|
] }) }),
|
|
70209
70397
|
isLoading && !kpis && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
|
|
70210
70398
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "animate-pulse", children: [
|
|
@@ -70521,7 +70709,8 @@ var KPIsOverviewView = ({
|
|
|
70521
70709
|
const {
|
|
70522
70710
|
lineMetrics,
|
|
70523
70711
|
isLoading: metricsLoading,
|
|
70524
|
-
error: metricsError
|
|
70712
|
+
error: metricsError,
|
|
70713
|
+
efficiencyLegend
|
|
70525
70714
|
} = useDashboardMetrics({
|
|
70526
70715
|
lineId: factoryViewId,
|
|
70527
70716
|
userAccessibleLineIds: metricsLineIds
|
|
@@ -70865,7 +71054,11 @@ var KPIsOverviewView = ({
|
|
|
70865
71054
|
trackProps.output_current = kpis.outputProgress?.current;
|
|
70866
71055
|
trackProps.output_target = kpis.outputProgress?.target;
|
|
70867
71056
|
trackProps.underperforming_workers = kpis.underperformingWorkers?.current;
|
|
70868
|
-
|
|
71057
|
+
const signalLabel = getKpiSignalLabel(kpis.lineSignal, efficiencyLegend);
|
|
71058
|
+
if (signalLabel) {
|
|
71059
|
+
trackProps.status = signalLabel;
|
|
71060
|
+
trackProps.signal_source = kpis.lineSignal?.source ?? null;
|
|
71061
|
+
}
|
|
70869
71062
|
}
|
|
70870
71063
|
trackCoreEvent("Line Card Clicked", trackProps);
|
|
70871
71064
|
if (activeTab === "leaderboard" && timeRange === "today" && isHistoricalLeaderboardDaily) {
|
|
@@ -70951,6 +71144,7 @@ var KPIsOverviewView = ({
|
|
|
70951
71144
|
isLoading: metricsLoading,
|
|
70952
71145
|
error: metricsError,
|
|
70953
71146
|
onClick: (kpis) => handleLineClick(line, kpis),
|
|
71147
|
+
efficiencyLegend,
|
|
70954
71148
|
supervisorEnabled,
|
|
70955
71149
|
supervisorName: supervisorNamesByLineId.get(line.id) || null,
|
|
70956
71150
|
supervisors: supervisorsByLineId?.get(line.id)
|
|
@@ -70972,6 +71166,7 @@ var KPIsOverviewView = ({
|
|
|
70972
71166
|
isLoading: metricsLoading,
|
|
70973
71167
|
error: metricsError,
|
|
70974
71168
|
isUptimeMode: viewType === "machine",
|
|
71169
|
+
efficiencyLegend,
|
|
70975
71170
|
onClick
|
|
70976
71171
|
},
|
|
70977
71172
|
key
|
|
@@ -77009,6 +77204,10 @@ var WorkspaceDetailView = ({
|
|
|
77009
77204
|
timezone
|
|
77010
77205
|
});
|
|
77011
77206
|
}, [isCurrentShiftView, workspace?.shift_start, workspace?.shift_end, idleClipDate, timezone]);
|
|
77207
|
+
const workspaceShiftBreaks = React144.useMemo(
|
|
77208
|
+
() => shiftConfig?.shifts?.find((shift2) => shift2.shiftId === workspace?.shift_id)?.breaks || [],
|
|
77209
|
+
[shiftConfig?.shifts, workspace?.shift_id]
|
|
77210
|
+
);
|
|
77012
77211
|
const uptimeSeries = React144.useMemo(
|
|
77013
77212
|
() => buildUptimeSeries({
|
|
77014
77213
|
idleTimeHourly: workspace?.idle_time_hourly,
|
|
@@ -77016,17 +77215,26 @@ var WorkspaceDetailView = ({
|
|
|
77016
77215
|
shiftEnd: workspace?.shift_end,
|
|
77017
77216
|
shiftDate: idleClipDate,
|
|
77018
77217
|
timezone,
|
|
77019
|
-
elapsedMinutes: elapsedShiftMinutes
|
|
77218
|
+
elapsedMinutes: elapsedShiftMinutes,
|
|
77219
|
+
shiftBreaks: workspaceShiftBreaks
|
|
77020
77220
|
}),
|
|
77021
|
-
[workspace?.idle_time_hourly, workspace?.shift_start, workspace?.shift_end, idleClipDate, timezone, elapsedShiftMinutes]
|
|
77221
|
+
[workspace?.idle_time_hourly, workspace?.shift_start, workspace?.shift_end, idleClipDate, timezone, elapsedShiftMinutes, workspaceShiftBreaks]
|
|
77022
77222
|
);
|
|
77023
77223
|
const uptimePieData = React144.useMemo(() => {
|
|
77024
77224
|
if (!isUptimeMode) return [];
|
|
77025
77225
|
let activeMinutes = uptimeSeries.activeMinutes;
|
|
77026
77226
|
let idleMinutes = uptimeSeries.idleMinutes;
|
|
77027
77227
|
let totalMinutes = uptimeSeries.availableMinutes;
|
|
77028
|
-
const fallbackDuration =
|
|
77029
|
-
|
|
77228
|
+
const fallbackDuration = getBreakExcludedShiftMinutes({
|
|
77229
|
+
shiftStart: workspace?.shift_start,
|
|
77230
|
+
shiftEnd: workspace?.shift_end,
|
|
77231
|
+
elapsedMinutes: elapsedShiftMinutes,
|
|
77232
|
+
shiftBreaks: workspaceShiftBreaks
|
|
77233
|
+
}) ?? elapsedShiftMinutes ?? shiftDurationMinutes;
|
|
77234
|
+
const hasIdleHourlyPayload = Boolean(
|
|
77235
|
+
workspace?.idle_time_hourly && typeof workspace.idle_time_hourly === "object" && Object.keys(workspace.idle_time_hourly).length > 0
|
|
77236
|
+
);
|
|
77237
|
+
if (!uptimeSeries.hasData && !hasIdleHourlyPayload && fallbackDuration !== null && fallbackDuration !== void 0) {
|
|
77030
77238
|
const idleSeconds = Number(workspace?.idle_time || 0);
|
|
77031
77239
|
const idleFromAggregate = Math.min(Math.max(Math.round(idleSeconds / 60), 0), fallbackDuration);
|
|
77032
77240
|
const activeFromAggregate = Math.max(fallbackDuration - idleFromAggregate, 0);
|
|
@@ -77039,7 +77247,7 @@ var WorkspaceDetailView = ({
|
|
|
77039
77247
|
{ name: "Productive", value: activeMinutes },
|
|
77040
77248
|
{ name: "Idle", value: idleMinutes }
|
|
77041
77249
|
];
|
|
77042
|
-
}, [isUptimeMode, uptimeSeries, shiftDurationMinutes, elapsedShiftMinutes, workspace?.idle_time]);
|
|
77250
|
+
}, [isUptimeMode, uptimeSeries, shiftDurationMinutes, elapsedShiftMinutes, workspace?.idle_time, workspace?.shift_start, workspace?.shift_end, workspaceShiftBreaks]);
|
|
77043
77251
|
const overviewTabLabel = isUptimeMode ? "Utilization" : "Efficiency";
|
|
77044
77252
|
const idleClipFetchEnabled = Boolean(
|
|
77045
77253
|
workspaceId && idleClipDate && idleClipShiftId !== void 0 && activeTab === "overview" && idleTimeVlmEnabled && isOutputLayout
|
|
@@ -77518,7 +77726,8 @@ var WorkspaceDetailView = ({
|
|
|
77518
77726
|
shiftEnd: workspace.shift_end,
|
|
77519
77727
|
shiftDate: idleClipDate,
|
|
77520
77728
|
timezone,
|
|
77521
|
-
elapsedMinutes: elapsedShiftMinutes
|
|
77729
|
+
elapsedMinutes: elapsedShiftMinutes,
|
|
77730
|
+
shiftBreaks: workspaceShiftBreaks
|
|
77522
77731
|
}
|
|
77523
77732
|
) : isAssemblyCycleLayout ? shouldShowCycleTimeUnavailableState ? cycleTimeUnavailableView : shouldShowCycleTimeChart ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
77524
77733
|
CycleTimeOverTimeChart,
|
|
@@ -77671,7 +77880,8 @@ var WorkspaceDetailView = ({
|
|
|
77671
77880
|
shiftEnd: workspace.shift_end,
|
|
77672
77881
|
shiftDate: idleClipDate,
|
|
77673
77882
|
timezone,
|
|
77674
|
-
elapsedMinutes: elapsedShiftMinutes
|
|
77883
|
+
elapsedMinutes: elapsedShiftMinutes,
|
|
77884
|
+
shiftBreaks: workspaceShiftBreaks
|
|
77675
77885
|
}
|
|
77676
77886
|
) : isAssemblyCycleLayout ? shouldShowCycleTimeUnavailableState ? cycleTimeUnavailableView : shouldShowCycleTimeChart ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
77677
77887
|
CycleTimeOverTimeChart,
|
|
@@ -87143,6 +87353,7 @@ exports.KPIDetailView = KPIDetailView_default;
|
|
|
87143
87353
|
exports.KPIGrid = KPIGrid;
|
|
87144
87354
|
exports.KPIHeader = KPIHeader;
|
|
87145
87355
|
exports.KPISection = KPISection;
|
|
87356
|
+
exports.KPI_SIGNAL_LABELS = KPI_SIGNAL_LABELS;
|
|
87146
87357
|
exports.KPIsOverviewView = KPIsOverviewView_default;
|
|
87147
87358
|
exports.LINE_1_UUID = LINE_1_UUID;
|
|
87148
87359
|
exports.LINE_2_UUID = LINE_2_UUID;
|
|
@@ -87276,6 +87487,7 @@ exports.WorkspaceWhatsAppShareButton = WorkspaceWhatsAppShareButton;
|
|
|
87276
87487
|
exports.actionService = actionService;
|
|
87277
87488
|
exports.addSentryBreadcrumb = addSentryBreadcrumb;
|
|
87278
87489
|
exports.aggregateKPIsFromLineMetricsRows = aggregateKPIsFromLineMetricsRows;
|
|
87490
|
+
exports.aggregateLineSignals = aggregateLineSignals;
|
|
87279
87491
|
exports.alertsService = alertsService;
|
|
87280
87492
|
exports.apiUtils = apiUtils;
|
|
87281
87493
|
exports.areAllLinesOnSameShift = areAllLinesOnSameShift;
|
|
@@ -87380,6 +87592,8 @@ exports.getDefaultCameraStreamUrl = getDefaultCameraStreamUrl;
|
|
|
87380
87592
|
exports.getDefaultLineId = getDefaultLineId;
|
|
87381
87593
|
exports.getDefaultTabForWorkspace = getDefaultTabForWorkspace;
|
|
87382
87594
|
exports.getInitials = getInitials;
|
|
87595
|
+
exports.getKpiSignalLabel = getKpiSignalLabel;
|
|
87596
|
+
exports.getKpiSignalStatus = getKpiSignalStatus;
|
|
87383
87597
|
exports.getLineDisplayName = getLineDisplayName;
|
|
87384
87598
|
exports.getManufacturingInsights = getManufacturingInsights;
|
|
87385
87599
|
exports.getMetricsTablePrefix = getMetricsTablePrefix;
|