@optifye/dashboard-core 6.11.33 → 6.11.35

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,109 @@ 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 buildPrefetchedExplorerMetadata = (activeFilter, metadataCategoryId, categoryMetadata) => {
37422
+ if (!activeFilter || !metadataCategoryId || metadataCategoryId !== activeFilter || categoryMetadata.length === 0) {
37423
+ return void 0;
37424
+ }
37425
+ return {
37426
+ [activeFilter]: categoryMetadata
37427
+ };
37428
+ };
37429
+ var getSecondsBetweenTimestamps = (startTime, endTime) => {
37430
+ const startDate = parseTimestamp(startTime);
37431
+ const endDate = parseTimestamp(endTime);
37432
+ if (!startDate || !endDate) return null;
37433
+ return Math.max(0, (endDate.getTime() - startDate.getTime()) / 1e3);
37434
+ };
37435
+ var formatClipExplorerTimeLabel = ({
37436
+ categoryId,
37437
+ clipTimestamp,
37438
+ timezone,
37439
+ durationSeconds,
37440
+ idleStartTime,
37441
+ idleEndTime
37442
+ }) => {
37443
+ if (IDLE_RANGE_CATEGORY_IDS.has(categoryId)) {
37444
+ const idleDurationSeconds = getSecondsBetweenTimestamps(idleStartTime, idleEndTime);
37445
+ const idleEndTimestamp = idleEndTime || clipTimestamp;
37446
+ if (idleDurationSeconds !== null && idleDurationSeconds >= 60 && idleStartTime && idleEndTime) {
37447
+ return formatTimestampRange(idleStartTime, idleEndTime, timezone);
37448
+ }
37449
+ if (idleDurationSeconds === null && typeof durationSeconds === "number" && Number.isFinite(durationSeconds) && durationSeconds >= 60) {
37450
+ const endDate = parseTimestamp(idleEndTimestamp);
37451
+ if (endDate) {
37452
+ const startDate = new Date(endDate.getTime() - durationSeconds * 1e3);
37453
+ return formatTimestampRange(startDate.toISOString(), idleEndTimestamp, timezone);
37454
+ }
37455
+ }
37456
+ return formatClipExplorerSingleTime(idleEndTimestamp, timezone);
37457
+ }
37458
+ const singleTime = formatClipExplorerSingleTime(clipTimestamp, timezone);
37459
+ if (CYCLE_RANGE_CATEGORY_IDS.has(categoryId) && typeof durationSeconds === "number" && Number.isFinite(durationSeconds) && durationSeconds > 60) {
37460
+ const endDate = parseTimestamp(clipTimestamp);
37461
+ if (endDate) {
37462
+ const startDate = new Date(endDate.getTime() - durationSeconds * 1e3);
37463
+ return formatTimestampRange(startDate.toISOString(), clipTimestamp, timezone);
37464
+ }
37465
+ }
37466
+ return singleTime;
37467
+ };
37468
+ var formatIdleTimeRange = (startTime, endTime, timezone) => formatTimestampRange(startTime, endTime, timezone);
37341
37469
  var formatTime2 = (seconds) => {
37342
37470
  if (!seconds || isNaN(seconds)) return "0:00";
37343
37471
  const h = Math.floor(seconds / 3600);
@@ -41304,15 +41432,16 @@ var FileManagerFilters = ({
41304
41432
  if ((displayCount > 0 || shouldShowEmptyIdleTime) && shouldShowCategory(category.id)) {
41305
41433
  const colorClasses = getColorClasses(category.color);
41306
41434
  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
41435
  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)` : ""}`;
41436
+ const baseTimeLabel = formatClipExplorerTimeLabel({
41437
+ categoryId: category.id,
41438
+ clipTimestamp: clip.clip_timestamp,
41439
+ timezone,
41440
+ durationSeconds: clip.duration,
41441
+ idleStartTime: clip.idle_start_time,
41442
+ idleEndTime: clip.idle_end_time
41443
+ });
41444
+ const displayLabel = `${baseTimeLabel}${clip.duration && category.id !== "idle_time" && category.id !== "low_value" ? ` - (${clip.duration.toFixed(1)}s)` : ""}`;
41316
41445
  return {
41317
41446
  id: clip.id,
41318
41447
  label: displayLabel,
@@ -41363,16 +41492,15 @@ var FileManagerFilters = ({
41363
41492
  percentileType: "fast-cycles",
41364
41493
  isPercentile: true,
41365
41494
  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
41495
  const cycleTime = extractCycleTimeSeconds(clip);
41373
41496
  return {
41374
41497
  id: clip.id,
41375
- label: `${timeString}${clip.cycle_time_seconds ? ` - (${clip.cycle_time_seconds.toFixed(1)}s)` : ""}`,
41498
+ label: `${formatClipExplorerTimeLabel({
41499
+ categoryId: "fast-cycles",
41500
+ clipTimestamp: clip.creation_timestamp || clip.timestamp || "",
41501
+ timezone,
41502
+ durationSeconds: cycleTime
41503
+ })}${clip.cycle_time_seconds ? ` - (${clip.cycle_time_seconds.toFixed(1)}s)` : ""}`,
41376
41504
  type: "video",
41377
41505
  icon: getSeverityIcon(clip.severity, "fast-cycles", cycleTime, resolvedTargetCycleTime),
41378
41506
  timestamp: clip.creation_timestamp,
@@ -41395,16 +41523,15 @@ var FileManagerFilters = ({
41395
41523
  percentileType: "slow-cycles",
41396
41524
  isPercentile: true,
41397
41525
  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
41526
  const cycleTime = extractCycleTimeSeconds(clip);
41405
41527
  return {
41406
41528
  id: clip.id,
41407
- label: `${timeString}${clip.cycle_time_seconds ? ` - (${clip.cycle_time_seconds.toFixed(1)}s)` : ""}`,
41529
+ label: `${formatClipExplorerTimeLabel({
41530
+ categoryId: "slow-cycles",
41531
+ clipTimestamp: clip.creation_timestamp || clip.timestamp || "",
41532
+ timezone,
41533
+ durationSeconds: cycleTime
41534
+ })}${clip.cycle_time_seconds ? ` - (${clip.cycle_time_seconds.toFixed(1)}s)` : ""}`,
41408
41535
  type: "video",
41409
41536
  icon: getSeverityIcon(clip.severity, "slow-cycles", cycleTime, resolvedTargetCycleTime),
41410
41537
  timestamp: clip.creation_timestamp,
@@ -42496,6 +42623,7 @@ var BottlenecksContent = ({
42496
42623
  const [error, setError] = useState(null);
42497
42624
  const [clipClassifications, setClipClassifications] = useState({});
42498
42625
  const [categoryMetadata, setCategoryMetadata] = useState([]);
42626
+ const [categoryMetadataCategoryId, setCategoryMetadataCategoryId] = useState(null);
42499
42627
  const [currentMetadataIndex, setCurrentMetadataIndex] = useState(0);
42500
42628
  const [metadataCache, setMetadataCache] = useState({});
42501
42629
  const invalidateMetadataCache = useCallback((categories) => {
@@ -42967,6 +43095,15 @@ var BottlenecksContent = ({
42967
43095
  const getMetadataCacheKey = useCallback((categoryId) => {
42968
43096
  return `${categoryId}-${effectiveDateString}-${effectiveShiftId}-${snapshotDateTime ?? "nosnap"}-${snapshotClipId ?? "nosnap"}`;
42969
43097
  }, [effectiveDateString, effectiveShiftId, snapshotDateTime, snapshotClipId]);
43098
+ const setVisibleCategoryMetadata = useCallback((categoryId, clips) => {
43099
+ if (activeFilterRef.current !== categoryId) {
43100
+ return false;
43101
+ }
43102
+ categoryMetadataRef.current = clips;
43103
+ setCategoryMetadata(clips);
43104
+ setCategoryMetadataCategoryId(clips.length > 0 ? categoryId : null);
43105
+ return true;
43106
+ }, []);
42970
43107
  const applyMetadataSnapshot = useCallback((categoryId, clips, total) => {
42971
43108
  if (!clips || clips.length === 0) {
42972
43109
  return;
@@ -42976,13 +43113,12 @@ var BottlenecksContent = ({
42976
43113
  ...prev,
42977
43114
  [cacheKey]: clips
42978
43115
  }));
42979
- categoryMetadataRef.current = clips;
42980
- setCategoryMetadata(clips);
43116
+ setVisibleCategoryMetadata(categoryId, clips);
42981
43117
  if (!isPercentileCategory(categoryId) && typeof total === "number") {
42982
43118
  currentTotalRef.current = total;
42983
43119
  setCurrentTotal(total);
42984
43120
  }
42985
- }, [getMetadataCacheKey, isPercentileCategory]);
43121
+ }, [getMetadataCacheKey, isPercentileCategory, setVisibleCategoryMetadata]);
42986
43122
  const getClipTypesForPercentileCategory = useCallback((categoryId) => {
42987
43123
  switch (categoryId) {
42988
43124
  case "fast-cycles":
@@ -43007,6 +43143,7 @@ var BottlenecksContent = ({
43007
43143
  return;
43008
43144
  }
43009
43145
  setCategoryMetadata([]);
43146
+ setCategoryMetadataCategoryId(null);
43010
43147
  categoryMetadataRef.current = [];
43011
43148
  updateActiveFilter(fallbackFilter);
43012
43149
  }, [isFastSlowClipFiltersEnabled, activeFilter, dynamicCounts, clipTypes, updateActiveFilter]);
@@ -43053,6 +43190,7 @@ var BottlenecksContent = ({
43053
43190
  }
43054
43191
  if (!isFastSlowClipFiltersEnabled && (categoryId === "fast-cycles" || categoryId === "slow-cycles")) {
43055
43192
  setCategoryMetadata([]);
43193
+ setCategoryMetadataCategoryId(null);
43056
43194
  categoryMetadataRef.current = [];
43057
43195
  return;
43058
43196
  }
@@ -43066,8 +43204,7 @@ var BottlenecksContent = ({
43066
43204
  try {
43067
43205
  if (cachedMetadata) {
43068
43206
  console.log(`[BottlenecksContent] Using cached metadata for ${categoryId}`);
43069
- setCategoryMetadata(cachedMetadata);
43070
- categoryMetadataRef.current = cachedMetadata;
43207
+ setVisibleCategoryMetadata(categoryId, cachedMetadata);
43071
43208
  if (autoLoadFirstVideo && cachedMetadata.length > 0 && s3ClipsService) {
43072
43209
  const firstClipMeta = cachedMetadata[0];
43073
43210
  try {
@@ -43181,8 +43318,7 @@ var BottlenecksContent = ({
43181
43318
  ...prev,
43182
43319
  [cacheKey]: metadataClips
43183
43320
  }));
43184
- setCategoryMetadata(metadataClips);
43185
- categoryMetadataRef.current = metadataClips;
43321
+ setVisibleCategoryMetadata(categoryId, metadataClips);
43186
43322
  console.log(`[BottlenecksContent] Loaded metadata for ${categoryId}: ${metadataClips.length} clips`);
43187
43323
  if (autoLoadFirstVideo && metadataClips.length > 0 && s3ClipsService) {
43188
43324
  const firstClipMeta = metadataClips[0];
@@ -43201,15 +43337,18 @@ var BottlenecksContent = ({
43201
43337
  }
43202
43338
  }
43203
43339
  } else {
43204
- setCategoryMetadata([]);
43205
- categoryMetadataRef.current = [];
43340
+ if (activeFilterRef.current === categoryId) {
43341
+ setCategoryMetadata([]);
43342
+ setCategoryMetadataCategoryId(null);
43343
+ categoryMetadataRef.current = [];
43344
+ }
43206
43345
  }
43207
43346
  } catch (error2) {
43208
43347
  console.error(`[BottlenecksContent] Error loading category metadata:`, error2);
43209
43348
  } finally {
43210
43349
  setIsCategoryLoading(false);
43211
43350
  }
43212
- }, [workspaceId, effectiveDateString, effectiveShiftId, getMetadataCacheKey, isPercentileCategory, isFastSlowClipFiltersEnabled, metadataCache, s3ClipsService, clearLoadingState, isEffectiveShiftReady, snapshotDateTime, snapshotClipId, supabase]);
43351
+ }, [workspaceId, effectiveDateString, effectiveShiftId, getMetadataCacheKey, isPercentileCategory, isFastSlowClipFiltersEnabled, metadataCache, s3ClipsService, clearLoadingState, isEffectiveShiftReady, snapshotDateTime, snapshotClipId, supabase, setVisibleCategoryMetadata]);
43213
43352
  useEffect(() => {
43214
43353
  if (previousFilterRef.current !== activeFilter) {
43215
43354
  console.log(`Filter changed from ${previousFilterRef.current} to ${activeFilter} - resetting to first video`);
@@ -43219,6 +43358,7 @@ var BottlenecksContent = ({
43219
43358
  setIsNavigating(false);
43220
43359
  loadingCategoryRef.current = null;
43221
43360
  setCategoryMetadata([]);
43361
+ setCategoryMetadataCategoryId(null);
43222
43362
  setCurrentMetadataIndex(0);
43223
43363
  categoryMetadataRef.current = [];
43224
43364
  currentMetadataIndexRef.current = 0;
@@ -43777,14 +43917,11 @@ var BottlenecksContent = ({
43777
43917
  }
43778
43918
  return currentPosition;
43779
43919
  }, [activeFilter, categoryMetadata.length, currentMetadataIndex, currentPosition, isPercentileCategory]);
43780
- const prefetchedExplorerMetadata = useMemo(() => {
43781
- if (!activeFilter || categoryMetadata.length === 0) {
43782
- return void 0;
43783
- }
43784
- return {
43785
- [activeFilter]: categoryMetadata
43786
- };
43787
- }, [activeFilter, categoryMetadata]);
43920
+ const prefetchedExplorerMetadata = useMemo(() => buildPrefetchedExplorerMetadata(
43921
+ activeFilter,
43922
+ categoryMetadataCategoryId,
43923
+ categoryMetadata
43924
+ ), [activeFilter, categoryMetadata, categoryMetadataCategoryId]);
43788
43925
  const classificationClipIds = useMemo(() => {
43789
43926
  if (!idleTimeVlmEnabled) {
43790
43927
  return [];
@@ -46878,6 +47015,41 @@ var IdleTimeReasonChartComponent = ({
46878
47015
  var IdleTimeReasonChart = React143__default.memo(IdleTimeReasonChartComponent);
46879
47016
  IdleTimeReasonChart.displayName = "IdleTimeReasonChart";
46880
47017
  var IdleTimeReasonChart_default = IdleTimeReasonChart;
47018
+
47019
+ // src/lib/utils/cycleTime.ts
47020
+ var toFiniteNumber = (value) => {
47021
+ if (typeof value === "number" && Number.isFinite(value)) return value;
47022
+ if (typeof value === "string" && value.trim() !== "") {
47023
+ const parsed = Number(value);
47024
+ return Number.isFinite(parsed) ? parsed : null;
47025
+ }
47026
+ return null;
47027
+ };
47028
+ var getCycleRatio = (workspace) => {
47029
+ const idealCycleTime = toFiniteNumber(workspace.ideal_cycle_time);
47030
+ const avgCycleTime = toFiniteNumber(workspace.avg_cycle_time);
47031
+ if (idealCycleTime === null || avgCycleTime === null || idealCycleTime <= 0 || avgCycleTime <= 0) {
47032
+ return null;
47033
+ }
47034
+ return idealCycleTime / avgCycleTime;
47035
+ };
47036
+ var formatCycleTimeValue = (value) => {
47037
+ const numericValue = toFiniteNumber(value);
47038
+ if (numericValue === null || numericValue <= 0) return "--";
47039
+ return `${numericValue.toFixed(1)}s`;
47040
+ };
47041
+ var CycleTimeComparison = memo$1(({
47042
+ workspace
47043
+ }) => {
47044
+ const averageValue = formatCycleTimeValue(workspace.avg_cycle_time);
47045
+ const standardValue = formatCycleTimeValue(workspace.ideal_cycle_time);
47046
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 tabular-nums", children: [
47047
+ /* @__PURE__ */ jsx("span", { className: "font-semibold text-gray-900", children: averageValue }),
47048
+ /* @__PURE__ */ jsx("span", { className: "text-gray-400 font-normal", children: "/" }),
47049
+ /* @__PURE__ */ jsx("span", { className: "font-medium text-gray-500", children: standardValue })
47050
+ ] });
47051
+ }, (prevProps, nextProps) => prevProps.workspace.avg_cycle_time === nextProps.workspace.avg_cycle_time && prevProps.workspace.ideal_cycle_time === nextProps.workspace.ideal_cycle_time);
47052
+ CycleTimeComparison.displayName = "CycleTimeComparison";
46881
47053
  var DEFAULT_PERFORMANCE_DATA = {
46882
47054
  avg_efficiency: 0,
46883
47055
  underperforming_workspaces: 0,
@@ -46976,6 +47148,7 @@ var LineMonthlyHistory = ({
46976
47148
  timezone,
46977
47149
  legend,
46978
47150
  monitoringMode,
47151
+ lineAssembly = false,
46979
47152
  underperformingWorkspaces = {},
46980
47153
  lineId,
46981
47154
  selectedShiftId = 0,
@@ -47265,7 +47438,7 @@ var LineMonthlyHistory = ({
47265
47438
  "div",
47266
47439
  {
47267
47440
  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)` : ""}`
47441
+ 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
47442
  },
47270
47443
  `${performance2.date}-${index}`
47271
47444
  )) });
@@ -47511,13 +47684,20 @@ var LineMonthlyHistory = ({
47511
47684
  onClick: () => handleWorkspaceClick(workspace),
47512
47685
  className: "block hover:bg-gray-50 transition-colors rounded-lg w-full text-left group",
47513
47686
  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
- "(",
47687
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
47688
+ /* @__PURE__ */ jsx("div", { className: "font-medium text-gray-900 text-[10px] sm:text-xs truncate", children: getWorkspaceDisplayName(workspace.workspace_name, lineId) }),
47689
+ lineAssembly && workspace.metric_mode === "cycle_time" ? /* @__PURE__ */ jsx("div", { className: "mt-0.5 text-[9px] sm:text-[11px]", children: /* @__PURE__ */ jsx(
47690
+ CycleTimeComparison,
47691
+ {
47692
+ workspace: {
47693
+ avg_cycle_time: workspace.avg_cycle_time ?? 0,
47694
+ ideal_cycle_time: workspace.ideal_cycle_time ?? void 0
47695
+ }
47696
+ }
47697
+ ) }) : workspace.avg_efficiency !== void 0 ? /* @__PURE__ */ jsxs("div", { className: "mt-0.5 text-[8px] sm:text-[10px] text-gray-500", children: [
47518
47698
  (workspace.avg_efficiency || 0).toFixed(1),
47519
- "%)"
47520
- ] })
47699
+ "%"
47700
+ ] }) : null
47521
47701
  ] }),
47522
47702
  /* @__PURE__ */ jsx("div", { className: "flex items-center gap-0.5 sm:gap-1 lg:gap-1.5", children: renderPerformanceSquares(workspace.last_5_days) })
47523
47703
  ] })
@@ -49887,7 +50067,7 @@ var WorkspaceMonthlyHistory = ({
49887
50067
  Math.round(shiftData.efficiency || 0),
49888
50068
  "%"
49889
50069
  ] }),
49890
- /* @__PURE__ */ jsxs("div", { children: [
50070
+ !isAssemblyWorkspace && /* @__PURE__ */ jsxs("div", { children: [
49891
50071
  "Output: ",
49892
50072
  shiftData.output || 0,
49893
50073
  " units"
@@ -62030,41 +62210,6 @@ function useEfficiencyLegend(companyId) {
62030
62210
  };
62031
62211
  }
62032
62212
 
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
62213
  // src/lib/utils/kpiPoorestPerformers.ts
62069
62214
  var getWorstAssemblyCycleTimeWorkspaces = (workspaces, limit = 5) => {
62070
62215
  return workspaces.map((workspace, index) => ({
@@ -63252,27 +63397,33 @@ var KPIDetailView = ({
63252
63397
  error: idleTimeError
63253
63398
  }), [idleTimeRawData, idleTimeChartData, idleTimeLoading, idleTimeError]);
63254
63399
  useEffect(() => {
63255
- if (activeTab === "monthly_history" && lineId) {
63400
+ if (activeTab === "monthly_history" && lineId && lineDetails) {
63256
63401
  if (!supabase || !dashboardConfig || !dashboardConfig.supabaseUrl || !dashboardConfig.supabaseKey) {
63257
63402
  console.error("Supabase client or required config not available in KPIsPage for monthly data");
63258
63403
  return;
63259
63404
  }
63260
63405
  setMonthlyDataLoading(true);
63406
+ const monthlyShiftIds = shiftConfig?.shifts?.map((s) => s.shiftId);
63407
+ const monthlyHistoryAssemblyMode = lineDetails.assembly === true && !isUptimeMode;
63408
+ const underperformingPromise = monthlyHistoryAssemblyMode ? dashboardService.getAssemblyMonthlyPoorestPerformers(lineId, currentMonth, currentYear, {
63409
+ startDate: isFullRange ? void 0 : range.startKey,
63410
+ endDate: isFullRange ? void 0 : range.endKey,
63411
+ shiftIds: monthlyShiftIds
63412
+ }) : dashboardService.getUnderperformingWorkspaces(
63413
+ lineId,
63414
+ currentMonth,
63415
+ currentYear,
63416
+ monthlyShiftIds,
63417
+ isFullRange ? void 0 : range.startKey,
63418
+ isFullRange ? void 0 : range.endKey
63419
+ );
63261
63420
  Promise.all([
63262
63421
  dashboardService.getLineMonthlyData(lineId, currentMonth, currentYear, {
63263
63422
  startDate: isFullRange ? void 0 : range.startKey,
63264
63423
  endDate: isFullRange ? void 0 : range.endKey,
63265
- shiftIds: shiftConfig?.shifts?.map((s) => s.shiftId)
63424
+ shiftIds: monthlyShiftIds
63266
63425
  }),
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
- )
63426
+ underperformingPromise
63276
63427
  ]).then(([monthlyMetrics, underperformingData]) => {
63277
63428
  console.log("Fetched monthly metrics data:", monthlyMetrics);
63278
63429
  const dayDataMap = /* @__PURE__ */ new Map();
@@ -63336,11 +63487,17 @@ var KPIDetailView = ({
63336
63487
  const mapWorkspaces = (workspaces2) => (workspaces2 || []).map((ws) => ({
63337
63488
  workspace_name: ws.workspace_name || "Unknown Workspace",
63338
63489
  workspace_uuid: ws.workspace_uuid || ws.workspace_name || `unknown-${Math.random()}`,
63339
- avg_efficiency: ws.avg_efficiency || 0,
63490
+ avg_efficiency: ws.avg_efficiency ?? 0,
63491
+ avg_cycle_time: ws.avg_cycle_time ?? null,
63492
+ ideal_cycle_time: ws.ideal_cycle_time ?? null,
63493
+ cycle_ratio: ws.cycle_ratio ?? null,
63494
+ metric_mode: ws.metric_mode ?? "efficiency",
63340
63495
  last_5_days: (ws.last_5_days || []).map((day) => ({
63341
63496
  date: day.date,
63342
63497
  efficiency: day.efficiency ?? 0,
63343
- performance_score: day.performance_score
63498
+ performance_score: day.performance_score,
63499
+ avg_cycle_time: day.avg_cycle_time ?? null,
63500
+ ideal_cycle_time: day.ideal_cycle_time ?? null
63344
63501
  }))
63345
63502
  }));
63346
63503
  const mappedData = {};
@@ -63365,7 +63522,7 @@ var KPIDetailView = ({
63365
63522
  setMonthlyDataLoading(false);
63366
63523
  });
63367
63524
  }
63368
- }, [activeTab, lineId, currentMonth, currentYear, supabase, dashboardConfig, shiftConfig, range.startKey, range.endKey, isFullRange, configuredTimezone, isUptimeMode, resolveShiftTimes]);
63525
+ }, [activeTab, lineId, lineDetails, currentMonth, currentYear, supabase, dashboardConfig, shiftConfig, range.startKey, range.endKey, isFullRange, configuredTimezone, isUptimeMode, resolveShiftTimes]);
63369
63526
  const analysisMonthlyData = useMemo(() => {
63370
63527
  return filterDataByDateKeyRange(monthlyData, range);
63371
63528
  }, [monthlyData, range]);
@@ -64271,6 +64428,7 @@ var KPIDetailView = ({
64271
64428
  timezone: configuredTimezone,
64272
64429
  legend: efficiencyLegend,
64273
64430
  monitoringMode: resolvedMonitoringMode,
64431
+ lineAssembly: resolvedLineInfo?.assembly === true,
64274
64432
  shiftConfig,
64275
64433
  selectedShiftId,
64276
64434
  onShiftChange: setSelectedShiftId,
@@ -70597,7 +70755,20 @@ var WorkspaceDetailView = ({
70597
70755
  } = useCompanyFastSlowClipFiltersEnabled();
70598
70756
  const isClipsEnabled = dashboardConfig?.clipsConfig?.enabled ?? true;
70599
70757
  dashboardConfig?.supervisorConfig?.enabled || false;
70600
- const effectiveLineId = lineId || selectedLineId;
70758
+ const routedLineId = lineId || selectedLineId;
70759
+ const latestCachedDetailedMetrics = useMemo(() => {
70760
+ if (!workspaceId) {
70761
+ return null;
70762
+ }
70763
+ return workspaceMetricsStore.getLatestDetailed(workspaceId);
70764
+ }, [workspaceId]);
70765
+ const latestCachedOverviewMetrics = useMemo(() => {
70766
+ if (!workspaceId) {
70767
+ return null;
70768
+ }
70769
+ return workspaceMetricsStore.getLatestOverview(workspaceId);
70770
+ }, [workspaceId]);
70771
+ const effectiveLineId = routedLineId || latestCachedDetailedMetrics?.line_id || latestCachedOverviewMetrics?.line_id;
70601
70772
  const { shiftConfig, isLoading: isShiftConfigLoading, isFromDatabase: isShiftConfigFromDatabase } = useDynamicShiftConfig(effectiveLineId);
70602
70773
  const currentShiftDetails = useMemo(() => {
70603
70774
  if (isShiftConfigLoading || !shiftConfig) return null;
@@ -70874,8 +71045,9 @@ var WorkspaceDetailView = ({
70874
71045
  }, [cachedOverviewMetrics, shiftConfig?.shifts]);
70875
71046
  const authoritativeCycleMetrics = isHistoricView ? historicMetrics : liveMetrics;
70876
71047
  const workspace = authoritativeCycleMetrics || cachedDetailedMetrics || overviewFallback;
71048
+ const resolvedLineId = effectiveLineId || workspace?.line_id || cachedDetailedMetrics?.line_id || cachedOverviewMetrics?.line_id || overviewFallback?.line_id;
70877
71049
  const { timezone: cycleTimeTimezone } = useTimezone({
70878
- lineId: effectiveLineId || workspace?.line_id || void 0,
71050
+ lineId: resolvedLineId || void 0,
70879
71051
  workspaceId: workspaceId || void 0
70880
71052
  });
70881
71053
  const effectiveCycleTimeTimezone = cycleTimeTimezone || timezone;
@@ -70920,7 +71092,7 @@ var WorkspaceDetailView = ({
70920
71092
  const error = isHistoricView ? historicError : liveError;
70921
71093
  const monitoringMode = workspace?.monitoring_mode ?? "output";
70922
71094
  const isUptimeMode = monitoringMode === "uptime";
70923
- const idleTimeVlmEnabled = isIdleTimeVlmEnabled(effectiveLineId || workspace?.line_id);
71095
+ const idleTimeVlmEnabled = isIdleTimeVlmEnabled(resolvedLineId);
70924
71096
  useEffect(() => {
70925
71097
  if (!isClipsEnabled || !dashboardConfig?.s3Config || !workspaceId) {
70926
71098
  return;
@@ -71155,7 +71327,7 @@ var WorkspaceDetailView = ({
71155
71327
  const analysisMonthlyData = useMemo(() => {
71156
71328
  return filterDataByDateKeyRange(monthlyData, range);
71157
71329
  }, [monthlyData, range]);
71158
- const formattedWorkspaceName = displayName || formatWorkspaceName3(workspace?.workspace_name || "", effectiveLineId);
71330
+ const formattedWorkspaceName = displayName || formatWorkspaceName3(workspace?.workspace_name || "", resolvedLineId);
71159
71331
  const workspaceCycleTimeEligibility = workspace ? {
71160
71332
  line_assembly_enabled: workspace.line_assembly_enabled,
71161
71333
  action_family: workspace.action_family,
@@ -71332,8 +71504,8 @@ var WorkspaceDetailView = ({
71332
71504
  params.set("rangeStart", range.startKey);
71333
71505
  params.set("rangeEnd", range.endKey);
71334
71506
  }
71335
- if (effectiveLineId) {
71336
- params.set("lineId", effectiveLineId);
71507
+ if (resolvedLineId) {
71508
+ params.set("lineId", resolvedLineId);
71337
71509
  }
71338
71510
  appendReturnUrl(params);
71339
71511
  onNavigate(`/workspace/${workspaceId}?${params.toString()}`);
@@ -71362,8 +71534,8 @@ var WorkspaceDetailView = ({
71362
71534
  params.set("rangeStart", range.startKey);
71363
71535
  params.set("rangeEnd", range.endKey);
71364
71536
  }
71365
- if (effectiveLineId) {
71366
- params.set("lineId", effectiveLineId);
71537
+ if (resolvedLineId) {
71538
+ params.set("lineId", resolvedLineId);
71367
71539
  }
71368
71540
  appendReturnUrl(params);
71369
71541
  onNavigate(`/workspace/${workspaceId}?${params.toString()}`);
@@ -71987,7 +72159,7 @@ var WorkspaceDetailView = ({
71987
72159
  month: selectedMonth,
71988
72160
  year: selectedYear,
71989
72161
  workspaceId,
71990
- lineId: effectiveLineId || workspace?.line_id,
72162
+ lineId: resolvedLineId,
71991
72163
  monitoringMode: workspace?.monitoring_mode,
71992
72164
  selectedShiftId: selectedShift,
71993
72165
  rangeStart,
@@ -72012,8 +72184,8 @@ var WorkspaceDetailView = ({
72012
72184
  params.set("rangeStart", range.startKey);
72013
72185
  params.set("rangeEnd", range.endKey);
72014
72186
  }
72015
- if (effectiveLineId) {
72016
- params.set("lineId", effectiveLineId);
72187
+ if (resolvedLineId) {
72188
+ params.set("lineId", resolvedLineId);
72017
72189
  }
72018
72190
  appendReturnUrl(params);
72019
72191
  onNavigate(`/workspace/${workspaceId}?${params.toString()}`);
@@ -72041,7 +72213,7 @@ var WorkspaceDetailView = ({
72041
72213
  workspaceId,
72042
72214
  workspaceName: formattedWorkspaceName,
72043
72215
  date,
72044
- lineId: effectiveLineId,
72216
+ lineId: resolvedLineId,
72045
72217
  shift,
72046
72218
  totalOutput: workspace?.total_actions,
72047
72219
  workspaceMetrics: detailedWorkspaceMetrics || void 0,