@optifye/dashboard-core 6.11.33 → 6.11.34

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.mjs CHANGED
@@ -4545,6 +4545,49 @@ var dashboardService = {
4545
4545
  throw err;
4546
4546
  }
4547
4547
  },
4548
+ async getAssemblyMonthlyPoorestPerformers(lineIdInput, month, year, options) {
4549
+ const supabase = _getSupabaseInstance();
4550
+ const config = _getDashboardConfigInstance();
4551
+ const entityConfig = config.entityConfig ?? DEFAULT_ENTITY_CONFIG;
4552
+ const configuredLineIds = getConfiguredLineIds(entityConfig);
4553
+ const factoryViewId = entityConfig.factoryViewId ?? "factory";
4554
+ const startDate = options?.startDate ? new Date(options.startDate) : new Date(year, month, 1);
4555
+ const endDate = options?.endDate ? new Date(options.endDate) : new Date(year, month + 1, 0);
4556
+ const formatDate2 = (date) => {
4557
+ const year2 = date.getFullYear();
4558
+ const month2 = String(date.getMonth() + 1).padStart(2, "0");
4559
+ const day = String(date.getDate()).padStart(2, "0");
4560
+ return `${year2}-${month2}-${day}`;
4561
+ };
4562
+ const formattedStartDate = formatDate2(startDate);
4563
+ const formattedEndDate = formatDate2(endDate);
4564
+ const params = new URLSearchParams({
4565
+ start_date: formattedStartDate,
4566
+ end_date: formattedEndDate,
4567
+ company_id: entityConfig.companyId || ""
4568
+ });
4569
+ if (lineIdInput === factoryViewId) {
4570
+ if (!isValidFactoryViewConfiguration(entityConfig)) {
4571
+ throw new Error("Factory View requires at least one configured line for monthly data.");
4572
+ }
4573
+ params.set("line_ids", configuredLineIds.join(","));
4574
+ } else {
4575
+ params.set("line_id", lineIdInput);
4576
+ }
4577
+ if (options?.shiftIds && options.shiftIds.length > 0) {
4578
+ params.set("shift_ids", options.shiftIds.join(","));
4579
+ }
4580
+ try {
4581
+ const response = await fetchBackendJson(
4582
+ supabase,
4583
+ `/api/dashboard/line-monthly-assembly-poorest-performers?${params.toString()}`
4584
+ );
4585
+ return response || {};
4586
+ } catch (err) {
4587
+ console.error("Exception in getAssemblyMonthlyPoorestPerformers:", err);
4588
+ throw err;
4589
+ }
4590
+ },
4548
4591
  async getUnderperformingWorkspaces(lineIdInput, monthInput, yearInput, shiftIds, startDate, endDate) {
4549
4592
  _getSupabaseInstance();
4550
4593
  const config = _getDashboardConfigInstance();
@@ -16685,6 +16728,7 @@ var runtimeWorkspaceDisplayNames = {};
16685
16728
  var isInitialized = false;
16686
16729
  var isInitializing = false;
16687
16730
  var initializedWithLineIds = [];
16731
+ var missingLineContextWarnings = /* @__PURE__ */ new Set();
16688
16732
  var initializationPromise = null;
16689
16733
  var workspaceDisplayNamesListeners = /* @__PURE__ */ new Set();
16690
16734
  var notifyWorkspaceDisplayNamesListeners = (changedLineId) => {
@@ -16854,6 +16898,9 @@ var forceRefreshWorkspaceDisplayNames = async (lineId) => {
16854
16898
  };
16855
16899
  console.log("\u{1F504} Module loaded, will initialize lazily when first function is called");
16856
16900
  var getWorkspaceDisplayName = (workspaceId, lineId) => {
16901
+ if (!workspaceId) {
16902
+ return workspaceId;
16903
+ }
16857
16904
  if (!isInitialized && !isInitializing) {
16858
16905
  console.log(`\u{1F504} [DEBUG] getWorkspaceDisplayName(${workspaceId}, lineId: ${lineId}) - Not initialized, triggering lazy init...`);
16859
16906
  } else if (isInitializing) {
@@ -16885,7 +16932,11 @@ var getWorkspaceDisplayName = (workspaceId, lineId) => {
16885
16932
  for (const cachedLineId of Object.keys(runtimeWorkspaceDisplayNames)) {
16886
16933
  if (runtimeWorkspaceDisplayNames[cachedLineId][workspaceId]) {
16887
16934
  displayName = runtimeWorkspaceDisplayNames[cachedLineId][workspaceId];
16888
- console.warn(`\u26A0\uFE0F No lineId provided for ${workspaceId}, found in line ${cachedLineId}`);
16935
+ const warningKey = `${workspaceId}:${cachedLineId}:full`;
16936
+ if (!missingLineContextWarnings.has(warningKey)) {
16937
+ missingLineContextWarnings.add(warningKey);
16938
+ console.warn(`\u26A0\uFE0F No lineId provided for ${workspaceId}, found in line ${cachedLineId}`);
16939
+ }
16889
16940
  break;
16890
16941
  }
16891
16942
  }
@@ -16900,6 +16951,9 @@ var getWorkspaceDisplayName = (workspaceId, lineId) => {
16900
16951
  }
16901
16952
  };
16902
16953
  var getShortWorkspaceDisplayName = (workspaceId, lineId) => {
16954
+ if (!workspaceId) {
16955
+ return workspaceId;
16956
+ }
16903
16957
  if (!isInitialized && !isInitializing) {
16904
16958
  console.log("\u{1F504} Lazy initialization triggered by getShortWorkspaceDisplayName with lineId:", lineId);
16905
16959
  initializeWorkspaceDisplayNames(lineId).catch((error) => {
@@ -16926,7 +16980,11 @@ var getShortWorkspaceDisplayName = (workspaceId, lineId) => {
16926
16980
  for (const cachedLineId of Object.keys(runtimeWorkspaceDisplayNames)) {
16927
16981
  if (runtimeWorkspaceDisplayNames[cachedLineId][workspaceId]) {
16928
16982
  displayName = runtimeWorkspaceDisplayNames[cachedLineId][workspaceId];
16929
- console.warn(`\u26A0\uFE0F No lineId provided for ${workspaceId}, found in line ${cachedLineId}`);
16983
+ const warningKey = `${workspaceId}:${cachedLineId}:short`;
16984
+ if (!missingLineContextWarnings.has(warningKey)) {
16985
+ missingLineContextWarnings.add(warningKey);
16986
+ console.warn(`\u26A0\uFE0F No lineId provided for ${workspaceId}, found in line ${cachedLineId}`);
16987
+ }
16930
16988
  break;
16931
16989
  }
16932
16990
  }
@@ -17798,7 +17856,6 @@ var usePrefetchClipCounts = ({
17798
17856
  subscriberId
17799
17857
  }) => {
17800
17858
  const [status] = useState("idle" /* IDLE */);
17801
- console.log("[usePrefetchClipCounts] DISABLED - Returning empty state");
17802
17859
  return {
17803
17860
  status,
17804
17861
  data: null,
@@ -17807,7 +17864,6 @@ var usePrefetchClipCounts = ({
17807
17864
  isFullyIndexed: false,
17808
17865
  isLoading: false,
17809
17866
  prefetchClipCounts: async () => {
17810
- console.log("[usePrefetchClipCounts] DISABLED - Not prefetching");
17811
17867
  return null;
17812
17868
  },
17813
17869
  cacheKey: `disabled:${workspaceId}:${date}:${shift}`
@@ -37307,37 +37363,101 @@ var getSeverityColor = (severity) => {
37307
37363
  return "bg-gray-500";
37308
37364
  }
37309
37365
  };
37310
- var formatIdleTimeRange = (startTime, endTime, timezone) => {
37311
- const roundToNearestMinute = (date) => {
37312
- const rounded = new Date(date.getTime());
37313
- const seconds = rounded.getSeconds();
37314
- if (seconds > 30) {
37315
- rounded.setMinutes(rounded.getMinutes() + 1);
37316
- }
37317
- rounded.setSeconds(0);
37318
- rounded.setMilliseconds(0);
37319
- return rounded;
37320
- };
37321
- const startDate = roundToNearestMinute(new Date(startTime));
37322
- const endDate = roundToNearestMinute(new Date(endTime));
37323
- const formatTimeWithoutPeriod = (date, tz) => {
37324
- return date.toLocaleTimeString("en-US", {
37325
- hour: "numeric",
37326
- minute: "2-digit",
37327
- timeZone: tz
37328
- }).replace(/\s?(AM|PM)$/i, "");
37329
- };
37330
- const formatTimeWithPeriod = (date, tz) => {
37331
- return date.toLocaleTimeString("en-US", {
37332
- hour: "numeric",
37333
- minute: "2-digit",
37334
- timeZone: tz
37335
- });
37336
- };
37337
- const startFormatted = formatTimeWithoutPeriod(startDate, timezone);
37338
- const endFormatted = formatTimeWithPeriod(endDate, timezone);
37366
+ var IDLE_RANGE_CATEGORY_IDS = /* @__PURE__ */ new Set(["idle_time", "low_value", "longest-idles"]);
37367
+ var CYCLE_RANGE_CATEGORY_IDS = /* @__PURE__ */ new Set([
37368
+ "cycle_completion",
37369
+ "best_cycle_time",
37370
+ "worst_cycle_time",
37371
+ "long_cycle_time",
37372
+ "fast-cycles",
37373
+ "slow-cycles"
37374
+ ]);
37375
+ var roundToNearestMinute = (date) => {
37376
+ const rounded = new Date(date.getTime());
37377
+ const seconds = rounded.getSeconds();
37378
+ if (seconds > 30) {
37379
+ rounded.setMinutes(rounded.getMinutes() + 1);
37380
+ }
37381
+ rounded.setSeconds(0);
37382
+ rounded.setMilliseconds(0);
37383
+ return rounded;
37384
+ };
37385
+ var parseTimestamp = (value) => {
37386
+ if (!value) return null;
37387
+ const parsed = new Date(value);
37388
+ return Number.isNaN(parsed.getTime()) ? null : parsed;
37389
+ };
37390
+ var formatTimeWithoutPeriod = (date, timezone) => date.toLocaleTimeString("en-US", {
37391
+ hour: "numeric",
37392
+ minute: "2-digit",
37393
+ timeZone: timezone
37394
+ }).replace(/\s?(AM|PM)$/i, "");
37395
+ var formatClipExplorerSingleTime = (timestamp, timezone) => {
37396
+ const parsed = parseTimestamp(timestamp);
37397
+ if (!parsed) return "";
37398
+ return parsed.toLocaleTimeString("en-US", {
37399
+ hour12: true,
37400
+ hour: "numeric",
37401
+ minute: "2-digit",
37402
+ timeZone: timezone
37403
+ });
37404
+ };
37405
+ var formatTimestampRange = (startTime, endTime, timezone) => {
37406
+ const startDate = parseTimestamp(startTime);
37407
+ const endDate = parseTimestamp(endTime);
37408
+ if (!startDate || !endDate) {
37409
+ return formatClipExplorerSingleTime(endTime, timezone);
37410
+ }
37411
+ const roundedStart = roundToNearestMinute(startDate);
37412
+ const roundedEnd = roundToNearestMinute(endDate);
37413
+ const startFormatted = formatTimeWithoutPeriod(roundedStart, timezone);
37414
+ const endFormatted = roundedEnd.toLocaleTimeString("en-US", {
37415
+ hour: "numeric",
37416
+ minute: "2-digit",
37417
+ timeZone: timezone
37418
+ });
37339
37419
  return `${startFormatted} - ${endFormatted}`;
37340
37420
  };
37421
+ var getSecondsBetweenTimestamps = (startTime, endTime) => {
37422
+ const startDate = parseTimestamp(startTime);
37423
+ const endDate = parseTimestamp(endTime);
37424
+ if (!startDate || !endDate) return null;
37425
+ return Math.max(0, (endDate.getTime() - startDate.getTime()) / 1e3);
37426
+ };
37427
+ var formatClipExplorerTimeLabel = ({
37428
+ categoryId,
37429
+ clipTimestamp,
37430
+ timezone,
37431
+ durationSeconds,
37432
+ idleStartTime,
37433
+ idleEndTime
37434
+ }) => {
37435
+ if (IDLE_RANGE_CATEGORY_IDS.has(categoryId)) {
37436
+ const idleDurationSeconds = getSecondsBetweenTimestamps(idleStartTime, idleEndTime);
37437
+ const idleEndTimestamp = idleEndTime || clipTimestamp;
37438
+ if (idleDurationSeconds !== null && idleDurationSeconds >= 60 && idleStartTime && idleEndTime) {
37439
+ return formatTimestampRange(idleStartTime, idleEndTime, timezone);
37440
+ }
37441
+ if (idleDurationSeconds === null && typeof durationSeconds === "number" && Number.isFinite(durationSeconds) && durationSeconds >= 60) {
37442
+ const endDate = parseTimestamp(idleEndTimestamp);
37443
+ if (endDate) {
37444
+ const startDate = new Date(endDate.getTime() - durationSeconds * 1e3);
37445
+ return formatTimestampRange(startDate.toISOString(), idleEndTimestamp, timezone);
37446
+ }
37447
+ }
37448
+ return formatClipExplorerSingleTime(idleEndTimestamp, timezone);
37449
+ }
37450
+ const singleTime = formatClipExplorerSingleTime(clipTimestamp, timezone);
37451
+ if (CYCLE_RANGE_CATEGORY_IDS.has(categoryId) && typeof durationSeconds === "number" && Number.isFinite(durationSeconds) && durationSeconds > 60) {
37452
+ const endDate = parseTimestamp(clipTimestamp);
37453
+ if (endDate) {
37454
+ const startDate = new Date(endDate.getTime() - durationSeconds * 1e3);
37455
+ return formatTimestampRange(startDate.toISOString(), clipTimestamp, timezone);
37456
+ }
37457
+ }
37458
+ return singleTime;
37459
+ };
37460
+ var formatIdleTimeRange = (startTime, endTime, timezone) => formatTimestampRange(startTime, endTime, timezone);
37341
37461
  var formatTime2 = (seconds) => {
37342
37462
  if (!seconds || isNaN(seconds)) return "0:00";
37343
37463
  const h = Math.floor(seconds / 3600);
@@ -41304,15 +41424,16 @@ var FileManagerFilters = ({
41304
41424
  if ((displayCount > 0 || shouldShowEmptyIdleTime) && shouldShowCategory(category.id)) {
41305
41425
  const colorClasses = getColorClasses(category.color);
41306
41426
  const clipNodes = filteredClips.map((clip, index) => {
41307
- const timeString = new Date(clip.clip_timestamp).toLocaleTimeString("en-US", {
41308
- hour12: true,
41309
- hour: "numeric",
41310
- minute: "2-digit",
41311
- timeZone: timezone
41312
- // Use database timezone for display
41313
- });
41314
41427
  const cycleTime = extractCycleTimeSeconds(clip);
41315
- const displayLabel = category.id === "idle_time" && clip.idle_start_time && clip.idle_end_time ? formatIdleTimeRange(clip.idle_start_time, clip.idle_end_time, timezone) : `${timeString}${clip.duration && category.id !== "idle_time" ? ` - (${clip.duration.toFixed(1)}s)` : ""}`;
41428
+ const baseTimeLabel = formatClipExplorerTimeLabel({
41429
+ categoryId: category.id,
41430
+ clipTimestamp: clip.clip_timestamp,
41431
+ timezone,
41432
+ durationSeconds: clip.duration,
41433
+ idleStartTime: clip.idle_start_time,
41434
+ idleEndTime: clip.idle_end_time
41435
+ });
41436
+ const displayLabel = `${baseTimeLabel}${clip.duration && category.id !== "idle_time" && category.id !== "low_value" ? ` - (${clip.duration.toFixed(1)}s)` : ""}`;
41316
41437
  return {
41317
41438
  id: clip.id,
41318
41439
  label: displayLabel,
@@ -41363,16 +41484,15 @@ var FileManagerFilters = ({
41363
41484
  percentileType: "fast-cycles",
41364
41485
  isPercentile: true,
41365
41486
  children: filteredFastCycles.map((clip, index) => {
41366
- const timeString = new Date(clip.creation_timestamp || clip.timestamp || "").toLocaleTimeString("en-US", {
41367
- hour12: true,
41368
- hour: "numeric",
41369
- minute: "2-digit",
41370
- timeZone: timezone
41371
- });
41372
41487
  const cycleTime = extractCycleTimeSeconds(clip);
41373
41488
  return {
41374
41489
  id: clip.id,
41375
- label: `${timeString}${clip.cycle_time_seconds ? ` - (${clip.cycle_time_seconds.toFixed(1)}s)` : ""}`,
41490
+ label: `${formatClipExplorerTimeLabel({
41491
+ categoryId: "fast-cycles",
41492
+ clipTimestamp: clip.creation_timestamp || clip.timestamp || "",
41493
+ timezone,
41494
+ durationSeconds: cycleTime
41495
+ })}${clip.cycle_time_seconds ? ` - (${clip.cycle_time_seconds.toFixed(1)}s)` : ""}`,
41376
41496
  type: "video",
41377
41497
  icon: getSeverityIcon(clip.severity, "fast-cycles", cycleTime, resolvedTargetCycleTime),
41378
41498
  timestamp: clip.creation_timestamp,
@@ -41395,16 +41515,15 @@ var FileManagerFilters = ({
41395
41515
  percentileType: "slow-cycles",
41396
41516
  isPercentile: true,
41397
41517
  children: filteredSlowCycles.map((clip, index) => {
41398
- const timeString = new Date(clip.creation_timestamp || clip.timestamp || "").toLocaleTimeString("en-US", {
41399
- hour12: true,
41400
- hour: "numeric",
41401
- minute: "2-digit",
41402
- timeZone: timezone
41403
- });
41404
41518
  const cycleTime = extractCycleTimeSeconds(clip);
41405
41519
  return {
41406
41520
  id: clip.id,
41407
- label: `${timeString}${clip.cycle_time_seconds ? ` - (${clip.cycle_time_seconds.toFixed(1)}s)` : ""}`,
41521
+ label: `${formatClipExplorerTimeLabel({
41522
+ categoryId: "slow-cycles",
41523
+ clipTimestamp: clip.creation_timestamp || clip.timestamp || "",
41524
+ timezone,
41525
+ durationSeconds: cycleTime
41526
+ })}${clip.cycle_time_seconds ? ` - (${clip.cycle_time_seconds.toFixed(1)}s)` : ""}`,
41408
41527
  type: "video",
41409
41528
  icon: getSeverityIcon(clip.severity, "slow-cycles", cycleTime, resolvedTargetCycleTime),
41410
41529
  timestamp: clip.creation_timestamp,
@@ -46878,6 +46997,41 @@ var IdleTimeReasonChartComponent = ({
46878
46997
  var IdleTimeReasonChart = React143__default.memo(IdleTimeReasonChartComponent);
46879
46998
  IdleTimeReasonChart.displayName = "IdleTimeReasonChart";
46880
46999
  var IdleTimeReasonChart_default = IdleTimeReasonChart;
47000
+
47001
+ // src/lib/utils/cycleTime.ts
47002
+ var toFiniteNumber = (value) => {
47003
+ if (typeof value === "number" && Number.isFinite(value)) return value;
47004
+ if (typeof value === "string" && value.trim() !== "") {
47005
+ const parsed = Number(value);
47006
+ return Number.isFinite(parsed) ? parsed : null;
47007
+ }
47008
+ return null;
47009
+ };
47010
+ var getCycleRatio = (workspace) => {
47011
+ const idealCycleTime = toFiniteNumber(workspace.ideal_cycle_time);
47012
+ const avgCycleTime = toFiniteNumber(workspace.avg_cycle_time);
47013
+ if (idealCycleTime === null || avgCycleTime === null || idealCycleTime <= 0 || avgCycleTime <= 0) {
47014
+ return null;
47015
+ }
47016
+ return idealCycleTime / avgCycleTime;
47017
+ };
47018
+ var formatCycleTimeValue = (value) => {
47019
+ const numericValue = toFiniteNumber(value);
47020
+ if (numericValue === null || numericValue <= 0) return "--";
47021
+ return `${numericValue.toFixed(1)}s`;
47022
+ };
47023
+ var CycleTimeComparison = memo$1(({
47024
+ workspace
47025
+ }) => {
47026
+ const averageValue = formatCycleTimeValue(workspace.avg_cycle_time);
47027
+ const standardValue = formatCycleTimeValue(workspace.ideal_cycle_time);
47028
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 tabular-nums", children: [
47029
+ /* @__PURE__ */ jsx("span", { className: "font-semibold text-gray-900", children: averageValue }),
47030
+ /* @__PURE__ */ jsx("span", { className: "text-gray-400 font-normal", children: "/" }),
47031
+ /* @__PURE__ */ jsx("span", { className: "font-medium text-gray-500", children: standardValue })
47032
+ ] });
47033
+ }, (prevProps, nextProps) => prevProps.workspace.avg_cycle_time === nextProps.workspace.avg_cycle_time && prevProps.workspace.ideal_cycle_time === nextProps.workspace.ideal_cycle_time);
47034
+ CycleTimeComparison.displayName = "CycleTimeComparison";
46881
47035
  var DEFAULT_PERFORMANCE_DATA = {
46882
47036
  avg_efficiency: 0,
46883
47037
  underperforming_workspaces: 0,
@@ -46976,6 +47130,7 @@ var LineMonthlyHistory = ({
46976
47130
  timezone,
46977
47131
  legend,
46978
47132
  monitoringMode,
47133
+ lineAssembly = false,
46979
47134
  underperformingWorkspaces = {},
46980
47135
  lineId,
46981
47136
  selectedShiftId = 0,
@@ -47265,7 +47420,7 @@ var LineMonthlyHistory = ({
47265
47420
  "div",
47266
47421
  {
47267
47422
  className: `w-3 h-3 sm:w-4 sm:h-4 rounded ${getColorClass(performance2.performance_score)}`,
47268
- title: `${getPerformanceText(performance2.performance_score)} performance on ${new Date(performance2.date).toLocaleDateString()}${performance2.efficiency !== void 0 ? ` (${performance2.efficiency.toFixed(1)}% efficiency)` : ""}`
47423
+ title: `${getPerformanceText(performance2.performance_score)} performance on ${new Date(performance2.date).toLocaleDateString()}${performance2.efficiency !== void 0 ? ` (${performance2.efficiency.toFixed(1)}% efficiency)` : performance2.avg_cycle_time !== void 0 && performance2.avg_cycle_time !== null && performance2.ideal_cycle_time !== void 0 && performance2.ideal_cycle_time !== null ? ` (${performance2.avg_cycle_time.toFixed(1)}s / ${performance2.ideal_cycle_time.toFixed(1)}s cycle time)` : ""}`
47269
47424
  },
47270
47425
  `${performance2.date}-${index}`
47271
47426
  )) });
@@ -47511,13 +47666,20 @@ var LineMonthlyHistory = ({
47511
47666
  onClick: () => handleWorkspaceClick(workspace),
47512
47667
  className: "block hover:bg-gray-50 transition-colors rounded-lg w-full text-left group",
47513
47668
  children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between py-1 sm:py-1.5 lg:py-2 px-1 sm:px-2 border-b border-gray-50 group-last:border-b-0", children: [
47514
- /* @__PURE__ */ jsxs("div", { className: "font-medium text-gray-900 text-[10px] sm:text-xs", children: [
47515
- getWorkspaceDisplayName(workspace.workspace_name, lineId),
47516
- workspace.avg_efficiency !== void 0 && /* @__PURE__ */ jsxs("span", { className: "ml-0.5 sm:ml-1 text-[8px] sm:text-[10px] text-gray-500", children: [
47517
- "(",
47669
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
47670
+ /* @__PURE__ */ jsx("div", { className: "font-medium text-gray-900 text-[10px] sm:text-xs truncate", children: getWorkspaceDisplayName(workspace.workspace_name, lineId) }),
47671
+ lineAssembly && workspace.metric_mode === "cycle_time" ? /* @__PURE__ */ jsx("div", { className: "mt-0.5 text-[9px] sm:text-[11px]", children: /* @__PURE__ */ jsx(
47672
+ CycleTimeComparison,
47673
+ {
47674
+ workspace: {
47675
+ avg_cycle_time: workspace.avg_cycle_time ?? 0,
47676
+ ideal_cycle_time: workspace.ideal_cycle_time ?? void 0
47677
+ }
47678
+ }
47679
+ ) }) : workspace.avg_efficiency !== void 0 ? /* @__PURE__ */ jsxs("div", { className: "mt-0.5 text-[8px] sm:text-[10px] text-gray-500", children: [
47518
47680
  (workspace.avg_efficiency || 0).toFixed(1),
47519
- "%)"
47520
- ] })
47681
+ "%"
47682
+ ] }) : null
47521
47683
  ] }),
47522
47684
  /* @__PURE__ */ jsx("div", { className: "flex items-center gap-0.5 sm:gap-1 lg:gap-1.5", children: renderPerformanceSquares(workspace.last_5_days) })
47523
47685
  ] })
@@ -49887,7 +50049,7 @@ var WorkspaceMonthlyHistory = ({
49887
50049
  Math.round(shiftData.efficiency || 0),
49888
50050
  "%"
49889
50051
  ] }),
49890
- /* @__PURE__ */ jsxs("div", { children: [
50052
+ !isAssemblyWorkspace && /* @__PURE__ */ jsxs("div", { children: [
49891
50053
  "Output: ",
49892
50054
  shiftData.output || 0,
49893
50055
  " units"
@@ -62030,41 +62192,6 @@ function useEfficiencyLegend(companyId) {
62030
62192
  };
62031
62193
  }
62032
62194
 
62033
- // src/lib/utils/cycleTime.ts
62034
- var toFiniteNumber = (value) => {
62035
- if (typeof value === "number" && Number.isFinite(value)) return value;
62036
- if (typeof value === "string" && value.trim() !== "") {
62037
- const parsed = Number(value);
62038
- return Number.isFinite(parsed) ? parsed : null;
62039
- }
62040
- return null;
62041
- };
62042
- var getCycleRatio = (workspace) => {
62043
- const idealCycleTime = toFiniteNumber(workspace.ideal_cycle_time);
62044
- const avgCycleTime = toFiniteNumber(workspace.avg_cycle_time);
62045
- if (idealCycleTime === null || avgCycleTime === null || idealCycleTime <= 0 || avgCycleTime <= 0) {
62046
- return null;
62047
- }
62048
- return idealCycleTime / avgCycleTime;
62049
- };
62050
- var formatCycleTimeValue = (value) => {
62051
- const numericValue = toFiniteNumber(value);
62052
- if (numericValue === null || numericValue <= 0) return "--";
62053
- return `${numericValue.toFixed(1)}s`;
62054
- };
62055
- var CycleTimeComparison = memo$1(({
62056
- workspace
62057
- }) => {
62058
- const averageValue = formatCycleTimeValue(workspace.avg_cycle_time);
62059
- const standardValue = formatCycleTimeValue(workspace.ideal_cycle_time);
62060
- return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 tabular-nums", children: [
62061
- /* @__PURE__ */ jsx("span", { className: "font-semibold text-gray-900", children: averageValue }),
62062
- /* @__PURE__ */ jsx("span", { className: "text-gray-400 font-normal", children: "/" }),
62063
- /* @__PURE__ */ jsx("span", { className: "font-medium text-gray-500", children: standardValue })
62064
- ] });
62065
- }, (prevProps, nextProps) => prevProps.workspace.avg_cycle_time === nextProps.workspace.avg_cycle_time && prevProps.workspace.ideal_cycle_time === nextProps.workspace.ideal_cycle_time);
62066
- CycleTimeComparison.displayName = "CycleTimeComparison";
62067
-
62068
62195
  // src/lib/utils/kpiPoorestPerformers.ts
62069
62196
  var getWorstAssemblyCycleTimeWorkspaces = (workspaces, limit = 5) => {
62070
62197
  return workspaces.map((workspace, index) => ({
@@ -63252,27 +63379,33 @@ var KPIDetailView = ({
63252
63379
  error: idleTimeError
63253
63380
  }), [idleTimeRawData, idleTimeChartData, idleTimeLoading, idleTimeError]);
63254
63381
  useEffect(() => {
63255
- if (activeTab === "monthly_history" && lineId) {
63382
+ if (activeTab === "monthly_history" && lineId && lineDetails) {
63256
63383
  if (!supabase || !dashboardConfig || !dashboardConfig.supabaseUrl || !dashboardConfig.supabaseKey) {
63257
63384
  console.error("Supabase client or required config not available in KPIsPage for monthly data");
63258
63385
  return;
63259
63386
  }
63260
63387
  setMonthlyDataLoading(true);
63388
+ const monthlyShiftIds = shiftConfig?.shifts?.map((s) => s.shiftId);
63389
+ const monthlyHistoryAssemblyMode = lineDetails.assembly === true && !isUptimeMode;
63390
+ const underperformingPromise = monthlyHistoryAssemblyMode ? dashboardService.getAssemblyMonthlyPoorestPerformers(lineId, currentMonth, currentYear, {
63391
+ startDate: isFullRange ? void 0 : range.startKey,
63392
+ endDate: isFullRange ? void 0 : range.endKey,
63393
+ shiftIds: monthlyShiftIds
63394
+ }) : dashboardService.getUnderperformingWorkspaces(
63395
+ lineId,
63396
+ currentMonth,
63397
+ currentYear,
63398
+ monthlyShiftIds,
63399
+ isFullRange ? void 0 : range.startKey,
63400
+ isFullRange ? void 0 : range.endKey
63401
+ );
63261
63402
  Promise.all([
63262
63403
  dashboardService.getLineMonthlyData(lineId, currentMonth, currentYear, {
63263
63404
  startDate: isFullRange ? void 0 : range.startKey,
63264
63405
  endDate: isFullRange ? void 0 : range.endKey,
63265
- shiftIds: shiftConfig?.shifts?.map((s) => s.shiftId)
63406
+ shiftIds: monthlyShiftIds
63266
63407
  }),
63267
- dashboardService.getUnderperformingWorkspaces(
63268
- lineId,
63269
- currentMonth,
63270
- currentYear,
63271
- shiftConfig?.shifts?.map((s) => s.shiftId),
63272
- // Pass dynamic shift IDs
63273
- isFullRange ? void 0 : range.startKey,
63274
- isFullRange ? void 0 : range.endKey
63275
- )
63408
+ underperformingPromise
63276
63409
  ]).then(([monthlyMetrics, underperformingData]) => {
63277
63410
  console.log("Fetched monthly metrics data:", monthlyMetrics);
63278
63411
  const dayDataMap = /* @__PURE__ */ new Map();
@@ -63336,11 +63469,17 @@ var KPIDetailView = ({
63336
63469
  const mapWorkspaces = (workspaces2) => (workspaces2 || []).map((ws) => ({
63337
63470
  workspace_name: ws.workspace_name || "Unknown Workspace",
63338
63471
  workspace_uuid: ws.workspace_uuid || ws.workspace_name || `unknown-${Math.random()}`,
63339
- avg_efficiency: ws.avg_efficiency || 0,
63472
+ avg_efficiency: ws.avg_efficiency ?? 0,
63473
+ avg_cycle_time: ws.avg_cycle_time ?? null,
63474
+ ideal_cycle_time: ws.ideal_cycle_time ?? null,
63475
+ cycle_ratio: ws.cycle_ratio ?? null,
63476
+ metric_mode: ws.metric_mode ?? "efficiency",
63340
63477
  last_5_days: (ws.last_5_days || []).map((day) => ({
63341
63478
  date: day.date,
63342
63479
  efficiency: day.efficiency ?? 0,
63343
- performance_score: day.performance_score
63480
+ performance_score: day.performance_score,
63481
+ avg_cycle_time: day.avg_cycle_time ?? null,
63482
+ ideal_cycle_time: day.ideal_cycle_time ?? null
63344
63483
  }))
63345
63484
  }));
63346
63485
  const mappedData = {};
@@ -63365,7 +63504,7 @@ var KPIDetailView = ({
63365
63504
  setMonthlyDataLoading(false);
63366
63505
  });
63367
63506
  }
63368
- }, [activeTab, lineId, currentMonth, currentYear, supabase, dashboardConfig, shiftConfig, range.startKey, range.endKey, isFullRange, configuredTimezone, isUptimeMode, resolveShiftTimes]);
63507
+ }, [activeTab, lineId, lineDetails, currentMonth, currentYear, supabase, dashboardConfig, shiftConfig, range.startKey, range.endKey, isFullRange, configuredTimezone, isUptimeMode, resolveShiftTimes]);
63369
63508
  const analysisMonthlyData = useMemo(() => {
63370
63509
  return filterDataByDateKeyRange(monthlyData, range);
63371
63510
  }, [monthlyData, range]);
@@ -64271,6 +64410,7 @@ var KPIDetailView = ({
64271
64410
  timezone: configuredTimezone,
64272
64411
  legend: efficiencyLegend,
64273
64412
  monitoringMode: resolvedMonitoringMode,
64413
+ lineAssembly: resolvedLineInfo?.assembly === true,
64274
64414
  shiftConfig,
64275
64415
  selectedShiftId,
64276
64416
  onShiftChange: setSelectedShiftId,
@@ -70597,7 +70737,20 @@ var WorkspaceDetailView = ({
70597
70737
  } = useCompanyFastSlowClipFiltersEnabled();
70598
70738
  const isClipsEnabled = dashboardConfig?.clipsConfig?.enabled ?? true;
70599
70739
  dashboardConfig?.supervisorConfig?.enabled || false;
70600
- const effectiveLineId = lineId || selectedLineId;
70740
+ const routedLineId = lineId || selectedLineId;
70741
+ const latestCachedDetailedMetrics = useMemo(() => {
70742
+ if (!workspaceId) {
70743
+ return null;
70744
+ }
70745
+ return workspaceMetricsStore.getLatestDetailed(workspaceId);
70746
+ }, [workspaceId]);
70747
+ const latestCachedOverviewMetrics = useMemo(() => {
70748
+ if (!workspaceId) {
70749
+ return null;
70750
+ }
70751
+ return workspaceMetricsStore.getLatestOverview(workspaceId);
70752
+ }, [workspaceId]);
70753
+ const effectiveLineId = routedLineId || latestCachedDetailedMetrics?.line_id || latestCachedOverviewMetrics?.line_id;
70601
70754
  const { shiftConfig, isLoading: isShiftConfigLoading, isFromDatabase: isShiftConfigFromDatabase } = useDynamicShiftConfig(effectiveLineId);
70602
70755
  const currentShiftDetails = useMemo(() => {
70603
70756
  if (isShiftConfigLoading || !shiftConfig) return null;
@@ -70874,8 +71027,9 @@ var WorkspaceDetailView = ({
70874
71027
  }, [cachedOverviewMetrics, shiftConfig?.shifts]);
70875
71028
  const authoritativeCycleMetrics = isHistoricView ? historicMetrics : liveMetrics;
70876
71029
  const workspace = authoritativeCycleMetrics || cachedDetailedMetrics || overviewFallback;
71030
+ const resolvedLineId = effectiveLineId || workspace?.line_id || cachedDetailedMetrics?.line_id || cachedOverviewMetrics?.line_id || overviewFallback?.line_id;
70877
71031
  const { timezone: cycleTimeTimezone } = useTimezone({
70878
- lineId: effectiveLineId || workspace?.line_id || void 0,
71032
+ lineId: resolvedLineId || void 0,
70879
71033
  workspaceId: workspaceId || void 0
70880
71034
  });
70881
71035
  const effectiveCycleTimeTimezone = cycleTimeTimezone || timezone;
@@ -70920,7 +71074,7 @@ var WorkspaceDetailView = ({
70920
71074
  const error = isHistoricView ? historicError : liveError;
70921
71075
  const monitoringMode = workspace?.monitoring_mode ?? "output";
70922
71076
  const isUptimeMode = monitoringMode === "uptime";
70923
- const idleTimeVlmEnabled = isIdleTimeVlmEnabled(effectiveLineId || workspace?.line_id);
71077
+ const idleTimeVlmEnabled = isIdleTimeVlmEnabled(resolvedLineId);
70924
71078
  useEffect(() => {
70925
71079
  if (!isClipsEnabled || !dashboardConfig?.s3Config || !workspaceId) {
70926
71080
  return;
@@ -71155,7 +71309,7 @@ var WorkspaceDetailView = ({
71155
71309
  const analysisMonthlyData = useMemo(() => {
71156
71310
  return filterDataByDateKeyRange(monthlyData, range);
71157
71311
  }, [monthlyData, range]);
71158
- const formattedWorkspaceName = displayName || formatWorkspaceName3(workspace?.workspace_name || "", effectiveLineId);
71312
+ const formattedWorkspaceName = displayName || formatWorkspaceName3(workspace?.workspace_name || "", resolvedLineId);
71159
71313
  const workspaceCycleTimeEligibility = workspace ? {
71160
71314
  line_assembly_enabled: workspace.line_assembly_enabled,
71161
71315
  action_family: workspace.action_family,
@@ -71332,8 +71486,8 @@ var WorkspaceDetailView = ({
71332
71486
  params.set("rangeStart", range.startKey);
71333
71487
  params.set("rangeEnd", range.endKey);
71334
71488
  }
71335
- if (effectiveLineId) {
71336
- params.set("lineId", effectiveLineId);
71489
+ if (resolvedLineId) {
71490
+ params.set("lineId", resolvedLineId);
71337
71491
  }
71338
71492
  appendReturnUrl(params);
71339
71493
  onNavigate(`/workspace/${workspaceId}?${params.toString()}`);
@@ -71362,8 +71516,8 @@ var WorkspaceDetailView = ({
71362
71516
  params.set("rangeStart", range.startKey);
71363
71517
  params.set("rangeEnd", range.endKey);
71364
71518
  }
71365
- if (effectiveLineId) {
71366
- params.set("lineId", effectiveLineId);
71519
+ if (resolvedLineId) {
71520
+ params.set("lineId", resolvedLineId);
71367
71521
  }
71368
71522
  appendReturnUrl(params);
71369
71523
  onNavigate(`/workspace/${workspaceId}?${params.toString()}`);
@@ -71987,7 +72141,7 @@ var WorkspaceDetailView = ({
71987
72141
  month: selectedMonth,
71988
72142
  year: selectedYear,
71989
72143
  workspaceId,
71990
- lineId: effectiveLineId || workspace?.line_id,
72144
+ lineId: resolvedLineId,
71991
72145
  monitoringMode: workspace?.monitoring_mode,
71992
72146
  selectedShiftId: selectedShift,
71993
72147
  rangeStart,
@@ -72012,8 +72166,8 @@ var WorkspaceDetailView = ({
72012
72166
  params.set("rangeStart", range.startKey);
72013
72167
  params.set("rangeEnd", range.endKey);
72014
72168
  }
72015
- if (effectiveLineId) {
72016
- params.set("lineId", effectiveLineId);
72169
+ if (resolvedLineId) {
72170
+ params.set("lineId", resolvedLineId);
72017
72171
  }
72018
72172
  appendReturnUrl(params);
72019
72173
  onNavigate(`/workspace/${workspaceId}?${params.toString()}`);
@@ -72041,7 +72195,7 @@ var WorkspaceDetailView = ({
72041
72195
  workspaceId,
72042
72196
  workspaceName: formattedWorkspaceName,
72043
72197
  date,
72044
- lineId: effectiveLineId,
72198
+ lineId: resolvedLineId,
72045
72199
  shift,
72046
72200
  totalOutput: workspace?.total_actions,
72047
72201
  workspaceMetrics: detailedWorkspaceMetrics || void 0,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optifye/dashboard-core",
3
- "version": "6.11.33",
3
+ "version": "6.11.34",
4
4
  "description": "Reusable UI & logic for Optifye dashboard",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",