@optifye/dashboard-core 6.11.44 → 6.11.46

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.d.mts CHANGED
@@ -66,6 +66,7 @@ interface WorkspaceMetrics {
66
66
  workspace_name: string;
67
67
  action_count: number;
68
68
  pph: number;
69
+ pph_threshold?: number;
69
70
  performance_score: 0 | 1 | 2;
70
71
  avg_cycle_time: number;
71
72
  ideal_cycle_time?: number;
@@ -5556,6 +5557,11 @@ declare const workspaceService: {
5556
5557
  lineIds?: string[];
5557
5558
  force?: boolean;
5558
5559
  }): Promise<Record<string, WorkspaceVideoStream>>;
5560
+ primeWorkspaceVideoStreamsCache(params: {
5561
+ streams: Record<string, WorkspaceVideoStream>;
5562
+ workspaceIds?: string[];
5563
+ lineIds?: string[];
5564
+ }): void;
5559
5565
  getWorkspaceCameraIps(params: {
5560
5566
  workspaceIds?: string[];
5561
5567
  lineIds?: string[];
package/dist/index.d.ts CHANGED
@@ -66,6 +66,7 @@ interface WorkspaceMetrics {
66
66
  workspace_name: string;
67
67
  action_count: number;
68
68
  pph: number;
69
+ pph_threshold?: number;
69
70
  performance_score: 0 | 1 | 2;
70
71
  avg_cycle_time: number;
71
72
  ideal_cycle_time?: number;
@@ -5556,6 +5557,11 @@ declare const workspaceService: {
5556
5557
  lineIds?: string[];
5557
5558
  force?: boolean;
5558
5559
  }): Promise<Record<string, WorkspaceVideoStream>>;
5560
+ primeWorkspaceVideoStreamsCache(params: {
5561
+ streams: Record<string, WorkspaceVideoStream>;
5562
+ workspaceIds?: string[];
5563
+ lineIds?: string[];
5564
+ }): void;
5559
5565
  getWorkspaceCameraIps(params: {
5560
5566
  workspaceIds?: string[];
5561
5567
  lineIds?: string[];
package/dist/index.js CHANGED
@@ -5117,6 +5117,27 @@ var workspaceService = {
5117
5117
  this._workspaceVideoStreamsInFlight.set(cacheKey, fetchPromise);
5118
5118
  return fetchPromise;
5119
5119
  },
5120
+ primeWorkspaceVideoStreamsCache(params) {
5121
+ const streams = params.streams || {};
5122
+ const workspaceIds = (params.workspaceIds || []).filter(Boolean);
5123
+ const lineIds = (params.lineIds || []).filter(Boolean);
5124
+ if (!Object.keys(streams).length || !workspaceIds.length && !lineIds.length) {
5125
+ return;
5126
+ }
5127
+ const timestamp = Date.now();
5128
+ const entry = {
5129
+ streams,
5130
+ timestamp
5131
+ };
5132
+ if (workspaceIds.length) {
5133
+ const workspaceKey = workspaceIds.slice().sort().join(",");
5134
+ this._workspaceVideoStreamsCache.set(`workspaces:${workspaceKey}`, entry);
5135
+ }
5136
+ if (lineIds.length) {
5137
+ const lineKey = lineIds.slice().sort().join(",");
5138
+ this._workspaceVideoStreamsCache.set(`lines:${lineKey}`, entry);
5139
+ }
5140
+ },
5120
5141
  async getWorkspaceCameraIps(params) {
5121
5142
  const workspaceIds = (params.workspaceIds || []).filter(Boolean);
5122
5143
  const lineIds = (params.lineIds || []).filter(Boolean);
@@ -11988,8 +12009,8 @@ var useOperationalShiftKey = ({
11988
12009
  };
11989
12010
 
11990
12011
  // src/lib/stores/workspaceMetricsStore.ts
11991
- var OVERVIEW_TTL_MS = 3e4;
11992
- var DETAILED_TTL_MS = 3e4;
12012
+ var OVERVIEW_TTL_MS = 12e4;
12013
+ var DETAILED_TTL_MS = 12e4;
11993
12014
  var overviewByKey = /* @__PURE__ */ new Map();
11994
12015
  var detailedByKey = /* @__PURE__ */ new Map();
11995
12016
  var latestOverviewByWorkspace = /* @__PURE__ */ new Map();
@@ -13485,6 +13506,109 @@ function getEfficiencyTextColorClasses(efficiency, legend = DEFAULT_EFFICIENCY_L
13485
13506
  }
13486
13507
  }
13487
13508
 
13509
+ // src/lib/utils/monitorWorkspaceMetrics.ts
13510
+ var sortWorkspaceMetrics = (left, right) => {
13511
+ if (left.line_id !== right.line_id) {
13512
+ return left.line_id.localeCompare(right.line_id);
13513
+ }
13514
+ return left.workspace_name.localeCompare(right.workspace_name, void 0, { numeric: true });
13515
+ };
13516
+ var buildLineMetricsById = (lineMetrics) => (lineMetrics || []).reduce((acc, lineMetric) => {
13517
+ const lineId = lineMetric?.line_id;
13518
+ if (!lineId) {
13519
+ return acc;
13520
+ }
13521
+ acc[lineId] = { total_workspaces: lineMetric?.total_workspaces };
13522
+ return acc;
13523
+ }, {});
13524
+ var transformMonitorWorkspaceMetrics = ({
13525
+ rows,
13526
+ companyId,
13527
+ workspaceConfig,
13528
+ appTimezone,
13529
+ lineMetrics,
13530
+ resolveShiftConfig,
13531
+ shouldOverrideShiftType,
13532
+ fallbackShiftConfig = null
13533
+ }) => {
13534
+ const effectiveWorkspaceConfig = workspaceConfig || DEFAULT_WORKSPACE_CONFIG;
13535
+ const detailTimezone = appTimezone || "Asia/Kolkata";
13536
+ const lineMetricsById = buildLineMetricsById(lineMetrics);
13537
+ return (rows || []).map((item) => {
13538
+ const lineId = String(item?.line_id || "");
13539
+ const lineShiftConfig = resolveShiftConfig?.(lineId) || fallbackShiftConfig || void 0;
13540
+ const detailedMetrics = toWorkspaceDetailedMetrics({
13541
+ data: item,
13542
+ companyId,
13543
+ workspaceConfig: effectiveWorkspaceConfig,
13544
+ shiftConfig: lineShiftConfig,
13545
+ appTimezone: detailTimezone,
13546
+ lineMetricsById,
13547
+ overrideShiftType: shouldOverrideShiftType?.(lineId) ?? false
13548
+ });
13549
+ if (detailedMetrics) {
13550
+ workspaceMetricsStore.setDetailed(detailedMetrics);
13551
+ }
13552
+ const idleTimeValue = typeof item.idle_time === "number" ? item.idle_time : Number(item.idle_time);
13553
+ const idleTimeSeconds = Number.isFinite(idleTimeValue) ? idleTimeValue : void 0;
13554
+ const pphThresholdValue = typeof item.pph_threshold === "number" ? item.pph_threshold : Number(item.pph_threshold);
13555
+ const actionFamily = normalizeActionFamily({
13556
+ actionFamily: item.action_family,
13557
+ actionType: item.action_type,
13558
+ actionName: item.action_name
13559
+ });
13560
+ const actionType = actionFamily === "assembly" || actionFamily === "output" ? actionFamily : null;
13561
+ const metric = {
13562
+ company_id: item.company_id || companyId,
13563
+ line_id: lineId,
13564
+ shift_id: item.shift_id,
13565
+ date: item.date,
13566
+ workspace_uuid: item.workspace_id,
13567
+ workspace_name: item.workspace_name,
13568
+ displayName: item.workspace_display_name || item.display_name || void 0,
13569
+ action_count: item.total_output || 0,
13570
+ pph: item.avg_pph || 0,
13571
+ pph_threshold: Number.isFinite(pphThresholdValue) ? pphThresholdValue : void 0,
13572
+ performance_score: item.performance_score || 0,
13573
+ avg_cycle_time: item.avg_cycle_time || 0,
13574
+ ideal_cycle_time: item.ideal_cycle_time || void 0,
13575
+ trend: item.trend_score === 1 ? 2 : 0,
13576
+ predicted_output: item.ideal_output || 0,
13577
+ efficiency: item.efficiency || 0,
13578
+ action_threshold: item.total_day_output || 0,
13579
+ monitoring_mode: item.monitoring_mode ?? void 0,
13580
+ idle_time: idleTimeSeconds,
13581
+ idle_time_hourly: item.idle_time_hourly ?? null,
13582
+ shift_start: item.shift_start ?? void 0,
13583
+ shift_end: item.shift_end ?? void 0,
13584
+ assembly_enabled: item.assembly_enabled ?? false,
13585
+ video_grid_metric_mode: normalizeVideoGridMetricMode(
13586
+ item.video_grid_metric_mode,
13587
+ item.assembly_enabled ?? false
13588
+ ),
13589
+ action_type: actionType,
13590
+ action_family: actionFamily,
13591
+ action_display_name: getActionDisplayName({
13592
+ displayName: item.action_display_name,
13593
+ actionFamily: item.action_family,
13594
+ actionType: item.action_type,
13595
+ actionName: item.action_name
13596
+ }),
13597
+ recent_flow_percent: item.recent_flow_percent ?? null,
13598
+ recent_flow_window_minutes: item.recent_flow_window_minutes ?? null,
13599
+ recent_flow_effective_end_at: item.recent_flow_effective_end_at ?? null,
13600
+ recent_flow_computed_at: item.recent_flow_computed_at ?? null,
13601
+ scheduled_break_active: item.scheduled_break_active ?? false,
13602
+ incoming_wip_current: item.incoming_wip_current ?? null,
13603
+ incoming_wip_effective_at: item.incoming_wip_effective_at ?? null,
13604
+ incoming_wip_buffer_name: item.incoming_wip_buffer_name ?? null,
13605
+ show_exclamation: item.show_exclamation ?? void 0
13606
+ };
13607
+ workspaceMetricsStore.setOverview(metric);
13608
+ return metric;
13609
+ }).sort(sortWorkspaceMetrics);
13610
+ };
13611
+
13488
13612
  // src/lib/hooks/useDashboardMetrics.ts
13489
13613
  var DEBUG_DASHBOARD_LOGS = process.env.NEXT_PUBLIC_DEBUG_DASHBOARD === "true";
13490
13614
  var REALTIME_REFRESH_DEBOUNCE_MS = 1500;
@@ -13802,89 +13926,16 @@ var useDashboardMetrics = ({
13802
13926
  }
13803
13927
  efficiencyLegend = parseEfficiencyLegend(backendData?.efficiency_legend) ?? DEFAULT_EFFICIENCY_LEGEND;
13804
13928
  }
13805
- const lineMetricsById = (allLineMetrics || []).reduce(
13806
- (acc, line) => {
13807
- const lineId2 = line?.line_id;
13808
- if (lineId2) {
13809
- acc[lineId2] = { total_workspaces: line?.total_workspaces };
13810
- }
13811
- return acc;
13812
- },
13813
- {}
13814
- );
13815
13929
  const detailTimezone = appTimezone || "Asia/Kolkata";
13816
- allWorkspaceMetrics.forEach((item) => {
13817
- const lineShiftConfig = isFactoryView ? multiLineShiftConfigMap.get(item.line_id) : shiftConfig;
13818
- const detailedMetrics = toWorkspaceDetailedMetrics({
13819
- data: item,
13820
- companyId: companyId || "",
13821
- workspaceConfig: effectiveWorkspaceConfig,
13822
- shiftConfig: lineShiftConfig || staticShiftConfig,
13823
- appTimezone: detailTimezone,
13824
- lineMetricsById,
13825
- overrideShiftType: Boolean(lineShiftConfig)
13826
- });
13827
- if (detailedMetrics) {
13828
- workspaceMetricsStore.setDetailed(detailedMetrics);
13829
- }
13830
- });
13831
- const transformedWorkspaceData = allWorkspaceMetrics.map((item) => {
13832
- const idleTimeValue = typeof item.idle_time === "number" ? item.idle_time : Number(item.idle_time);
13833
- const idleTimeSeconds = Number.isFinite(idleTimeValue) ? idleTimeValue : void 0;
13834
- const actionFamily = normalizeActionFamily({
13835
- actionFamily: item.action_family,
13836
- actionType: item.action_type,
13837
- actionName: item.action_name
13838
- });
13839
- const actionType = actionFamily === "assembly" || actionFamily === "output" ? actionFamily : null;
13840
- return {
13841
- company_id: item.company_id || companyId,
13842
- line_id: item.line_id,
13843
- shift_id: item.shift_id,
13844
- date: item.date,
13845
- workspace_uuid: item.workspace_id,
13846
- workspace_name: item.workspace_name,
13847
- displayName: item.workspace_display_name || item.display_name || void 0,
13848
- action_count: item.total_output || 0,
13849
- pph: item.avg_pph || 0,
13850
- performance_score: item.performance_score || 0,
13851
- avg_cycle_time: item.avg_cycle_time || 0,
13852
- trend: item.trend_score === 1 ? 2 : 0,
13853
- predicted_output: item.ideal_output || 0,
13854
- efficiency: item.efficiency || 0,
13855
- action_threshold: item.total_day_output || 0,
13856
- show_exclamation: item.show_exclamation ?? void 0,
13857
- monitoring_mode: item.monitoring_mode ?? void 0,
13858
- idle_time: idleTimeSeconds,
13859
- assembly_enabled: item.assembly_enabled ?? false,
13860
- video_grid_metric_mode: normalizeVideoGridMetricMode(
13861
- item.video_grid_metric_mode,
13862
- item.assembly_enabled ?? false
13863
- ),
13864
- action_type: actionType,
13865
- action_family: actionFamily,
13866
- action_display_name: getActionDisplayName({
13867
- displayName: item.action_display_name,
13868
- actionFamily: item.action_family,
13869
- actionType: item.action_type,
13870
- actionName: item.action_name
13871
- }),
13872
- recent_flow_percent: item.recent_flow_percent ?? null,
13873
- recent_flow_window_minutes: item.recent_flow_window_minutes ?? null,
13874
- recent_flow_effective_end_at: item.recent_flow_effective_end_at ?? null,
13875
- recent_flow_computed_at: item.recent_flow_computed_at ?? null,
13876
- incoming_wip_current: item.incoming_wip_current ?? null,
13877
- incoming_wip_effective_at: item.incoming_wip_effective_at ?? null,
13878
- incoming_wip_buffer_name: item.incoming_wip_buffer_name ?? null
13879
- };
13880
- }).sort((a, b) => {
13881
- if (a.line_id !== b.line_id) return a.line_id.localeCompare(b.line_id);
13882
- const wsNumA = parseInt(a.workspace_name?.replace(/[^0-9]/g, "") || "0");
13883
- const wsNumB = parseInt(b.workspace_name?.replace(/[^0-9]/g, "") || "0");
13884
- return wsNumA - wsNumB;
13885
- });
13886
- transformedWorkspaceData.forEach((metric) => {
13887
- workspaceMetricsStore.setOverview(metric);
13930
+ const transformedWorkspaceData = transformMonitorWorkspaceMetrics({
13931
+ rows: allWorkspaceMetrics,
13932
+ companyId: companyId || "",
13933
+ workspaceConfig: effectiveWorkspaceConfig,
13934
+ appTimezone: detailTimezone,
13935
+ lineMetrics: allLineMetrics,
13936
+ resolveShiftConfig: (metricLineId) => isFactoryView ? multiLineShiftConfigMap.get(metricLineId) || staticShiftConfig : shiftConfig || staticShiftConfig,
13937
+ shouldOverrideShiftType: (metricLineId) => isFactoryView ? Boolean(multiLineShiftConfigMap.get(metricLineId)) : Boolean(shiftConfig),
13938
+ fallbackShiftConfig: staticShiftConfig
13888
13939
  });
13889
13940
  const newMetricsState = {
13890
13941
  workspaceMetrics: transformedWorkspaceData,
@@ -37604,6 +37655,7 @@ var buildPrefetchedExplorerMetadata = (activeFilter, metadataCategoryId, categor
37604
37655
  [activeFilter]: categoryMetadata
37605
37656
  };
37606
37657
  };
37658
+ var shouldDeferClipPlayerRender = (cropLoading, workspaceCrop) => cropLoading && workspaceCrop === null;
37607
37659
  var getSecondsBetweenTimestamps = (startTime, endTime) => {
37608
37660
  const startDate = parseTimestamp(startTime);
37609
37661
  const endDate = parseTimestamp(endTime);
@@ -42735,7 +42787,7 @@ var BottlenecksContent = ({
42735
42787
  const isEffectiveShiftReady = Boolean(effectiveShift && effectiveDate);
42736
42788
  const effectiveDateString = effectiveDate || "";
42737
42789
  const effectiveShiftId = effectiveShift ?? "";
42738
- const { crop: workspaceCrop} = useWorkspaceCrop(workspaceId);
42790
+ const { crop: workspaceCrop, isLoading: cropLoading } = useWorkspaceCrop(workspaceId);
42739
42791
  const { metrics: fetchedWorkspaceMetrics } = useWorkspaceDetailedMetrics(
42740
42792
  workspaceId,
42741
42793
  date,
@@ -42784,6 +42836,8 @@ var BottlenecksContent = ({
42784
42836
  const [pendingVideo, setPendingVideo] = React143.useState(null);
42785
42837
  const [isVideoBuffering, setIsVideoBuffering] = React143.useState(false);
42786
42838
  const [isInitialLoading, setIsInitialLoading] = React143.useState(false);
42839
+ const shouldDeferPlayerRenderForCrop = shouldDeferClipPlayerRender(cropLoading, workspaceCrop);
42840
+ const showBlockingVideoLoader = shouldDeferPlayerRenderForCrop || isTransitioning || isVideoBuffering && isInitialLoading;
42787
42841
  const [isShareLoading, setIsShareLoading] = React143.useState(false);
42788
42842
  const [isShareCopied, setIsShareCopied] = React143.useState(false);
42789
42843
  const shareCopiedTimeoutRef = React143.useRef(null);
@@ -44523,7 +44577,7 @@ var BottlenecksContent = ({
44523
44577
  opacity: isTransitioning ? 0 : 1,
44524
44578
  transition: "opacity 0.1s ease-in-out"
44525
44579
  },
44526
- children: /* @__PURE__ */ jsxRuntime.jsx(
44580
+ children: !shouldDeferPlayerRenderForCrop && /* @__PURE__ */ jsxRuntime.jsx(
44527
44581
  CroppedVideoPlayer,
44528
44582
  {
44529
44583
  ref: videoRef,
@@ -44554,8 +44608,8 @@ var BottlenecksContent = ({
44554
44608
  )
44555
44609
  }
44556
44610
  ),
44557
- (isTransitioning || isVideoBuffering && isInitialLoading) && !error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 z-30 flex items-center justify-center bg-black", children: /* @__PURE__ */ jsxRuntime.jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading video..." }) }),
44558
- !isTransitioning && isVideoBuffering && !isInitialLoading && !error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 z-30 flex items-center justify-center bg-black/60", children: /* @__PURE__ */ jsxRuntime.jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading video..." }) }),
44611
+ showBlockingVideoLoader && !error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 z-30 flex items-center justify-center bg-black", children: /* @__PURE__ */ jsxRuntime.jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading video..." }) }),
44612
+ !shouldDeferPlayerRenderForCrop && !isTransitioning && isVideoBuffering && !isInitialLoading && !error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 z-30 flex items-center justify-center bg-black/60", children: /* @__PURE__ */ jsxRuntime.jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading video..." }) }),
44559
44613
  error && error.type === "retrying" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 z-40 flex items-center justify-center bg-black/60", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center", children: [
44560
44614
  /* @__PURE__ */ jsxRuntime.jsx(OptifyeLogoLoader_default, { size: "md" }),
44561
44615
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-white text-sm mt-4 font-medium", children: error.message })
@@ -44948,7 +45002,7 @@ var BottlenecksContent = ({
44948
45002
  opacity: isTransitioning ? 0 : 1,
44949
45003
  transition: "opacity 0.1s ease-in-out"
44950
45004
  },
44951
- children: /* @__PURE__ */ jsxRuntime.jsx(
45005
+ children: !shouldDeferPlayerRenderForCrop && /* @__PURE__ */ jsxRuntime.jsx(
44952
45006
  CroppedVideoPlayer,
44953
45007
  {
44954
45008
  ref: videoRef,
@@ -44979,8 +45033,8 @@ var BottlenecksContent = ({
44979
45033
  )
44980
45034
  }
44981
45035
  ),
44982
- (isTransitioning || isVideoBuffering && isInitialLoading) && !error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 z-30 flex items-center justify-center bg-black", children: /* @__PURE__ */ jsxRuntime.jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading video..." }) }),
44983
- !isTransitioning && isVideoBuffering && !isInitialLoading && !error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 z-30 flex items-center justify-center bg-black/60", children: /* @__PURE__ */ jsxRuntime.jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading video..." }) }),
45036
+ showBlockingVideoLoader && !error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 z-30 flex items-center justify-center bg-black", children: /* @__PURE__ */ jsxRuntime.jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading video..." }) }),
45037
+ !shouldDeferPlayerRenderForCrop && !isTransitioning && isVideoBuffering && !isInitialLoading && !error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 z-30 flex items-center justify-center bg-black/60", children: /* @__PURE__ */ jsxRuntime.jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading video..." }) }),
44984
45038
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-0 left-0 right-0 p-4 bg-gradient-to-t from-black/70 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300 z-10", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between text-white", children: [
44985
45039
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
44986
45040
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: "Speed:" }),
@@ -60844,67 +60898,6 @@ var HelpView = ({
60844
60898
  };
60845
60899
  var AuthenticatedHelpView = withAuth(HelpView);
60846
60900
  var HelpView_default = HelpView;
60847
- var sortWorkspaceMetrics = (left, right) => {
60848
- if (left.line_id !== right.line_id) {
60849
- return left.line_id.localeCompare(right.line_id);
60850
- }
60851
- return left.workspace_name.localeCompare(right.workspace_name, void 0, { numeric: true });
60852
- };
60853
- var transformWorkspaceMetrics = (rows) => (rows || []).map((item) => {
60854
- const actionFamily = normalizeActionFamily({
60855
- actionFamily: item.action_family,
60856
- actionType: item.action_type,
60857
- actionName: item.action_name
60858
- });
60859
- const actionType = actionFamily === "assembly" || actionFamily === "output" ? actionFamily : null;
60860
- const metric = {
60861
- company_id: item.company_id || "",
60862
- line_id: item.line_id,
60863
- shift_id: item.shift_id,
60864
- date: item.date,
60865
- workspace_uuid: item.workspace_id,
60866
- workspace_name: item.workspace_name,
60867
- displayName: item.workspace_display_name || item.display_name || void 0,
60868
- action_count: item.total_output || 0,
60869
- pph: item.avg_pph || 0,
60870
- performance_score: item.performance_score || 0,
60871
- avg_cycle_time: item.avg_cycle_time || 0,
60872
- ideal_cycle_time: item.ideal_cycle_time || void 0,
60873
- trend: item.trend_score === 1 ? 2 : 0,
60874
- predicted_output: item.ideal_output || 0,
60875
- efficiency: item.efficiency || 0,
60876
- action_threshold: item.total_day_output || 0,
60877
- monitoring_mode: item.monitoring_mode ?? void 0,
60878
- idle_time: typeof item.idle_time === "number" ? item.idle_time : Number(item.idle_time),
60879
- idle_time_hourly: item.idle_time_hourly ?? null,
60880
- shift_start: item.shift_start ?? void 0,
60881
- shift_end: item.shift_end ?? void 0,
60882
- assembly_enabled: item.assembly_enabled ?? false,
60883
- video_grid_metric_mode: normalizeVideoGridMetricMode(
60884
- item.video_grid_metric_mode,
60885
- item.assembly_enabled ?? false
60886
- ),
60887
- action_type: actionType,
60888
- action_family: actionFamily,
60889
- action_display_name: getActionDisplayName({
60890
- displayName: item.action_display_name,
60891
- actionFamily: item.action_family,
60892
- actionType: item.action_type,
60893
- actionName: item.action_name
60894
- }),
60895
- recent_flow_percent: item.recent_flow_percent ?? null,
60896
- recent_flow_window_minutes: item.recent_flow_window_minutes ?? null,
60897
- recent_flow_effective_end_at: item.recent_flow_effective_end_at ?? null,
60898
- recent_flow_computed_at: item.recent_flow_computed_at ?? null,
60899
- scheduled_break_active: item.scheduled_break_active ?? false,
60900
- incoming_wip_current: item.incoming_wip_current ?? null,
60901
- incoming_wip_effective_at: item.incoming_wip_effective_at ?? null,
60902
- incoming_wip_buffer_name: item.incoming_wip_buffer_name ?? null,
60903
- show_exclamation: item.show_exclamation ?? void 0
60904
- };
60905
- workspaceMetricsStore.setOverview(metric);
60906
- return metric;
60907
- }).sort(sortWorkspaceMetrics);
60908
60901
  var transformActiveBreaks = (activeBreaksByLine) => {
60909
60902
  if (!activeBreaksByLine) return [];
60910
60903
  return Object.values(activeBreaksByLine).flat().map((item) => ({
@@ -60945,12 +60938,18 @@ var normalizeMetadata = (metadata) => ({
60945
60938
  var useLiveMonitorBootstrap = ({
60946
60939
  lineIds,
60947
60940
  companyId,
60948
- enabled = true
60941
+ enabled = true,
60942
+ appTimezone,
60943
+ workspaceConfig,
60944
+ fallbackShiftConfig,
60945
+ lineShiftConfigs
60949
60946
  }) => {
60950
60947
  const supabase = useSupabase();
60951
60948
  const entityConfig = useEntityConfig();
60952
60949
  const { hydrateFromBackend } = useIdleTimeVlmConfig();
60953
60950
  const resolvedCompanyId = companyId || entityConfig?.companyId;
60951
+ const effectiveWorkspaceConfig = workspaceConfig || DEFAULT_WORKSPACE_CONFIG;
60952
+ const effectiveTimezone = appTimezone || "Asia/Kolkata";
60954
60953
  const rawLineIdsKey = (lineIds || []).filter(Boolean).join(",");
60955
60954
  const normalizedLineIds = React143.useMemo(
60956
60955
  () => Array.from(new Set(rawLineIdsKey ? rawLineIdsKey.split(",") : [])),
@@ -60991,12 +60990,28 @@ var useLiveMonitorBootstrap = ({
60991
60990
  if (requestId !== activeRequestIdRef.current) {
60992
60991
  return;
60993
60992
  }
60994
- const workspaceMetrics = transformWorkspaceMetrics(response.workspace_metrics || []);
60993
+ const workspaceMetrics = transformMonitorWorkspaceMetrics({
60994
+ rows: response.workspace_metrics || [],
60995
+ companyId: resolvedCompanyId,
60996
+ workspaceConfig: effectiveWorkspaceConfig,
60997
+ appTimezone: effectiveTimezone,
60998
+ lineMetrics: response.line_metrics || [],
60999
+ resolveShiftConfig: (lineId) => lineShiftConfigs?.get(lineId) || fallbackShiftConfig,
61000
+ shouldOverrideShiftType: (lineId) => Boolean(lineShiftConfigs?.get(lineId)),
61001
+ fallbackShiftConfig
61002
+ });
60995
61003
  const activeBreaks = transformActiveBreaks(response.active_breaks_by_line);
60996
61004
  const metadata = normalizeMetadata(response.metadata);
61005
+ const workspaceIds = workspaceMetrics.map((metric) => metric.workspace_uuid).filter((workspaceId) => Boolean(workspaceId));
61006
+ const videoStreamsByWorkspaceId = response.video_streams_by_workspace_id || {};
60997
61007
  if (metadata.idleTimeVlmByLine) {
60998
61008
  hydrateFromBackend(metadata.idleTimeVlmByLine);
60999
61009
  }
61010
+ workspaceService.primeWorkspaceVideoStreamsCache({
61011
+ streams: videoStreamsByWorkspaceId,
61012
+ workspaceIds,
61013
+ lineIds: normalizedLineIds
61014
+ });
61000
61015
  setState({
61001
61016
  requestKey,
61002
61017
  resolvedScope: response.resolved_scope || [],
@@ -61006,7 +61021,7 @@ var useLiveMonitorBootstrap = ({
61006
61021
  lineMetrics: response.line_metrics || [],
61007
61022
  kpiTrend: response.kpi_trend || null,
61008
61023
  activeBreaks,
61009
- videoStreamsByWorkspaceId: response.video_streams_by_workspace_id || {},
61024
+ videoStreamsByWorkspaceId,
61010
61025
  efficiencyLegend: response.efficiency_legend || null,
61011
61026
  metadata
61012
61027
  });
@@ -61020,7 +61035,18 @@ var useLiveMonitorBootstrap = ({
61020
61035
  setIsLoading(false);
61021
61036
  }
61022
61037
  }
61023
- }, [enabled, supabase, resolvedCompanyId, normalizedLineIds, requestKey, hydrateFromBackend]);
61038
+ }, [
61039
+ enabled,
61040
+ supabase,
61041
+ resolvedCompanyId,
61042
+ normalizedLineIds,
61043
+ requestKey,
61044
+ hydrateFromBackend,
61045
+ effectiveWorkspaceConfig,
61046
+ effectiveTimezone,
61047
+ lineShiftConfigs,
61048
+ fallbackShiftConfig
61049
+ ]);
61024
61050
  React143.useEffect(() => {
61025
61051
  if (!enabled) {
61026
61052
  setIsLoading(false);
@@ -61580,7 +61606,11 @@ function HomeView({
61580
61606
  const bootstrapMonitor = useLiveMonitorBootstrap({
61581
61607
  lineIds: selectedLineIds,
61582
61608
  companyId: userCompanyId,
61583
- enabled: shouldEnableMetricsFetch && !isLegacyMonitorMode
61609
+ enabled: shouldEnableMetricsFetch && !isLegacyMonitorMode,
61610
+ appTimezone: timezone,
61611
+ workspaceConfig: dashboardConfig?.workspaceConfig,
61612
+ fallbackShiftConfig: dashboardConfig?.shiftConfig,
61613
+ lineShiftConfigs
61584
61614
  });
61585
61615
  const currentWorkspaceMetrics = isBootstrapMonitorMode ? bootstrapMonitor.workspaceMetrics : legacyWorkspaceMetrics;
61586
61616
  const currentLineMetrics = isBootstrapMonitorMode ? bootstrapMonitor.lineMetrics : legacyLineMetrics;
@@ -62784,7 +62814,7 @@ var buildLineInfoSnapshot = (lineDetails, metrics2) => {
62784
62814
  }
62785
62815
  };
62786
62816
  };
62787
- var transformWorkspaceMetrics2 = (workspaceData, lineId, companyId, queryDate, queryShiftId) => (workspaceData || []).map((item) => ({
62817
+ var transformWorkspaceMetrics = (workspaceData, lineId, companyId, queryDate, queryShiftId) => (workspaceData || []).map((item) => ({
62788
62818
  company_id: item.company_id || companyId,
62789
62819
  line_id: item.line_id || lineId,
62790
62820
  shift_id: item.shift_id ?? queryShiftId,
@@ -62932,7 +62962,7 @@ var useLineDetailPageData = ({
62932
62962
  setDetailResponse(nextDetail);
62933
62963
  const metrics3 = transformLineMetrics(lineId, nextDetail, queryDate, queryShiftId);
62934
62964
  const lineDetails2 = transformLineDetails(lineId, nextDetail);
62935
- const workspaces2 = transformWorkspaceMetrics2(
62965
+ const workspaces2 = transformWorkspaceMetrics(
62936
62966
  nextDetail.workspace_metrics || [],
62937
62967
  lineId,
62938
62968
  companyId,
@@ -63022,7 +63052,7 @@ var useLineDetailPageData = ({
63022
63052
  [detailResponse, lineId]
63023
63053
  );
63024
63054
  const workspaces = React143.useMemo(
63025
- () => detailResponse && companyId ? transformWorkspaceMetrics2(detailResponse.workspace_metrics || [], lineId, companyId, queryDate, queryShiftId) : [],
63055
+ () => detailResponse && companyId ? transformWorkspaceMetrics(detailResponse.workspace_metrics || [], lineId, companyId, queryDate, queryShiftId) : [],
63026
63056
  [detailResponse, companyId, lineId, queryDate, queryShiftId]
63027
63057
  );
63028
63058
  const lineInfo = React143.useMemo(() => buildLineInfoSnapshot(lineDetails, metrics2), [lineDetails, metrics2]);
@@ -72090,6 +72120,8 @@ var WorkspaceDetailView = ({
72090
72120
  const totalActions = Number(cachedOverviewMetrics.action_count || 0);
72091
72121
  const targetOutput = Number(cachedOverviewMetrics.action_threshold || 0);
72092
72122
  const idealOutput = Number(cachedOverviewMetrics.predicted_output ?? targetOutput ?? 0);
72123
+ const pphThreshold = Number(cachedOverviewMetrics.pph_threshold || 0);
72124
+ const idealCycleTime = Number(cachedOverviewMetrics.ideal_cycle_time || 0);
72093
72125
  return {
72094
72126
  line_id: cachedOverviewMetrics.line_id,
72095
72127
  line_name: "",
@@ -72108,11 +72140,11 @@ var WorkspaceDetailView = ({
72108
72140
  shift_start: shiftDefinition?.startTime || "",
72109
72141
  shift_end: shiftDefinition?.endTime || "",
72110
72142
  shift_type: shiftType,
72111
- pph_threshold: 0,
72143
+ pph_threshold: pphThreshold,
72112
72144
  target_output: targetOutput,
72113
72145
  avg_pph: Number(cachedOverviewMetrics.pph || 0),
72114
72146
  avg_cycle_time: avgCycleTime,
72115
- ideal_cycle_time: avgCycleTime,
72147
+ ideal_cycle_time: idealCycleTime,
72116
72148
  avg_efficiency: Number(cachedOverviewMetrics.efficiency || 0),
72117
72149
  total_actions: totalActions,
72118
72150
  hourly_action_counts: [],
package/dist/index.mjs CHANGED
@@ -5088,6 +5088,27 @@ var workspaceService = {
5088
5088
  this._workspaceVideoStreamsInFlight.set(cacheKey, fetchPromise);
5089
5089
  return fetchPromise;
5090
5090
  },
5091
+ primeWorkspaceVideoStreamsCache(params) {
5092
+ const streams = params.streams || {};
5093
+ const workspaceIds = (params.workspaceIds || []).filter(Boolean);
5094
+ const lineIds = (params.lineIds || []).filter(Boolean);
5095
+ if (!Object.keys(streams).length || !workspaceIds.length && !lineIds.length) {
5096
+ return;
5097
+ }
5098
+ const timestamp = Date.now();
5099
+ const entry = {
5100
+ streams,
5101
+ timestamp
5102
+ };
5103
+ if (workspaceIds.length) {
5104
+ const workspaceKey = workspaceIds.slice().sort().join(",");
5105
+ this._workspaceVideoStreamsCache.set(`workspaces:${workspaceKey}`, entry);
5106
+ }
5107
+ if (lineIds.length) {
5108
+ const lineKey = lineIds.slice().sort().join(",");
5109
+ this._workspaceVideoStreamsCache.set(`lines:${lineKey}`, entry);
5110
+ }
5111
+ },
5091
5112
  async getWorkspaceCameraIps(params) {
5092
5113
  const workspaceIds = (params.workspaceIds || []).filter(Boolean);
5093
5114
  const lineIds = (params.lineIds || []).filter(Boolean);
@@ -11959,8 +11980,8 @@ var useOperationalShiftKey = ({
11959
11980
  };
11960
11981
 
11961
11982
  // src/lib/stores/workspaceMetricsStore.ts
11962
- var OVERVIEW_TTL_MS = 3e4;
11963
- var DETAILED_TTL_MS = 3e4;
11983
+ var OVERVIEW_TTL_MS = 12e4;
11984
+ var DETAILED_TTL_MS = 12e4;
11964
11985
  var overviewByKey = /* @__PURE__ */ new Map();
11965
11986
  var detailedByKey = /* @__PURE__ */ new Map();
11966
11987
  var latestOverviewByWorkspace = /* @__PURE__ */ new Map();
@@ -13456,6 +13477,109 @@ function getEfficiencyTextColorClasses(efficiency, legend = DEFAULT_EFFICIENCY_L
13456
13477
  }
13457
13478
  }
13458
13479
 
13480
+ // src/lib/utils/monitorWorkspaceMetrics.ts
13481
+ var sortWorkspaceMetrics = (left, right) => {
13482
+ if (left.line_id !== right.line_id) {
13483
+ return left.line_id.localeCompare(right.line_id);
13484
+ }
13485
+ return left.workspace_name.localeCompare(right.workspace_name, void 0, { numeric: true });
13486
+ };
13487
+ var buildLineMetricsById = (lineMetrics) => (lineMetrics || []).reduce((acc, lineMetric) => {
13488
+ const lineId = lineMetric?.line_id;
13489
+ if (!lineId) {
13490
+ return acc;
13491
+ }
13492
+ acc[lineId] = { total_workspaces: lineMetric?.total_workspaces };
13493
+ return acc;
13494
+ }, {});
13495
+ var transformMonitorWorkspaceMetrics = ({
13496
+ rows,
13497
+ companyId,
13498
+ workspaceConfig,
13499
+ appTimezone,
13500
+ lineMetrics,
13501
+ resolveShiftConfig,
13502
+ shouldOverrideShiftType,
13503
+ fallbackShiftConfig = null
13504
+ }) => {
13505
+ const effectiveWorkspaceConfig = workspaceConfig || DEFAULT_WORKSPACE_CONFIG;
13506
+ const detailTimezone = appTimezone || "Asia/Kolkata";
13507
+ const lineMetricsById = buildLineMetricsById(lineMetrics);
13508
+ return (rows || []).map((item) => {
13509
+ const lineId = String(item?.line_id || "");
13510
+ const lineShiftConfig = resolveShiftConfig?.(lineId) || fallbackShiftConfig || void 0;
13511
+ const detailedMetrics = toWorkspaceDetailedMetrics({
13512
+ data: item,
13513
+ companyId,
13514
+ workspaceConfig: effectiveWorkspaceConfig,
13515
+ shiftConfig: lineShiftConfig,
13516
+ appTimezone: detailTimezone,
13517
+ lineMetricsById,
13518
+ overrideShiftType: shouldOverrideShiftType?.(lineId) ?? false
13519
+ });
13520
+ if (detailedMetrics) {
13521
+ workspaceMetricsStore.setDetailed(detailedMetrics);
13522
+ }
13523
+ const idleTimeValue = typeof item.idle_time === "number" ? item.idle_time : Number(item.idle_time);
13524
+ const idleTimeSeconds = Number.isFinite(idleTimeValue) ? idleTimeValue : void 0;
13525
+ const pphThresholdValue = typeof item.pph_threshold === "number" ? item.pph_threshold : Number(item.pph_threshold);
13526
+ const actionFamily = normalizeActionFamily({
13527
+ actionFamily: item.action_family,
13528
+ actionType: item.action_type,
13529
+ actionName: item.action_name
13530
+ });
13531
+ const actionType = actionFamily === "assembly" || actionFamily === "output" ? actionFamily : null;
13532
+ const metric = {
13533
+ company_id: item.company_id || companyId,
13534
+ line_id: lineId,
13535
+ shift_id: item.shift_id,
13536
+ date: item.date,
13537
+ workspace_uuid: item.workspace_id,
13538
+ workspace_name: item.workspace_name,
13539
+ displayName: item.workspace_display_name || item.display_name || void 0,
13540
+ action_count: item.total_output || 0,
13541
+ pph: item.avg_pph || 0,
13542
+ pph_threshold: Number.isFinite(pphThresholdValue) ? pphThresholdValue : void 0,
13543
+ performance_score: item.performance_score || 0,
13544
+ avg_cycle_time: item.avg_cycle_time || 0,
13545
+ ideal_cycle_time: item.ideal_cycle_time || void 0,
13546
+ trend: item.trend_score === 1 ? 2 : 0,
13547
+ predicted_output: item.ideal_output || 0,
13548
+ efficiency: item.efficiency || 0,
13549
+ action_threshold: item.total_day_output || 0,
13550
+ monitoring_mode: item.monitoring_mode ?? void 0,
13551
+ idle_time: idleTimeSeconds,
13552
+ idle_time_hourly: item.idle_time_hourly ?? null,
13553
+ shift_start: item.shift_start ?? void 0,
13554
+ shift_end: item.shift_end ?? void 0,
13555
+ assembly_enabled: item.assembly_enabled ?? false,
13556
+ video_grid_metric_mode: normalizeVideoGridMetricMode(
13557
+ item.video_grid_metric_mode,
13558
+ item.assembly_enabled ?? false
13559
+ ),
13560
+ action_type: actionType,
13561
+ action_family: actionFamily,
13562
+ action_display_name: getActionDisplayName({
13563
+ displayName: item.action_display_name,
13564
+ actionFamily: item.action_family,
13565
+ actionType: item.action_type,
13566
+ actionName: item.action_name
13567
+ }),
13568
+ recent_flow_percent: item.recent_flow_percent ?? null,
13569
+ recent_flow_window_minutes: item.recent_flow_window_minutes ?? null,
13570
+ recent_flow_effective_end_at: item.recent_flow_effective_end_at ?? null,
13571
+ recent_flow_computed_at: item.recent_flow_computed_at ?? null,
13572
+ scheduled_break_active: item.scheduled_break_active ?? false,
13573
+ incoming_wip_current: item.incoming_wip_current ?? null,
13574
+ incoming_wip_effective_at: item.incoming_wip_effective_at ?? null,
13575
+ incoming_wip_buffer_name: item.incoming_wip_buffer_name ?? null,
13576
+ show_exclamation: item.show_exclamation ?? void 0
13577
+ };
13578
+ workspaceMetricsStore.setOverview(metric);
13579
+ return metric;
13580
+ }).sort(sortWorkspaceMetrics);
13581
+ };
13582
+
13459
13583
  // src/lib/hooks/useDashboardMetrics.ts
13460
13584
  var DEBUG_DASHBOARD_LOGS = process.env.NEXT_PUBLIC_DEBUG_DASHBOARD === "true";
13461
13585
  var REALTIME_REFRESH_DEBOUNCE_MS = 1500;
@@ -13773,89 +13897,16 @@ var useDashboardMetrics = ({
13773
13897
  }
13774
13898
  efficiencyLegend = parseEfficiencyLegend(backendData?.efficiency_legend) ?? DEFAULT_EFFICIENCY_LEGEND;
13775
13899
  }
13776
- const lineMetricsById = (allLineMetrics || []).reduce(
13777
- (acc, line) => {
13778
- const lineId2 = line?.line_id;
13779
- if (lineId2) {
13780
- acc[lineId2] = { total_workspaces: line?.total_workspaces };
13781
- }
13782
- return acc;
13783
- },
13784
- {}
13785
- );
13786
13900
  const detailTimezone = appTimezone || "Asia/Kolkata";
13787
- allWorkspaceMetrics.forEach((item) => {
13788
- const lineShiftConfig = isFactoryView ? multiLineShiftConfigMap.get(item.line_id) : shiftConfig;
13789
- const detailedMetrics = toWorkspaceDetailedMetrics({
13790
- data: item,
13791
- companyId: companyId || "",
13792
- workspaceConfig: effectiveWorkspaceConfig,
13793
- shiftConfig: lineShiftConfig || staticShiftConfig,
13794
- appTimezone: detailTimezone,
13795
- lineMetricsById,
13796
- overrideShiftType: Boolean(lineShiftConfig)
13797
- });
13798
- if (detailedMetrics) {
13799
- workspaceMetricsStore.setDetailed(detailedMetrics);
13800
- }
13801
- });
13802
- const transformedWorkspaceData = allWorkspaceMetrics.map((item) => {
13803
- const idleTimeValue = typeof item.idle_time === "number" ? item.idle_time : Number(item.idle_time);
13804
- const idleTimeSeconds = Number.isFinite(idleTimeValue) ? idleTimeValue : void 0;
13805
- const actionFamily = normalizeActionFamily({
13806
- actionFamily: item.action_family,
13807
- actionType: item.action_type,
13808
- actionName: item.action_name
13809
- });
13810
- const actionType = actionFamily === "assembly" || actionFamily === "output" ? actionFamily : null;
13811
- return {
13812
- company_id: item.company_id || companyId,
13813
- line_id: item.line_id,
13814
- shift_id: item.shift_id,
13815
- date: item.date,
13816
- workspace_uuid: item.workspace_id,
13817
- workspace_name: item.workspace_name,
13818
- displayName: item.workspace_display_name || item.display_name || void 0,
13819
- action_count: item.total_output || 0,
13820
- pph: item.avg_pph || 0,
13821
- performance_score: item.performance_score || 0,
13822
- avg_cycle_time: item.avg_cycle_time || 0,
13823
- trend: item.trend_score === 1 ? 2 : 0,
13824
- predicted_output: item.ideal_output || 0,
13825
- efficiency: item.efficiency || 0,
13826
- action_threshold: item.total_day_output || 0,
13827
- show_exclamation: item.show_exclamation ?? void 0,
13828
- monitoring_mode: item.monitoring_mode ?? void 0,
13829
- idle_time: idleTimeSeconds,
13830
- assembly_enabled: item.assembly_enabled ?? false,
13831
- video_grid_metric_mode: normalizeVideoGridMetricMode(
13832
- item.video_grid_metric_mode,
13833
- item.assembly_enabled ?? false
13834
- ),
13835
- action_type: actionType,
13836
- action_family: actionFamily,
13837
- action_display_name: getActionDisplayName({
13838
- displayName: item.action_display_name,
13839
- actionFamily: item.action_family,
13840
- actionType: item.action_type,
13841
- actionName: item.action_name
13842
- }),
13843
- recent_flow_percent: item.recent_flow_percent ?? null,
13844
- recent_flow_window_minutes: item.recent_flow_window_minutes ?? null,
13845
- recent_flow_effective_end_at: item.recent_flow_effective_end_at ?? null,
13846
- recent_flow_computed_at: item.recent_flow_computed_at ?? null,
13847
- incoming_wip_current: item.incoming_wip_current ?? null,
13848
- incoming_wip_effective_at: item.incoming_wip_effective_at ?? null,
13849
- incoming_wip_buffer_name: item.incoming_wip_buffer_name ?? null
13850
- };
13851
- }).sort((a, b) => {
13852
- if (a.line_id !== b.line_id) return a.line_id.localeCompare(b.line_id);
13853
- const wsNumA = parseInt(a.workspace_name?.replace(/[^0-9]/g, "") || "0");
13854
- const wsNumB = parseInt(b.workspace_name?.replace(/[^0-9]/g, "") || "0");
13855
- return wsNumA - wsNumB;
13856
- });
13857
- transformedWorkspaceData.forEach((metric) => {
13858
- workspaceMetricsStore.setOverview(metric);
13901
+ const transformedWorkspaceData = transformMonitorWorkspaceMetrics({
13902
+ rows: allWorkspaceMetrics,
13903
+ companyId: companyId || "",
13904
+ workspaceConfig: effectiveWorkspaceConfig,
13905
+ appTimezone: detailTimezone,
13906
+ lineMetrics: allLineMetrics,
13907
+ resolveShiftConfig: (metricLineId) => isFactoryView ? multiLineShiftConfigMap.get(metricLineId) || staticShiftConfig : shiftConfig || staticShiftConfig,
13908
+ shouldOverrideShiftType: (metricLineId) => isFactoryView ? Boolean(multiLineShiftConfigMap.get(metricLineId)) : Boolean(shiftConfig),
13909
+ fallbackShiftConfig: staticShiftConfig
13859
13910
  });
13860
13911
  const newMetricsState = {
13861
13912
  workspaceMetrics: transformedWorkspaceData,
@@ -37575,6 +37626,7 @@ var buildPrefetchedExplorerMetadata = (activeFilter, metadataCategoryId, categor
37575
37626
  [activeFilter]: categoryMetadata
37576
37627
  };
37577
37628
  };
37629
+ var shouldDeferClipPlayerRender = (cropLoading, workspaceCrop) => cropLoading && workspaceCrop === null;
37578
37630
  var getSecondsBetweenTimestamps = (startTime, endTime) => {
37579
37631
  const startDate = parseTimestamp(startTime);
37580
37632
  const endDate = parseTimestamp(endTime);
@@ -42706,7 +42758,7 @@ var BottlenecksContent = ({
42706
42758
  const isEffectiveShiftReady = Boolean(effectiveShift && effectiveDate);
42707
42759
  const effectiveDateString = effectiveDate || "";
42708
42760
  const effectiveShiftId = effectiveShift ?? "";
42709
- const { crop: workspaceCrop} = useWorkspaceCrop(workspaceId);
42761
+ const { crop: workspaceCrop, isLoading: cropLoading } = useWorkspaceCrop(workspaceId);
42710
42762
  const { metrics: fetchedWorkspaceMetrics } = useWorkspaceDetailedMetrics(
42711
42763
  workspaceId,
42712
42764
  date,
@@ -42755,6 +42807,8 @@ var BottlenecksContent = ({
42755
42807
  const [pendingVideo, setPendingVideo] = useState(null);
42756
42808
  const [isVideoBuffering, setIsVideoBuffering] = useState(false);
42757
42809
  const [isInitialLoading, setIsInitialLoading] = useState(false);
42810
+ const shouldDeferPlayerRenderForCrop = shouldDeferClipPlayerRender(cropLoading, workspaceCrop);
42811
+ const showBlockingVideoLoader = shouldDeferPlayerRenderForCrop || isTransitioning || isVideoBuffering && isInitialLoading;
42758
42812
  const [isShareLoading, setIsShareLoading] = useState(false);
42759
42813
  const [isShareCopied, setIsShareCopied] = useState(false);
42760
42814
  const shareCopiedTimeoutRef = useRef(null);
@@ -44494,7 +44548,7 @@ var BottlenecksContent = ({
44494
44548
  opacity: isTransitioning ? 0 : 1,
44495
44549
  transition: "opacity 0.1s ease-in-out"
44496
44550
  },
44497
- children: /* @__PURE__ */ jsx(
44551
+ children: !shouldDeferPlayerRenderForCrop && /* @__PURE__ */ jsx(
44498
44552
  CroppedVideoPlayer,
44499
44553
  {
44500
44554
  ref: videoRef,
@@ -44525,8 +44579,8 @@ var BottlenecksContent = ({
44525
44579
  )
44526
44580
  }
44527
44581
  ),
44528
- (isTransitioning || isVideoBuffering && isInitialLoading) && !error && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 z-30 flex items-center justify-center bg-black", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading video..." }) }),
44529
- !isTransitioning && isVideoBuffering && !isInitialLoading && !error && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 z-30 flex items-center justify-center bg-black/60", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading video..." }) }),
44582
+ showBlockingVideoLoader && !error && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 z-30 flex items-center justify-center bg-black", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading video..." }) }),
44583
+ !shouldDeferPlayerRenderForCrop && !isTransitioning && isVideoBuffering && !isInitialLoading && !error && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 z-30 flex items-center justify-center bg-black/60", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading video..." }) }),
44530
44584
  error && error.type === "retrying" && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 z-40 flex items-center justify-center bg-black/60", children: /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
44531
44585
  /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "md" }),
44532
44586
  /* @__PURE__ */ jsx("p", { className: "text-white text-sm mt-4 font-medium", children: error.message })
@@ -44919,7 +44973,7 @@ var BottlenecksContent = ({
44919
44973
  opacity: isTransitioning ? 0 : 1,
44920
44974
  transition: "opacity 0.1s ease-in-out"
44921
44975
  },
44922
- children: /* @__PURE__ */ jsx(
44976
+ children: !shouldDeferPlayerRenderForCrop && /* @__PURE__ */ jsx(
44923
44977
  CroppedVideoPlayer,
44924
44978
  {
44925
44979
  ref: videoRef,
@@ -44950,8 +45004,8 @@ var BottlenecksContent = ({
44950
45004
  )
44951
45005
  }
44952
45006
  ),
44953
- (isTransitioning || isVideoBuffering && isInitialLoading) && !error && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 z-30 flex items-center justify-center bg-black", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading video..." }) }),
44954
- !isTransitioning && isVideoBuffering && !isInitialLoading && !error && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 z-30 flex items-center justify-center bg-black/60", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading video..." }) }),
45007
+ showBlockingVideoLoader && !error && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 z-30 flex items-center justify-center bg-black", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading video..." }) }),
45008
+ !shouldDeferPlayerRenderForCrop && !isTransitioning && isVideoBuffering && !isInitialLoading && !error && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 z-30 flex items-center justify-center bg-black/60", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading video..." }) }),
44955
45009
  /* @__PURE__ */ jsx("div", { className: "absolute bottom-0 left-0 right-0 p-4 bg-gradient-to-t from-black/70 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300 z-10", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-white", children: [
44956
45010
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
44957
45011
  /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: "Speed:" }),
@@ -60815,67 +60869,6 @@ var HelpView = ({
60815
60869
  };
60816
60870
  var AuthenticatedHelpView = withAuth(HelpView);
60817
60871
  var HelpView_default = HelpView;
60818
- var sortWorkspaceMetrics = (left, right) => {
60819
- if (left.line_id !== right.line_id) {
60820
- return left.line_id.localeCompare(right.line_id);
60821
- }
60822
- return left.workspace_name.localeCompare(right.workspace_name, void 0, { numeric: true });
60823
- };
60824
- var transformWorkspaceMetrics = (rows) => (rows || []).map((item) => {
60825
- const actionFamily = normalizeActionFamily({
60826
- actionFamily: item.action_family,
60827
- actionType: item.action_type,
60828
- actionName: item.action_name
60829
- });
60830
- const actionType = actionFamily === "assembly" || actionFamily === "output" ? actionFamily : null;
60831
- const metric = {
60832
- company_id: item.company_id || "",
60833
- line_id: item.line_id,
60834
- shift_id: item.shift_id,
60835
- date: item.date,
60836
- workspace_uuid: item.workspace_id,
60837
- workspace_name: item.workspace_name,
60838
- displayName: item.workspace_display_name || item.display_name || void 0,
60839
- action_count: item.total_output || 0,
60840
- pph: item.avg_pph || 0,
60841
- performance_score: item.performance_score || 0,
60842
- avg_cycle_time: item.avg_cycle_time || 0,
60843
- ideal_cycle_time: item.ideal_cycle_time || void 0,
60844
- trend: item.trend_score === 1 ? 2 : 0,
60845
- predicted_output: item.ideal_output || 0,
60846
- efficiency: item.efficiency || 0,
60847
- action_threshold: item.total_day_output || 0,
60848
- monitoring_mode: item.monitoring_mode ?? void 0,
60849
- idle_time: typeof item.idle_time === "number" ? item.idle_time : Number(item.idle_time),
60850
- idle_time_hourly: item.idle_time_hourly ?? null,
60851
- shift_start: item.shift_start ?? void 0,
60852
- shift_end: item.shift_end ?? void 0,
60853
- assembly_enabled: item.assembly_enabled ?? false,
60854
- video_grid_metric_mode: normalizeVideoGridMetricMode(
60855
- item.video_grid_metric_mode,
60856
- item.assembly_enabled ?? false
60857
- ),
60858
- action_type: actionType,
60859
- action_family: actionFamily,
60860
- action_display_name: getActionDisplayName({
60861
- displayName: item.action_display_name,
60862
- actionFamily: item.action_family,
60863
- actionType: item.action_type,
60864
- actionName: item.action_name
60865
- }),
60866
- recent_flow_percent: item.recent_flow_percent ?? null,
60867
- recent_flow_window_minutes: item.recent_flow_window_minutes ?? null,
60868
- recent_flow_effective_end_at: item.recent_flow_effective_end_at ?? null,
60869
- recent_flow_computed_at: item.recent_flow_computed_at ?? null,
60870
- scheduled_break_active: item.scheduled_break_active ?? false,
60871
- incoming_wip_current: item.incoming_wip_current ?? null,
60872
- incoming_wip_effective_at: item.incoming_wip_effective_at ?? null,
60873
- incoming_wip_buffer_name: item.incoming_wip_buffer_name ?? null,
60874
- show_exclamation: item.show_exclamation ?? void 0
60875
- };
60876
- workspaceMetricsStore.setOverview(metric);
60877
- return metric;
60878
- }).sort(sortWorkspaceMetrics);
60879
60872
  var transformActiveBreaks = (activeBreaksByLine) => {
60880
60873
  if (!activeBreaksByLine) return [];
60881
60874
  return Object.values(activeBreaksByLine).flat().map((item) => ({
@@ -60916,12 +60909,18 @@ var normalizeMetadata = (metadata) => ({
60916
60909
  var useLiveMonitorBootstrap = ({
60917
60910
  lineIds,
60918
60911
  companyId,
60919
- enabled = true
60912
+ enabled = true,
60913
+ appTimezone,
60914
+ workspaceConfig,
60915
+ fallbackShiftConfig,
60916
+ lineShiftConfigs
60920
60917
  }) => {
60921
60918
  const supabase = useSupabase();
60922
60919
  const entityConfig = useEntityConfig();
60923
60920
  const { hydrateFromBackend } = useIdleTimeVlmConfig();
60924
60921
  const resolvedCompanyId = companyId || entityConfig?.companyId;
60922
+ const effectiveWorkspaceConfig = workspaceConfig || DEFAULT_WORKSPACE_CONFIG;
60923
+ const effectiveTimezone = appTimezone || "Asia/Kolkata";
60925
60924
  const rawLineIdsKey = (lineIds || []).filter(Boolean).join(",");
60926
60925
  const normalizedLineIds = useMemo(
60927
60926
  () => Array.from(new Set(rawLineIdsKey ? rawLineIdsKey.split(",") : [])),
@@ -60962,12 +60961,28 @@ var useLiveMonitorBootstrap = ({
60962
60961
  if (requestId !== activeRequestIdRef.current) {
60963
60962
  return;
60964
60963
  }
60965
- const workspaceMetrics = transformWorkspaceMetrics(response.workspace_metrics || []);
60964
+ const workspaceMetrics = transformMonitorWorkspaceMetrics({
60965
+ rows: response.workspace_metrics || [],
60966
+ companyId: resolvedCompanyId,
60967
+ workspaceConfig: effectiveWorkspaceConfig,
60968
+ appTimezone: effectiveTimezone,
60969
+ lineMetrics: response.line_metrics || [],
60970
+ resolveShiftConfig: (lineId) => lineShiftConfigs?.get(lineId) || fallbackShiftConfig,
60971
+ shouldOverrideShiftType: (lineId) => Boolean(lineShiftConfigs?.get(lineId)),
60972
+ fallbackShiftConfig
60973
+ });
60966
60974
  const activeBreaks = transformActiveBreaks(response.active_breaks_by_line);
60967
60975
  const metadata = normalizeMetadata(response.metadata);
60976
+ const workspaceIds = workspaceMetrics.map((metric) => metric.workspace_uuid).filter((workspaceId) => Boolean(workspaceId));
60977
+ const videoStreamsByWorkspaceId = response.video_streams_by_workspace_id || {};
60968
60978
  if (metadata.idleTimeVlmByLine) {
60969
60979
  hydrateFromBackend(metadata.idleTimeVlmByLine);
60970
60980
  }
60981
+ workspaceService.primeWorkspaceVideoStreamsCache({
60982
+ streams: videoStreamsByWorkspaceId,
60983
+ workspaceIds,
60984
+ lineIds: normalizedLineIds
60985
+ });
60971
60986
  setState({
60972
60987
  requestKey,
60973
60988
  resolvedScope: response.resolved_scope || [],
@@ -60977,7 +60992,7 @@ var useLiveMonitorBootstrap = ({
60977
60992
  lineMetrics: response.line_metrics || [],
60978
60993
  kpiTrend: response.kpi_trend || null,
60979
60994
  activeBreaks,
60980
- videoStreamsByWorkspaceId: response.video_streams_by_workspace_id || {},
60995
+ videoStreamsByWorkspaceId,
60981
60996
  efficiencyLegend: response.efficiency_legend || null,
60982
60997
  metadata
60983
60998
  });
@@ -60991,7 +61006,18 @@ var useLiveMonitorBootstrap = ({
60991
61006
  setIsLoading(false);
60992
61007
  }
60993
61008
  }
60994
- }, [enabled, supabase, resolvedCompanyId, normalizedLineIds, requestKey, hydrateFromBackend]);
61009
+ }, [
61010
+ enabled,
61011
+ supabase,
61012
+ resolvedCompanyId,
61013
+ normalizedLineIds,
61014
+ requestKey,
61015
+ hydrateFromBackend,
61016
+ effectiveWorkspaceConfig,
61017
+ effectiveTimezone,
61018
+ lineShiftConfigs,
61019
+ fallbackShiftConfig
61020
+ ]);
60995
61021
  useEffect(() => {
60996
61022
  if (!enabled) {
60997
61023
  setIsLoading(false);
@@ -61551,7 +61577,11 @@ function HomeView({
61551
61577
  const bootstrapMonitor = useLiveMonitorBootstrap({
61552
61578
  lineIds: selectedLineIds,
61553
61579
  companyId: userCompanyId,
61554
- enabled: shouldEnableMetricsFetch && !isLegacyMonitorMode
61580
+ enabled: shouldEnableMetricsFetch && !isLegacyMonitorMode,
61581
+ appTimezone: timezone,
61582
+ workspaceConfig: dashboardConfig?.workspaceConfig,
61583
+ fallbackShiftConfig: dashboardConfig?.shiftConfig,
61584
+ lineShiftConfigs
61555
61585
  });
61556
61586
  const currentWorkspaceMetrics = isBootstrapMonitorMode ? bootstrapMonitor.workspaceMetrics : legacyWorkspaceMetrics;
61557
61587
  const currentLineMetrics = isBootstrapMonitorMode ? bootstrapMonitor.lineMetrics : legacyLineMetrics;
@@ -62755,7 +62785,7 @@ var buildLineInfoSnapshot = (lineDetails, metrics2) => {
62755
62785
  }
62756
62786
  };
62757
62787
  };
62758
- var transformWorkspaceMetrics2 = (workspaceData, lineId, companyId, queryDate, queryShiftId) => (workspaceData || []).map((item) => ({
62788
+ var transformWorkspaceMetrics = (workspaceData, lineId, companyId, queryDate, queryShiftId) => (workspaceData || []).map((item) => ({
62759
62789
  company_id: item.company_id || companyId,
62760
62790
  line_id: item.line_id || lineId,
62761
62791
  shift_id: item.shift_id ?? queryShiftId,
@@ -62903,7 +62933,7 @@ var useLineDetailPageData = ({
62903
62933
  setDetailResponse(nextDetail);
62904
62934
  const metrics3 = transformLineMetrics(lineId, nextDetail, queryDate, queryShiftId);
62905
62935
  const lineDetails2 = transformLineDetails(lineId, nextDetail);
62906
- const workspaces2 = transformWorkspaceMetrics2(
62936
+ const workspaces2 = transformWorkspaceMetrics(
62907
62937
  nextDetail.workspace_metrics || [],
62908
62938
  lineId,
62909
62939
  companyId,
@@ -62993,7 +63023,7 @@ var useLineDetailPageData = ({
62993
63023
  [detailResponse, lineId]
62994
63024
  );
62995
63025
  const workspaces = useMemo(
62996
- () => detailResponse && companyId ? transformWorkspaceMetrics2(detailResponse.workspace_metrics || [], lineId, companyId, queryDate, queryShiftId) : [],
63026
+ () => detailResponse && companyId ? transformWorkspaceMetrics(detailResponse.workspace_metrics || [], lineId, companyId, queryDate, queryShiftId) : [],
62997
63027
  [detailResponse, companyId, lineId, queryDate, queryShiftId]
62998
63028
  );
62999
63029
  const lineInfo = useMemo(() => buildLineInfoSnapshot(lineDetails, metrics2), [lineDetails, metrics2]);
@@ -72061,6 +72091,8 @@ var WorkspaceDetailView = ({
72061
72091
  const totalActions = Number(cachedOverviewMetrics.action_count || 0);
72062
72092
  const targetOutput = Number(cachedOverviewMetrics.action_threshold || 0);
72063
72093
  const idealOutput = Number(cachedOverviewMetrics.predicted_output ?? targetOutput ?? 0);
72094
+ const pphThreshold = Number(cachedOverviewMetrics.pph_threshold || 0);
72095
+ const idealCycleTime = Number(cachedOverviewMetrics.ideal_cycle_time || 0);
72064
72096
  return {
72065
72097
  line_id: cachedOverviewMetrics.line_id,
72066
72098
  line_name: "",
@@ -72079,11 +72111,11 @@ var WorkspaceDetailView = ({
72079
72111
  shift_start: shiftDefinition?.startTime || "",
72080
72112
  shift_end: shiftDefinition?.endTime || "",
72081
72113
  shift_type: shiftType,
72082
- pph_threshold: 0,
72114
+ pph_threshold: pphThreshold,
72083
72115
  target_output: targetOutput,
72084
72116
  avg_pph: Number(cachedOverviewMetrics.pph || 0),
72085
72117
  avg_cycle_time: avgCycleTime,
72086
- ideal_cycle_time: avgCycleTime,
72118
+ ideal_cycle_time: idealCycleTime,
72087
72119
  avg_efficiency: Number(cachedOverviewMetrics.efficiency || 0),
72088
72120
  total_actions: totalActions,
72089
72121
  hourly_action_counts: [],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optifye/dashboard-core",
3
- "version": "6.11.44",
3
+ "version": "6.11.46",
4
4
  "description": "Reusable UI & logic for Optifye dashboard",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",