@optifye/dashboard-core 6.6.8 → 6.6.10

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
@@ -1299,11 +1299,11 @@ declare class S3ClipsSupabaseService {
1299
1299
  /**
1300
1300
  * Get clip counts with optional video index
1301
1301
  */
1302
- getClipCountsCacheFirst(workspaceId: string, date: string, shiftId: string | number, buildIndex?: boolean): Promise<ClipCountsWithIndex | Record<string, number>>;
1302
+ getClipCountsCacheFirst(workspaceId: string, date: string, shiftId: string | number, buildIndex?: boolean, totalOutput?: number): Promise<ClipCountsWithIndex | Record<string, number>>;
1303
1303
  /**
1304
1304
  * Get clip counts (simplified version)
1305
1305
  */
1306
- getClipCounts(workspaceId: string, date: string, shiftId: string | number): Promise<Record<string, number>>;
1306
+ getClipCounts(workspaceId: string, date: string, shiftId: string | number, totalOutput?: number): Promise<Record<string, number>>;
1307
1307
  /**
1308
1308
  * Get clip by ID - stable navigation method
1309
1309
  * This ensures navigation works even when new clips are added
@@ -3257,7 +3257,7 @@ declare function useClipTypes(): UseClipTypesResult;
3257
3257
  /**
3258
3258
  * Hook to get clip types with counts for a specific workspace/date/shift
3259
3259
  */
3260
- declare function useClipTypesWithCounts(workspaceId: string, date: string, shiftId: string | number): UseClipTypesResult & {
3260
+ declare function useClipTypesWithCounts(workspaceId: string, date: string, shiftId: string | number, totalOutput?: number): UseClipTypesResult & {
3261
3261
  counts: Record<string, number>;
3262
3262
  };
3263
3263
 
@@ -5334,6 +5334,10 @@ interface BottlenecksContentProps {
5334
5334
  * Optional className for styling
5335
5335
  */
5336
5336
  className?: string;
5337
+ /**
5338
+ * Total output from workspace metrics for cycle completion adjustment
5339
+ */
5340
+ totalOutput?: number;
5337
5341
  }
5338
5342
  /**
5339
5343
  * Filter type for bottleneck clips - expanded for new video types
@@ -5959,6 +5963,8 @@ interface CroppedVideoPlayerProps extends VideoPlayerProps {
5959
5963
  crop?: CropConfig | null;
5960
5964
  /** Whether to show debug info */
5961
5965
  debug?: boolean;
5966
+ /** Optional click handler for the video container */
5967
+ onClick?: () => void;
5962
5968
  }
5963
5969
  /**
5964
5970
  * Video player with canvas-based cropping capability
package/dist/index.d.ts CHANGED
@@ -1299,11 +1299,11 @@ declare class S3ClipsSupabaseService {
1299
1299
  /**
1300
1300
  * Get clip counts with optional video index
1301
1301
  */
1302
- getClipCountsCacheFirst(workspaceId: string, date: string, shiftId: string | number, buildIndex?: boolean): Promise<ClipCountsWithIndex | Record<string, number>>;
1302
+ getClipCountsCacheFirst(workspaceId: string, date: string, shiftId: string | number, buildIndex?: boolean, totalOutput?: number): Promise<ClipCountsWithIndex | Record<string, number>>;
1303
1303
  /**
1304
1304
  * Get clip counts (simplified version)
1305
1305
  */
1306
- getClipCounts(workspaceId: string, date: string, shiftId: string | number): Promise<Record<string, number>>;
1306
+ getClipCounts(workspaceId: string, date: string, shiftId: string | number, totalOutput?: number): Promise<Record<string, number>>;
1307
1307
  /**
1308
1308
  * Get clip by ID - stable navigation method
1309
1309
  * This ensures navigation works even when new clips are added
@@ -3257,7 +3257,7 @@ declare function useClipTypes(): UseClipTypesResult;
3257
3257
  /**
3258
3258
  * Hook to get clip types with counts for a specific workspace/date/shift
3259
3259
  */
3260
- declare function useClipTypesWithCounts(workspaceId: string, date: string, shiftId: string | number): UseClipTypesResult & {
3260
+ declare function useClipTypesWithCounts(workspaceId: string, date: string, shiftId: string | number, totalOutput?: number): UseClipTypesResult & {
3261
3261
  counts: Record<string, number>;
3262
3262
  };
3263
3263
 
@@ -5334,6 +5334,10 @@ interface BottlenecksContentProps {
5334
5334
  * Optional className for styling
5335
5335
  */
5336
5336
  className?: string;
5337
+ /**
5338
+ * Total output from workspace metrics for cycle completion adjustment
5339
+ */
5340
+ totalOutput?: number;
5337
5341
  }
5338
5342
  /**
5339
5343
  * Filter type for bottleneck clips - expanded for new video types
@@ -5959,6 +5963,8 @@ interface CroppedVideoPlayerProps extends VideoPlayerProps {
5959
5963
  crop?: CropConfig | null;
5960
5964
  /** Whether to show debug info */
5961
5965
  debug?: boolean;
5966
+ /** Optional click handler for the video container */
5967
+ onClick?: () => void;
5962
5968
  }
5963
5969
  /**
5964
5970
  * Video player with canvas-based cropping capability
package/dist/index.js CHANGED
@@ -3765,7 +3765,7 @@ var S3ClipsSupabaseService = class {
3765
3765
  /**
3766
3766
  * Get clip counts with optional video index
3767
3767
  */
3768
- async getClipCountsCacheFirst(workspaceId, date, shiftId, buildIndex = false) {
3768
+ async getClipCountsCacheFirst(workspaceId, date, shiftId, buildIndex = false, totalOutput) {
3769
3769
  const cacheKey = `clip-counts:${workspaceId}:${date}:${shiftId}`;
3770
3770
  return this.deduplicate(cacheKey, async () => {
3771
3771
  console.log(`[S3ClipsSupabase] Fetching clip counts from Supabase for:`, {
@@ -3776,7 +3776,8 @@ var S3ClipsSupabaseService = class {
3776
3776
  const response = await this.fetchWithAuth("count", {
3777
3777
  workspaceId,
3778
3778
  date,
3779
- shift: shiftId.toString()
3779
+ shift: shiftId.toString(),
3780
+ totalOutput
3780
3781
  });
3781
3782
  console.log(`[S3ClipsSupabase] Count API response:`, response);
3782
3783
  const counts = response.counts || {};
@@ -3828,8 +3829,8 @@ var S3ClipsSupabaseService = class {
3828
3829
  /**
3829
3830
  * Get clip counts (simplified version)
3830
3831
  */
3831
- async getClipCounts(workspaceId, date, shiftId) {
3832
- const result = await this.getClipCountsCacheFirst(workspaceId, date, shiftId, false);
3832
+ async getClipCounts(workspaceId, date, shiftId, totalOutput) {
3833
+ const result = await this.getClipCountsCacheFirst(workspaceId, date, shiftId, false, totalOutput);
3833
3834
  if (typeof result === "object" && "counts" in result) {
3834
3835
  return result.counts;
3835
3836
  }
@@ -4053,7 +4054,7 @@ var S3ClipsSupabaseService = class {
4053
4054
  description: this.getDescriptionFromClipType(clip.clip_type_name),
4054
4055
  type: clip.clip_type_name,
4055
4056
  originalUri: `clips:${clip.clip_id}`,
4056
- cycle_time_seconds: clip.metadata?.request?.metadata?.cycle_time ? clip.metadata.request.metadata.cycle_time / 20 : void 0,
4057
+ cycle_time_seconds: clip.metadata?.request?.metadata?.cycle_time ? clip.metadata.request.metadata.cycle_time / (clip.metadata?.playlist?.fps || 20) : void 0,
4057
4058
  creation_timestamp: clip.created_at,
4058
4059
  percentile: clip.cycle_time_percentile || clip.idle_time_percentile
4059
4060
  }));
@@ -9020,7 +9021,7 @@ function useClipTypes() {
9020
9021
  refresh: fetchClipTypes
9021
9022
  };
9022
9023
  }
9023
- function useClipTypesWithCounts(workspaceId, date, shiftId) {
9024
+ function useClipTypesWithCounts(workspaceId, date, shiftId, totalOutput) {
9024
9025
  const { clipTypes, isLoading: typesLoading, error: typesError, refresh } = useClipTypes();
9025
9026
  const [counts, setCounts] = React21.useState({});
9026
9027
  const [countsLoading, setCountsLoading] = React21.useState(false);
@@ -9045,7 +9046,8 @@ function useClipTypesWithCounts(workspaceId, date, shiftId) {
9045
9046
  const clipCounts = await s3Service.getClipCounts(
9046
9047
  workspaceId,
9047
9048
  date,
9048
- shiftId.toString()
9049
+ shiftId.toString(),
9050
+ totalOutput
9049
9051
  );
9050
9052
  console.log("[useClipTypesWithCounts] Received counts:", clipCounts);
9051
9053
  setCounts(clipCounts);
@@ -9056,7 +9058,7 @@ function useClipTypesWithCounts(workspaceId, date, shiftId) {
9056
9058
  }
9057
9059
  };
9058
9060
  fetchCounts();
9059
- }, [s3Service, workspaceId, date, shiftId]);
9061
+ }, [s3Service, workspaceId, date, shiftId, totalOutput]);
9060
9062
  return {
9061
9063
  clipTypes: clipTypes.map((type) => ({
9062
9064
  ...type,
@@ -27633,6 +27635,7 @@ VideoPlayer.displayName = "VideoPlayer";
27633
27635
  var CroppedVideoPlayer = React21.forwardRef(({
27634
27636
  crop,
27635
27637
  debug = false,
27638
+ onClick,
27636
27639
  ...videoProps
27637
27640
  }, ref) => {
27638
27641
  const videoContainerRef = React21.useRef(null);
@@ -27650,7 +27653,9 @@ var CroppedVideoPlayer = React21.forwardRef(({
27650
27653
  }
27651
27654
  }, []);
27652
27655
  React21.useImperativeHandle(ref, () => ({
27653
- player: hiddenVideoRef.current?.player || null,
27656
+ get player() {
27657
+ return hiddenVideoRef.current?.player || null;
27658
+ },
27654
27659
  play: () => hiddenVideoRef.current?.play() || void 0,
27655
27660
  pause: () => hiddenVideoRef.current?.pause(),
27656
27661
  currentTime: (time2) => {
@@ -27667,7 +27672,9 @@ var CroppedVideoPlayer = React21.forwardRef(({
27667
27672
  hiddenVideoRef.current?.dispose();
27668
27673
  stopCanvasRendering();
27669
27674
  },
27670
- isReady: hiddenVideoRef.current?.isReady || false
27675
+ get isReady() {
27676
+ return hiddenVideoRef.current?.isReady || false;
27677
+ }
27671
27678
  }), [stopCanvasRendering]);
27672
27679
  const calculateCanvasDimensions = React21.useCallback(() => {
27673
27680
  if (!crop || !videoContainerRef.current) return;
@@ -27795,7 +27802,8 @@ var CroppedVideoPlayer = React21.forwardRef(({
27795
27802
  "div",
27796
27803
  {
27797
27804
  ref: videoContainerRef,
27798
- className: `relative w-full h-full flex items-center justify-center bg-black ${videoProps.className || ""}`,
27805
+ className: `relative w-full h-full flex items-center justify-center bg-black ${onClick ? "cursor-pointer" : ""} ${videoProps.className || ""}`,
27806
+ onClick,
27799
27807
  children: [
27800
27808
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
27801
27809
  VideoPlayer,
@@ -27824,9 +27832,7 @@ var CroppedVideoPlayer = React21.forwardRef(({
27824
27832
  style: {
27825
27833
  display: isVideoReady ? "block" : "none",
27826
27834
  width: `${canvasDimensions.width}px`,
27827
- height: `${canvasDimensions.height}px`,
27828
- pointerEvents: "none"
27829
- // Allow clicks to pass through to controls
27835
+ height: `${canvasDimensions.height}px`
27830
27836
  }
27831
27837
  }
27832
27838
  ),
@@ -28559,7 +28565,6 @@ var FileManagerFilters = ({
28559
28565
  hour12: false,
28560
28566
  hour: "2-digit",
28561
28567
  minute: "2-digit",
28562
- second: "2-digit",
28563
28568
  timeZone: timezone
28564
28569
  // Use database timezone for display
28565
28570
  });
@@ -29220,7 +29225,8 @@ var BottlenecksContent = ({
29220
29225
  workspaceName,
29221
29226
  date,
29222
29227
  shift,
29223
- className
29228
+ className,
29229
+ totalOutput
29224
29230
  }) => {
29225
29231
  const dashboardConfig = useDashboardConfig();
29226
29232
  const timezone = useAppTimezone();
@@ -29319,8 +29325,9 @@ var BottlenecksContent = ({
29319
29325
  } = useClipTypesWithCounts(
29320
29326
  workspaceId,
29321
29327
  date || getOperationalDate(timezone),
29322
- effectiveShift
29328
+ effectiveShift,
29323
29329
  // Use same shift as video loading for consistency
29330
+ totalOutput
29324
29331
  );
29325
29332
  console.log("[BottlenecksContent] Clip types data:", {
29326
29333
  clipTypes,
@@ -29365,8 +29372,9 @@ var BottlenecksContent = ({
29365
29372
  const fullResult = await s3ClipsService.getClipCounts(
29366
29373
  workspaceId,
29367
29374
  operationalDate,
29368
- shiftStr
29369
- // Don't build index - use pagination for cost efficiency
29375
+ shiftStr,
29376
+ totalOutput
29377
+ // Pass totalOutput for cycle completion adjustment
29370
29378
  );
29371
29379
  console.log(`[BottlenecksContent] Direct fetch result:`, fullResult);
29372
29380
  if (fullResult) {
@@ -30101,6 +30109,7 @@ var BottlenecksContent = ({
30101
30109
  src: currentVideo.src,
30102
30110
  className: "w-full h-full",
30103
30111
  crop: workspaceCrop?.crop || null,
30112
+ onClick: togglePlayback,
30104
30113
  autoplay: true,
30105
30114
  playsInline: true,
30106
30115
  loop: false,
@@ -30125,13 +30134,6 @@ var BottlenecksContent = ({
30125
30134
  ),
30126
30135
  (isTransitioning || isVideoBuffering && isInitialLoading) && /* @__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..." }) }),
30127
30136
  !isTransitioning && isVideoBuffering && !isInitialLoading && /* @__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..." }) }),
30128
- /* @__PURE__ */ jsxRuntime.jsx(
30129
- "div",
30130
- {
30131
- className: "absolute inset-0 z-10 cursor-pointer",
30132
- onClick: togglePlayback
30133
- }
30134
- ),
30135
30137
  error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center bg-black/80 text-white p-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center max-w-md", children: [
30136
30138
  /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-16 h-16 mx-auto mb-4 text-red-400", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.732-.833-2.5 0L4.268 16.5c-.77.833.192 2.5 1.732 2.5z" }) }),
30137
30139
  /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold mb-2", children: "Video Stream Error" }),
@@ -30177,7 +30179,10 @@ var BottlenecksContent = ({
30177
30179
  /* @__PURE__ */ jsxRuntime.jsx(
30178
30180
  "button",
30179
30181
  {
30180
- onClick: togglePlayback,
30182
+ onClick: (e) => {
30183
+ e.stopPropagation();
30184
+ togglePlayback();
30185
+ },
30181
30186
  className: "p-1.5 hover:bg-white/20 rounded-full focus:outline-none focus:ring-2 focus:ring-white/50",
30182
30187
  "aria-label": isPlaying ? "Pause" : "Play",
30183
30188
  children: isPlaying ? /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { fillRule: "evenodd", d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zM7 8a1 1 0 00-1 1v2a1 1 0 102 0V9a1 1 0 00-1-1zm5 0a1 1 0 00-1 1v2a1 1 0 102 0V9a1 1 0 00-1-1z", clipRule: "evenodd" }) }) : /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { fillRule: "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zM9.555 7.168A1 1 0 008 8.118l-.001 3.764a1 1 0 001.555.832l3.196-1.882a1 1 0 000-1.664l-3.196-1.882z", clipRule: "evenodd" }) })
@@ -42854,6 +42859,7 @@ var WorkspaceDetailView = ({
42854
42859
  workspaceName: formattedWorkspaceName,
42855
42860
  date,
42856
42861
  shift,
42862
+ totalOutput: workspace?.total_actions,
42857
42863
  className: "h-[calc(100vh-10rem)]"
42858
42864
  }
42859
42865
  ) })
package/dist/index.mjs CHANGED
@@ -3735,7 +3735,7 @@ var S3ClipsSupabaseService = class {
3735
3735
  /**
3736
3736
  * Get clip counts with optional video index
3737
3737
  */
3738
- async getClipCountsCacheFirst(workspaceId, date, shiftId, buildIndex = false) {
3738
+ async getClipCountsCacheFirst(workspaceId, date, shiftId, buildIndex = false, totalOutput) {
3739
3739
  const cacheKey = `clip-counts:${workspaceId}:${date}:${shiftId}`;
3740
3740
  return this.deduplicate(cacheKey, async () => {
3741
3741
  console.log(`[S3ClipsSupabase] Fetching clip counts from Supabase for:`, {
@@ -3746,7 +3746,8 @@ var S3ClipsSupabaseService = class {
3746
3746
  const response = await this.fetchWithAuth("count", {
3747
3747
  workspaceId,
3748
3748
  date,
3749
- shift: shiftId.toString()
3749
+ shift: shiftId.toString(),
3750
+ totalOutput
3750
3751
  });
3751
3752
  console.log(`[S3ClipsSupabase] Count API response:`, response);
3752
3753
  const counts = response.counts || {};
@@ -3798,8 +3799,8 @@ var S3ClipsSupabaseService = class {
3798
3799
  /**
3799
3800
  * Get clip counts (simplified version)
3800
3801
  */
3801
- async getClipCounts(workspaceId, date, shiftId) {
3802
- const result = await this.getClipCountsCacheFirst(workspaceId, date, shiftId, false);
3802
+ async getClipCounts(workspaceId, date, shiftId, totalOutput) {
3803
+ const result = await this.getClipCountsCacheFirst(workspaceId, date, shiftId, false, totalOutput);
3803
3804
  if (typeof result === "object" && "counts" in result) {
3804
3805
  return result.counts;
3805
3806
  }
@@ -4023,7 +4024,7 @@ var S3ClipsSupabaseService = class {
4023
4024
  description: this.getDescriptionFromClipType(clip.clip_type_name),
4024
4025
  type: clip.clip_type_name,
4025
4026
  originalUri: `clips:${clip.clip_id}`,
4026
- cycle_time_seconds: clip.metadata?.request?.metadata?.cycle_time ? clip.metadata.request.metadata.cycle_time / 20 : void 0,
4027
+ cycle_time_seconds: clip.metadata?.request?.metadata?.cycle_time ? clip.metadata.request.metadata.cycle_time / (clip.metadata?.playlist?.fps || 20) : void 0,
4027
4028
  creation_timestamp: clip.created_at,
4028
4029
  percentile: clip.cycle_time_percentile || clip.idle_time_percentile
4029
4030
  }));
@@ -8990,7 +8991,7 @@ function useClipTypes() {
8990
8991
  refresh: fetchClipTypes
8991
8992
  };
8992
8993
  }
8993
- function useClipTypesWithCounts(workspaceId, date, shiftId) {
8994
+ function useClipTypesWithCounts(workspaceId, date, shiftId, totalOutput) {
8994
8995
  const { clipTypes, isLoading: typesLoading, error: typesError, refresh } = useClipTypes();
8995
8996
  const [counts, setCounts] = useState({});
8996
8997
  const [countsLoading, setCountsLoading] = useState(false);
@@ -9015,7 +9016,8 @@ function useClipTypesWithCounts(workspaceId, date, shiftId) {
9015
9016
  const clipCounts = await s3Service.getClipCounts(
9016
9017
  workspaceId,
9017
9018
  date,
9018
- shiftId.toString()
9019
+ shiftId.toString(),
9020
+ totalOutput
9019
9021
  );
9020
9022
  console.log("[useClipTypesWithCounts] Received counts:", clipCounts);
9021
9023
  setCounts(clipCounts);
@@ -9026,7 +9028,7 @@ function useClipTypesWithCounts(workspaceId, date, shiftId) {
9026
9028
  }
9027
9029
  };
9028
9030
  fetchCounts();
9029
- }, [s3Service, workspaceId, date, shiftId]);
9031
+ }, [s3Service, workspaceId, date, shiftId, totalOutput]);
9030
9032
  return {
9031
9033
  clipTypes: clipTypes.map((type) => ({
9032
9034
  ...type,
@@ -27603,6 +27605,7 @@ VideoPlayer.displayName = "VideoPlayer";
27603
27605
  var CroppedVideoPlayer = forwardRef(({
27604
27606
  crop,
27605
27607
  debug = false,
27608
+ onClick,
27606
27609
  ...videoProps
27607
27610
  }, ref) => {
27608
27611
  const videoContainerRef = useRef(null);
@@ -27620,7 +27623,9 @@ var CroppedVideoPlayer = forwardRef(({
27620
27623
  }
27621
27624
  }, []);
27622
27625
  useImperativeHandle(ref, () => ({
27623
- player: hiddenVideoRef.current?.player || null,
27626
+ get player() {
27627
+ return hiddenVideoRef.current?.player || null;
27628
+ },
27624
27629
  play: () => hiddenVideoRef.current?.play() || void 0,
27625
27630
  pause: () => hiddenVideoRef.current?.pause(),
27626
27631
  currentTime: (time2) => {
@@ -27637,7 +27642,9 @@ var CroppedVideoPlayer = forwardRef(({
27637
27642
  hiddenVideoRef.current?.dispose();
27638
27643
  stopCanvasRendering();
27639
27644
  },
27640
- isReady: hiddenVideoRef.current?.isReady || false
27645
+ get isReady() {
27646
+ return hiddenVideoRef.current?.isReady || false;
27647
+ }
27641
27648
  }), [stopCanvasRendering]);
27642
27649
  const calculateCanvasDimensions = useCallback(() => {
27643
27650
  if (!crop || !videoContainerRef.current) return;
@@ -27765,7 +27772,8 @@ var CroppedVideoPlayer = forwardRef(({
27765
27772
  "div",
27766
27773
  {
27767
27774
  ref: videoContainerRef,
27768
- className: `relative w-full h-full flex items-center justify-center bg-black ${videoProps.className || ""}`,
27775
+ className: `relative w-full h-full flex items-center justify-center bg-black ${onClick ? "cursor-pointer" : ""} ${videoProps.className || ""}`,
27776
+ onClick,
27769
27777
  children: [
27770
27778
  /* @__PURE__ */ jsx("div", { className: "hidden", children: /* @__PURE__ */ jsx(
27771
27779
  VideoPlayer,
@@ -27794,9 +27802,7 @@ var CroppedVideoPlayer = forwardRef(({
27794
27802
  style: {
27795
27803
  display: isVideoReady ? "block" : "none",
27796
27804
  width: `${canvasDimensions.width}px`,
27797
- height: `${canvasDimensions.height}px`,
27798
- pointerEvents: "none"
27799
- // Allow clicks to pass through to controls
27805
+ height: `${canvasDimensions.height}px`
27800
27806
  }
27801
27807
  }
27802
27808
  ),
@@ -28529,7 +28535,6 @@ var FileManagerFilters = ({
28529
28535
  hour12: false,
28530
28536
  hour: "2-digit",
28531
28537
  minute: "2-digit",
28532
- second: "2-digit",
28533
28538
  timeZone: timezone
28534
28539
  // Use database timezone for display
28535
28540
  });
@@ -29190,7 +29195,8 @@ var BottlenecksContent = ({
29190
29195
  workspaceName,
29191
29196
  date,
29192
29197
  shift,
29193
- className
29198
+ className,
29199
+ totalOutput
29194
29200
  }) => {
29195
29201
  const dashboardConfig = useDashboardConfig();
29196
29202
  const timezone = useAppTimezone();
@@ -29289,8 +29295,9 @@ var BottlenecksContent = ({
29289
29295
  } = useClipTypesWithCounts(
29290
29296
  workspaceId,
29291
29297
  date || getOperationalDate(timezone),
29292
- effectiveShift
29298
+ effectiveShift,
29293
29299
  // Use same shift as video loading for consistency
29300
+ totalOutput
29294
29301
  );
29295
29302
  console.log("[BottlenecksContent] Clip types data:", {
29296
29303
  clipTypes,
@@ -29335,8 +29342,9 @@ var BottlenecksContent = ({
29335
29342
  const fullResult = await s3ClipsService.getClipCounts(
29336
29343
  workspaceId,
29337
29344
  operationalDate,
29338
- shiftStr
29339
- // Don't build index - use pagination for cost efficiency
29345
+ shiftStr,
29346
+ totalOutput
29347
+ // Pass totalOutput for cycle completion adjustment
29340
29348
  );
29341
29349
  console.log(`[BottlenecksContent] Direct fetch result:`, fullResult);
29342
29350
  if (fullResult) {
@@ -30071,6 +30079,7 @@ var BottlenecksContent = ({
30071
30079
  src: currentVideo.src,
30072
30080
  className: "w-full h-full",
30073
30081
  crop: workspaceCrop?.crop || null,
30082
+ onClick: togglePlayback,
30074
30083
  autoplay: true,
30075
30084
  playsInline: true,
30076
30085
  loop: false,
@@ -30095,13 +30104,6 @@ var BottlenecksContent = ({
30095
30104
  ),
30096
30105
  (isTransitioning || isVideoBuffering && isInitialLoading) && /* @__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..." }) }),
30097
30106
  !isTransitioning && isVideoBuffering && !isInitialLoading && /* @__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..." }) }),
30098
- /* @__PURE__ */ jsx(
30099
- "div",
30100
- {
30101
- className: "absolute inset-0 z-10 cursor-pointer",
30102
- onClick: togglePlayback
30103
- }
30104
- ),
30105
30107
  error && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center bg-black/80 text-white p-4", children: /* @__PURE__ */ jsxs("div", { className: "text-center max-w-md", children: [
30106
30108
  /* @__PURE__ */ jsx("svg", { className: "w-16 h-16 mx-auto mb-4 text-red-400", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.732-.833-2.5 0L4.268 16.5c-.77.833.192 2.5 1.732 2.5z" }) }),
30107
30109
  /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold mb-2", children: "Video Stream Error" }),
@@ -30147,7 +30149,10 @@ var BottlenecksContent = ({
30147
30149
  /* @__PURE__ */ jsx(
30148
30150
  "button",
30149
30151
  {
30150
- onClick: togglePlayback,
30152
+ onClick: (e) => {
30153
+ e.stopPropagation();
30154
+ togglePlayback();
30155
+ },
30151
30156
  className: "p-1.5 hover:bg-white/20 rounded-full focus:outline-none focus:ring-2 focus:ring-white/50",
30152
30157
  "aria-label": isPlaying ? "Pause" : "Play",
30153
30158
  children: isPlaying ? /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { fillRule: "evenodd", d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zM7 8a1 1 0 00-1 1v2a1 1 0 102 0V9a1 1 0 00-1-1zm5 0a1 1 0 00-1 1v2a1 1 0 102 0V9a1 1 0 00-1-1z", clipRule: "evenodd" }) }) : /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { fillRule: "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zM9.555 7.168A1 1 0 008 8.118l-.001 3.764a1 1 0 001.555.832l3.196-1.882a1 1 0 000-1.664l-3.196-1.882z", clipRule: "evenodd" }) })
@@ -42824,6 +42829,7 @@ var WorkspaceDetailView = ({
42824
42829
  workspaceName: formattedWorkspaceName,
42825
42830
  date,
42826
42831
  shift,
42832
+ totalOutput: workspace?.total_actions,
42827
42833
  className: "h-[calc(100vh-10rem)]"
42828
42834
  }
42829
42835
  ) })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optifye/dashboard-core",
3
- "version": "6.6.8",
3
+ "version": "6.6.10",
4
4
  "description": "Reusable UI & logic for Optifye dashboard",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",