@optifye/dashboard-core 6.3.3 → 6.3.5

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
@@ -394,11 +394,11 @@ var actionService = {
394
394
  };
395
395
  function createMemoizedFunction(fn, getCacheKey) {
396
396
  const cache = /* @__PURE__ */ new Map();
397
- const CACHE_DURATION3 = 5 * 60 * 1e3;
397
+ const CACHE_DURATION = 5 * 60 * 1e3;
398
398
  return (...args) => {
399
399
  const key = getCacheKey(...args);
400
400
  const cached = cache.get(key);
401
- if (cached && Date.now() - cached.timestamp < CACHE_DURATION3) {
401
+ if (cached && Date.now() - cached.timestamp < CACHE_DURATION) {
402
402
  return cached.result;
403
403
  }
404
404
  const result = fn(...args);
@@ -2449,199 +2449,6 @@ async function deleteThread(threadId) {
2449
2449
  if (error) throw error;
2450
2450
  }
2451
2451
 
2452
- // src/lib/services/cacheService.ts
2453
- var CacheService = class {
2454
- constructor() {
2455
- this.memoryCache = /* @__PURE__ */ new Map();
2456
- this.DEFAULT_DURATION = 5 * 60 * 1e3;
2457
- }
2458
- // 5 minutes
2459
- /**
2460
- * Generate a cache key from multiple parts
2461
- */
2462
- generateKey(...parts) {
2463
- return parts.filter((p) => p !== void 0 && p !== null).join(":");
2464
- }
2465
- /**
2466
- * Get item from cache
2467
- */
2468
- get(key, options) {
2469
- const storage = options?.storage || "memory";
2470
- try {
2471
- let cacheItem = null;
2472
- if (storage === "memory") {
2473
- cacheItem = this.memoryCache.get(key) || null;
2474
- } else if (storage === "localStorage" || storage === "sessionStorage") {
2475
- const stored = window[storage].getItem(key);
2476
- if (stored) {
2477
- cacheItem = JSON.parse(stored);
2478
- }
2479
- }
2480
- if (!cacheItem) {
2481
- return null;
2482
- }
2483
- if (Date.now() > cacheItem.expiresAt) {
2484
- this.delete(key, options);
2485
- return null;
2486
- }
2487
- return cacheItem.data;
2488
- } catch (error) {
2489
- console.error(`Error getting cache item ${key}:`, error);
2490
- return null;
2491
- }
2492
- }
2493
- /**
2494
- * Set item in cache
2495
- */
2496
- set(key, data, options) {
2497
- const storage = options?.storage || "memory";
2498
- const duration = options?.duration || this.DEFAULT_DURATION;
2499
- const cacheItem = {
2500
- data,
2501
- timestamp: Date.now(),
2502
- expiresAt: Date.now() + duration
2503
- };
2504
- try {
2505
- if (storage === "memory") {
2506
- this.memoryCache.set(key, cacheItem);
2507
- if (this.memoryCache.size > 100) {
2508
- const firstKey = this.memoryCache.keys().next().value;
2509
- if (firstKey) {
2510
- this.memoryCache.delete(firstKey);
2511
- }
2512
- }
2513
- } else if (storage === "localStorage" || storage === "sessionStorage") {
2514
- window[storage].setItem(key, JSON.stringify(cacheItem));
2515
- }
2516
- } catch (error) {
2517
- console.error(`Error setting cache item ${key}:`, error);
2518
- }
2519
- }
2520
- /**
2521
- * Delete item from cache
2522
- */
2523
- delete(key, options) {
2524
- const storage = options?.storage || "memory";
2525
- try {
2526
- if (storage === "memory") {
2527
- this.memoryCache.delete(key);
2528
- } else if (storage === "localStorage" || storage === "sessionStorage") {
2529
- window[storage].removeItem(key);
2530
- }
2531
- } catch (error) {
2532
- console.error(`Error deleting cache item ${key}:`, error);
2533
- }
2534
- }
2535
- /**
2536
- * Clear all items from cache
2537
- */
2538
- clear(options) {
2539
- const storage = options?.storage || "memory";
2540
- try {
2541
- if (storage === "memory") {
2542
- this.memoryCache.clear();
2543
- } else if (storage === "localStorage" || storage === "sessionStorage") {
2544
- const keys = Object.keys(window[storage]);
2545
- keys.forEach((key) => {
2546
- try {
2547
- const item = window[storage].getItem(key);
2548
- if (item) {
2549
- const parsed = JSON.parse(item);
2550
- if (parsed.timestamp && parsed.expiresAt && parsed.data !== void 0) {
2551
- window[storage].removeItem(key);
2552
- }
2553
- }
2554
- } catch {
2555
- }
2556
- });
2557
- }
2558
- } catch (error) {
2559
- console.error("Error clearing cache:", error);
2560
- }
2561
- }
2562
- /**
2563
- * Get or set item in cache with a factory function
2564
- */
2565
- async getOrSet(key, factory, options) {
2566
- const cached = this.get(key, options);
2567
- if (cached !== null) {
2568
- return cached;
2569
- }
2570
- const data = await factory();
2571
- this.set(key, data, options);
2572
- return data;
2573
- }
2574
- /**
2575
- * Invalidate cache entries matching a pattern
2576
- */
2577
- invalidatePattern(pattern, options) {
2578
- const storage = options?.storage || "memory";
2579
- const regex = typeof pattern === "string" ? new RegExp(pattern) : pattern;
2580
- try {
2581
- if (storage === "memory") {
2582
- const keysToDelete = [];
2583
- this.memoryCache.forEach((_, key) => {
2584
- if (regex.test(key)) {
2585
- keysToDelete.push(key);
2586
- }
2587
- });
2588
- keysToDelete.forEach((key) => this.memoryCache.delete(key));
2589
- } else if (storage === "localStorage" || storage === "sessionStorage") {
2590
- const keys = Object.keys(window[storage]);
2591
- keys.forEach((key) => {
2592
- if (regex.test(key)) {
2593
- window[storage].removeItem(key);
2594
- }
2595
- });
2596
- }
2597
- } catch (error) {
2598
- console.error("Error invalidating cache pattern:", error);
2599
- }
2600
- }
2601
- /**
2602
- * Clean up expired items
2603
- */
2604
- cleanup(options) {
2605
- const storage = options?.storage || "memory";
2606
- const now2 = Date.now();
2607
- try {
2608
- if (storage === "memory") {
2609
- const keysToDelete = [];
2610
- this.memoryCache.forEach((item, key) => {
2611
- if (now2 > item.expiresAt) {
2612
- keysToDelete.push(key);
2613
- }
2614
- });
2615
- keysToDelete.forEach((key) => this.memoryCache.delete(key));
2616
- } else if (storage === "localStorage" || storage === "sessionStorage") {
2617
- const keys = Object.keys(window[storage]);
2618
- keys.forEach((key) => {
2619
- try {
2620
- const item = window[storage].getItem(key);
2621
- if (item) {
2622
- const parsed = JSON.parse(item);
2623
- if (parsed.expiresAt && now2 > parsed.expiresAt) {
2624
- window[storage].removeItem(key);
2625
- }
2626
- }
2627
- } catch {
2628
- }
2629
- });
2630
- }
2631
- } catch (error) {
2632
- console.error("Error cleaning up cache:", error);
2633
- }
2634
- }
2635
- };
2636
- var cacheService = new CacheService();
2637
- if (typeof window !== "undefined") {
2638
- setInterval(() => {
2639
- cacheService.cleanup({ storage: "localStorage" });
2640
- cacheService.cleanup({ storage: "sessionStorage" });
2641
- cacheService.cleanup({ storage: "memory" });
2642
- }, 60 * 1e3);
2643
- }
2644
-
2645
2452
  // src/lib/services/subscriptionManager.ts
2646
2453
  var SubscriptionManager = class {
2647
2454
  constructor(supabase) {
@@ -3970,6 +3777,8 @@ var S3ClipsService = class {
3970
3777
  constructor(config) {
3971
3778
  // Request deduplication cache
3972
3779
  this.requestCache = new RequestDeduplicationCache();
3780
+ // Flag to prevent metadata fetching during index building
3781
+ this.isIndexBuilding = false;
3973
3782
  this.config = config;
3974
3783
  if (!config.s3Config) {
3975
3784
  throw new Error("S3 configuration is required");
@@ -4121,6 +3930,10 @@ var S3ClipsService = class {
4121
3930
  * Fetches full metadata including timestamps with deduplication
4122
3931
  */
4123
3932
  async getFullMetadata(playlistUri) {
3933
+ if (this.isIndexBuilding) {
3934
+ console.warn(`[S3ClipsService] Skipping metadata fetch during index building for: ${playlistUri}`);
3935
+ return null;
3936
+ }
4124
3937
  const deduplicationKey = `full-metadata:${playlistUri}`;
4125
3938
  return this.requestCache.deduplicate(
4126
3939
  deduplicationKey,
@@ -4187,141 +4000,152 @@ var S3ClipsService = class {
4187
4000
  * Internal implementation of clip counts fetching
4188
4001
  */
4189
4002
  async executeGetClipCounts(workspaceId, date, shiftId, buildIndex) {
4190
- const basePrefix = `sop_violations/${workspaceId}/${date}/${shiftId}/`;
4191
- const counts = { total: 0 };
4192
- const categoryFolders = [
4193
- "idle_time",
4194
- "low_value",
4195
- "sop_deviation",
4196
- "missing_quality_check",
4197
- "best_cycle_time",
4198
- "worst_cycle_time",
4199
- "long_cycle_time",
4200
- "cycle_completion",
4201
- "bottleneck"
4202
- ];
4203
- console.log(`[S3ClipsService] ${buildIndex ? "Building video index and counting" : "Fast counting"} clips for ${workspaceId} on ${date}, shift ${shiftId}`);
4204
- const startTime = performance.now();
4205
- const videoIndex = buildIndex ? {
4206
- byCategory: /* @__PURE__ */ new Map(),
4207
- allVideos: [],
4208
- counts: {},
4209
- workspaceId,
4210
- date,
4211
- shiftId: shiftId.toString(),
4212
- lastUpdated: /* @__PURE__ */ new Date(),
4213
- _debugId: `vid_${Date.now()}_${Math.random().toString(36).substring(7)}`
4214
- } : null;
4215
- const countPromises = categoryFolders.map(async (category) => {
4216
- const categoryPrefix = `${basePrefix}${category}/videos/`;
4217
- const categoryVideos = [];
4218
- try {
4219
- if (buildIndex) {
4220
- const command = new ListObjectsV2Command({
4221
- Bucket: this.config.s3Config.bucketName,
4222
- Prefix: categoryPrefix,
4223
- MaxKeys: 1e3
4224
- });
4225
- let continuationToken;
4226
- do {
4227
- if (continuationToken) {
4228
- command.input.ContinuationToken = continuationToken;
4229
- }
4230
- const response = await this.s3Client.send(command);
4231
- if (response.Contents) {
4232
- for (const obj of response.Contents) {
4233
- if (obj.Key && obj.Key.endsWith("playlist.m3u8")) {
4234
- if (obj.Key.includes("missed_qchecks")) {
4235
- continue;
4236
- }
4237
- const s3Uri = `s3://${this.config.s3Config.bucketName}/${obj.Key}`;
4238
- const sopCategories = this.getSOPCategories(workspaceId);
4239
- const parsedInfo = parseS3Uri(s3Uri, sopCategories);
4240
- const belongsToCategory = parsedInfo && (parsedInfo.type === category || // Handle specific mismatches between folder names and parsed types
4241
- category === "cycle_completion" && parsedInfo.type === "cycle_completion" || category === "sop_deviation" && parsedInfo.type === "missing_quality_check" || category === "missing_quality_check" && parsedInfo.type === "missing_quality_check" || category === "idle_time" && parsedInfo.type === "low_value" || category === "low_value" && parsedInfo.type === "low_value");
4242
- if (belongsToCategory) {
4243
- const videoEntry = {
4244
- uri: s3Uri,
4245
- category: parsedInfo.type,
4246
- // Use the parsed type, not the folder name
4247
- timestamp: parsedInfo.timestamp,
4248
- videoId: `${workspaceId}-${parsedInfo.timestamp}`,
4249
- workspaceId,
4250
- date,
4251
- shiftId: shiftId.toString()
4252
- };
4253
- categoryVideos.push(videoEntry);
4003
+ if (buildIndex) {
4004
+ this.isIndexBuilding = true;
4005
+ console.log(`[S3ClipsService] Starting index building - metadata fetching disabled`);
4006
+ }
4007
+ try {
4008
+ const basePrefix = `sop_violations/${workspaceId}/${date}/${shiftId}/`;
4009
+ const counts = { total: 0 };
4010
+ const categoryFolders = [
4011
+ "idle_time",
4012
+ "low_value",
4013
+ "sop_deviation",
4014
+ "missing_quality_check",
4015
+ "best_cycle_time",
4016
+ "worst_cycle_time",
4017
+ "long_cycle_time",
4018
+ "cycle_completion",
4019
+ "bottleneck"
4020
+ ];
4021
+ console.log(`[S3ClipsService] ${buildIndex ? "Building video index and counting" : "Fast counting"} clips for ${workspaceId} on ${date}, shift ${shiftId}`);
4022
+ const startTime = performance.now();
4023
+ const videoIndex = buildIndex ? {
4024
+ byCategory: /* @__PURE__ */ new Map(),
4025
+ allVideos: [],
4026
+ counts: {},
4027
+ workspaceId,
4028
+ date,
4029
+ shiftId: shiftId.toString(),
4030
+ lastUpdated: /* @__PURE__ */ new Date(),
4031
+ _debugId: `vid_${Date.now()}_${Math.random().toString(36).substring(7)}`
4032
+ } : null;
4033
+ const countPromises = categoryFolders.map(async (category) => {
4034
+ const categoryPrefix = `${basePrefix}${category}/videos/`;
4035
+ const categoryVideos = [];
4036
+ try {
4037
+ if (buildIndex) {
4038
+ const command = new ListObjectsV2Command({
4039
+ Bucket: this.config.s3Config.bucketName,
4040
+ Prefix: categoryPrefix,
4041
+ MaxKeys: 1e3
4042
+ });
4043
+ let continuationToken;
4044
+ do {
4045
+ if (continuationToken) {
4046
+ command.input.ContinuationToken = continuationToken;
4047
+ }
4048
+ const response = await this.s3Client.send(command);
4049
+ if (response.Contents) {
4050
+ for (const obj of response.Contents) {
4051
+ if (obj.Key && obj.Key.endsWith("playlist.m3u8")) {
4052
+ if (obj.Key.includes("missed_qchecks")) {
4053
+ continue;
4054
+ }
4055
+ const s3Uri = `s3://${this.config.s3Config.bucketName}/${obj.Key}`;
4056
+ const sopCategories = this.getSOPCategories(workspaceId);
4057
+ const parsedInfo = parseS3Uri(s3Uri, sopCategories);
4058
+ const belongsToCategory = parsedInfo && (parsedInfo.type === category || // Handle specific mismatches between folder names and parsed types
4059
+ category === "cycle_completion" && parsedInfo.type === "cycle_completion" || category === "sop_deviation" && parsedInfo.type === "missing_quality_check" || category === "missing_quality_check" && parsedInfo.type === "missing_quality_check" || category === "idle_time" && parsedInfo.type === "low_value" || category === "low_value" && parsedInfo.type === "low_value");
4060
+ if (belongsToCategory) {
4061
+ const videoEntry = {
4062
+ uri: s3Uri,
4063
+ category: parsedInfo.type,
4064
+ // Use the parsed type, not the folder name
4065
+ timestamp: parsedInfo.timestamp,
4066
+ videoId: `${workspaceId}-${parsedInfo.timestamp}`,
4067
+ workspaceId,
4068
+ date,
4069
+ shiftId: shiftId.toString()
4070
+ };
4071
+ categoryVideos.push(videoEntry);
4072
+ }
4254
4073
  }
4255
4074
  }
4256
4075
  }
4076
+ continuationToken = response.NextContinuationToken;
4077
+ } while (continuationToken);
4078
+ categoryVideos.sort((a, b) => b.timestamp.localeCompare(a.timestamp));
4079
+ if (categoryVideos.length > 0) {
4080
+ console.log(`[S3ClipsService] Found ${categoryVideos.length} videos for category '${category}' (parsed types: ${[...new Set(categoryVideos.map((v) => v.category))].join(", ")})`);
4257
4081
  }
4258
- continuationToken = response.NextContinuationToken;
4259
- } while (continuationToken);
4260
- categoryVideos.sort((a, b) => b.timestamp.localeCompare(a.timestamp));
4261
- if (categoryVideos.length > 0) {
4262
- console.log(`[S3ClipsService] Found ${categoryVideos.length} videos for category '${category}' (parsed types: ${[...new Set(categoryVideos.map((v) => v.category))].join(", ")})`);
4082
+ return { category, count: categoryVideos.length, videos: categoryVideos };
4083
+ } else {
4084
+ const command = new ListObjectsV2Command({
4085
+ Bucket: this.config.s3Config.bucketName,
4086
+ Prefix: categoryPrefix,
4087
+ Delimiter: "/",
4088
+ MaxKeys: 1e3
4089
+ });
4090
+ let folderCount = 0;
4091
+ let continuationToken;
4092
+ do {
4093
+ if (continuationToken) {
4094
+ command.input.ContinuationToken = continuationToken;
4095
+ }
4096
+ const response = await this.s3Client.send(command);
4097
+ if (response.CommonPrefixes) {
4098
+ folderCount += response.CommonPrefixes.length;
4099
+ }
4100
+ continuationToken = response.NextContinuationToken;
4101
+ } while (continuationToken);
4102
+ return { category, count: folderCount, videos: [] };
4263
4103
  }
4264
- return { category, count: categoryVideos.length, videos: categoryVideos };
4265
- } else {
4266
- const command = new ListObjectsV2Command({
4267
- Bucket: this.config.s3Config.bucketName,
4268
- Prefix: categoryPrefix,
4269
- Delimiter: "/",
4270
- MaxKeys: 1e3
4271
- });
4272
- let folderCount = 0;
4273
- let continuationToken;
4274
- do {
4275
- if (continuationToken) {
4276
- command.input.ContinuationToken = continuationToken;
4277
- }
4278
- const response = await this.s3Client.send(command);
4279
- if (response.CommonPrefixes) {
4280
- folderCount += response.CommonPrefixes.length;
4104
+ } catch (error) {
4105
+ console.error(`Error ${buildIndex ? "building index for" : "counting folders for"} category ${category}:`, error);
4106
+ return { category, count: 0, videos: [] };
4107
+ }
4108
+ });
4109
+ const results = await Promise.all(countPromises);
4110
+ for (const { category, count, videos } of results) {
4111
+ counts[category] = count;
4112
+ counts.total += count;
4113
+ if (buildIndex && videoIndex && videos) {
4114
+ if (videos.length > 0) {
4115
+ const parsedType = videos[0].category;
4116
+ videoIndex.byCategory.set(parsedType, videos);
4117
+ console.log(`[S3ClipsService] Indexed ${videos.length} videos under parsed type '${parsedType}'`);
4118
+ if (category !== parsedType) {
4119
+ videoIndex.byCategory.set(category, videos);
4120
+ console.log(`[S3ClipsService] Created alias: S3 folder '${category}' -> parsed type '${parsedType}' (${videos.length} videos)`);
4281
4121
  }
4282
- continuationToken = response.NextContinuationToken;
4283
- } while (continuationToken);
4284
- return { category, count: folderCount, videos: [] };
4122
+ }
4123
+ videoIndex.allVideos.push(...videos);
4285
4124
  }
4286
- } catch (error) {
4287
- console.error(`Error ${buildIndex ? "building index for" : "counting folders for"} category ${category}:`, error);
4288
- return { category, count: 0, videos: [] };
4289
4125
  }
4290
- });
4291
- const results = await Promise.all(countPromises);
4292
- for (const { category, count, videos } of results) {
4293
- counts[category] = count;
4294
- counts.total += count;
4295
- if (buildIndex && videoIndex && videos) {
4296
- if (videos.length > 0) {
4297
- const parsedType = videos[0].category;
4298
- videoIndex.byCategory.set(parsedType, videos);
4299
- console.log(`[S3ClipsService] Indexed ${videos.length} videos under parsed type '${parsedType}'`);
4300
- if (category !== parsedType) {
4301
- videoIndex.byCategory.set(category, videos);
4302
- console.log(`[S3ClipsService] Created alias: S3 folder '${category}' -> parsed type '${parsedType}' (${videos.length} videos)`);
4303
- }
4126
+ if (buildIndex && videoIndex) {
4127
+ videoIndex.allVideos.sort((a, b) => b.timestamp.localeCompare(a.timestamp));
4128
+ videoIndex.counts = { ...counts };
4129
+ }
4130
+ const elapsed = performance.now() - startTime;
4131
+ console.log(`[S3ClipsService] ${buildIndex ? "Video index and counts" : "Clip counts"} completed in ${elapsed.toFixed(2)}ms - Total: ${counts.total}`);
4132
+ if (buildIndex && videoIndex) {
4133
+ console.log(`[S3ClipsService] Final video index summary:`);
4134
+ console.log(` - VideoIndex ID: ${videoIndex._debugId}`);
4135
+ console.log(` - Total videos in allVideos: ${videoIndex.allVideos.length}`);
4136
+ console.log(` - Categories in byCategory Map: ${Array.from(videoIndex.byCategory.keys()).join(", ")}`);
4137
+ for (const [cat, vids] of videoIndex.byCategory.entries()) {
4138
+ console.log(` - '${cat}': ${vids.length} videos`);
4304
4139
  }
4305
- videoIndex.allVideos.push(...videos);
4140
+ return { counts, videoIndex };
4306
4141
  }
4307
- }
4308
- if (buildIndex && videoIndex) {
4309
- videoIndex.allVideos.sort((a, b) => b.timestamp.localeCompare(a.timestamp));
4310
- videoIndex.counts = { ...counts };
4311
- }
4312
- const elapsed = performance.now() - startTime;
4313
- console.log(`[S3ClipsService] ${buildIndex ? "Video index and counts" : "Clip counts"} completed in ${elapsed.toFixed(2)}ms - Total: ${counts.total}`);
4314
- if (buildIndex && videoIndex) {
4315
- console.log(`[S3ClipsService] Final video index summary:`);
4316
- console.log(` - VideoIndex ID: ${videoIndex._debugId}`);
4317
- console.log(` - Total videos in allVideos: ${videoIndex.allVideos.length}`);
4318
- console.log(` - Categories in byCategory Map: ${Array.from(videoIndex.byCategory.keys()).join(", ")}`);
4319
- for (const [cat, vids] of videoIndex.byCategory.entries()) {
4320
- console.log(` - '${cat}': ${vids.length} videos`);
4142
+ return counts;
4143
+ } finally {
4144
+ if (buildIndex) {
4145
+ this.isIndexBuilding = false;
4146
+ console.log(`[S3ClipsService] Index building complete - metadata fetching re-enabled`);
4321
4147
  }
4322
- return { counts, videoIndex };
4323
4148
  }
4324
- return counts;
4325
4149
  }
4326
4150
  async getClipCountsCacheFirst(workspaceId, date, shiftId, buildIndex) {
4327
4151
  const cacheKey = `clip-counts:${workspaceId}:${date}:${shiftId}`;
@@ -4415,18 +4239,18 @@ var S3ClipsService = class {
4415
4239
  * Get a specific clip by index for a category with deduplication
4416
4240
  * @deprecated Use getVideoFromIndex with a pre-built VideoIndex for better performance
4417
4241
  */
4418
- async getClipByIndex(workspaceId, date, shiftId, category, index) {
4419
- const deduplicationKey = `clip-by-index:${workspaceId}:${date}:${shiftId}:${category}:${index}`;
4242
+ async getClipByIndex(workspaceId, date, shiftId, category, index, includeCycleTime = true, includeMetadata = false) {
4243
+ const deduplicationKey = `clip-by-index:${workspaceId}:${date}:${shiftId}:${category}:${index}:${includeCycleTime}:${includeMetadata}`;
4420
4244
  return this.requestCache.deduplicate(
4421
4245
  deduplicationKey,
4422
- () => this.executeGetClipByIndex(workspaceId, date, shiftId, category, index),
4246
+ () => this.executeGetClipByIndex(workspaceId, date, shiftId, category, index, includeCycleTime, includeMetadata),
4423
4247
  "ClipByIndex"
4424
4248
  );
4425
4249
  }
4426
4250
  /**
4427
4251
  * Internal implementation of clip by index fetching
4428
4252
  */
4429
- async executeGetClipByIndex(workspaceId, date, shiftId, category, index) {
4253
+ async executeGetClipByIndex(workspaceId, date, shiftId, category, index, includeCycleTime = true, includeMetadata = false) {
4430
4254
  const categoryPrefix = `sop_violations/${workspaceId}/${date}/${shiftId}/${category}/videos/`;
4431
4255
  try {
4432
4256
  const command = new ListObjectsV2Command({
@@ -4464,10 +4288,8 @@ var S3ClipsService = class {
4464
4288
  workspaceId,
4465
4289
  date,
4466
4290
  shiftId.toString(),
4467
- true,
4468
- // includeCycleTime
4469
- true
4470
- // includeMetadata
4291
+ includeCycleTime,
4292
+ includeMetadata
4471
4293
  );
4472
4294
  }
4473
4295
  } catch (error) {
@@ -4538,7 +4360,7 @@ var S3ClipsService = class {
4538
4360
  }
4539
4361
  let cycleTimeSeconds = null;
4540
4362
  let creationTimestamp = void 0;
4541
- if (includeMetadata || includeCycleTime && (parsedInfo.type === "bottleneck" && parsedInfo.description.toLowerCase().includes("cycle time") || parsedInfo.type === "best_cycle_time" || parsedInfo.type === "worst_cycle_time" || parsedInfo.type === "cycle_completion")) {
4363
+ if (includeMetadata) {
4542
4364
  const metadata = await this.getFullMetadata(uri);
4543
4365
  if (metadata) {
4544
4366
  if (metadata.original_task_metadata?.cycle_time) {
@@ -4546,6 +4368,8 @@ var S3ClipsService = class {
4546
4368
  }
4547
4369
  creationTimestamp = metadata.upload_timestamp || metadata.original_task_metadata?.timestamp || metadata.creation_timestamp || metadata[""];
4548
4370
  }
4371
+ } else if (includeCycleTime && (parsedInfo.type === "bottleneck" && parsedInfo.description.toLowerCase().includes("cycle time") || parsedInfo.type === "best_cycle_time" || parsedInfo.type === "worst_cycle_time" || parsedInfo.type === "cycle_completion")) {
4372
+ cycleTimeSeconds = null;
4549
4373
  }
4550
4374
  const cloudfrontPlaylistUrl = this.s3UriToCloudfront(uri);
4551
4375
  const { type: videoType, timestamp: videoTimestamp } = parsedInfo;
@@ -5567,7 +5391,6 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
5567
5391
  const [error, setError] = useState(null);
5568
5392
  const updateQueueRef = useRef(false);
5569
5393
  const isFetchingRef = useRef(false);
5570
- const timeoutRef = useRef(null);
5571
5394
  const channelRef = useRef(null);
5572
5395
  const schema = databaseConfig.schema ?? "public";
5573
5396
  const companyId = entityConfig.companyId || "";
@@ -5576,7 +5399,7 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
5576
5399
  const defaultTimezone = dateTimeConfig.defaultTimezone;
5577
5400
  const workspaceMetricsBaseTable = databaseConfig.tables?.workspaces ?? "workspace_metrics";
5578
5401
  const workspaceActionsTable = databaseConfig.tables?.actions ?? "workspace_actions";
5579
- const fetchMetrics = useCallback(async (skipCache = false) => {
5402
+ const fetchMetrics = useCallback(async () => {
5580
5403
  if (!workspaceId || isFetchingRef.current) return;
5581
5404
  try {
5582
5405
  isFetchingRef.current = true;
@@ -5585,28 +5408,6 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
5585
5408
  const queryShiftId = shiftId !== void 0 ? shiftId : currentShift.shiftId;
5586
5409
  console.log("[useWorkspaceDetailedMetrics] Using shift ID:", queryShiftId, "from input shift:", shiftId);
5587
5410
  console.log("[useWorkspaceDetailedMetrics] Using date:", queryDate, "from input date:", date);
5588
- const cacheKey = cacheService.generateKey(
5589
- "workspace-detailed-metrics",
5590
- workspaceId,
5591
- queryDate,
5592
- queryShiftId,
5593
- companyId
5594
- );
5595
- if (!skipCache) {
5596
- const cachedData = cacheService.get(cacheKey, {
5597
- storage: "memory",
5598
- duration: 5 * 60 * 1e3
5599
- // 5 minutes
5600
- });
5601
- if (cachedData) {
5602
- console.log("[useWorkspaceDetailedMetrics] Using cached data for:", cacheKey);
5603
- setMetrics(cachedData);
5604
- setIsLoading(false);
5605
- updateQueueRef.current = false;
5606
- isFetchingRef.current = false;
5607
- return;
5608
- }
5609
- }
5610
5411
  console.log(`[useWorkspaceDetailedMetrics] Querying ${metricsTable} for workspace: ${workspaceId}, date: ${queryDate}, shift: ${queryShiftId}`);
5611
5412
  const { data, error: fetchError } = await supabase.from(metricsTable).select("*").eq("workspace_id", workspaceId).eq("date", queryDate).eq("shift_id", queryShiftId).maybeSingle();
5612
5413
  if (fetchError) throw fetchError;
@@ -5709,18 +5510,6 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
5709
5510
  setIsLoading(false);
5710
5511
  updateQueueRef.current = false;
5711
5512
  isFetchingRef.current = false;
5712
- const fallbackCacheKey = cacheService.generateKey(
5713
- "workspace-detailed-metrics",
5714
- workspaceId,
5715
- recentData.date,
5716
- recentData.shift_id,
5717
- companyId
5718
- );
5719
- cacheService.set(fallbackCacheKey, transformedData2, {
5720
- storage: "memory",
5721
- duration: 2 * 60 * 1e3
5722
- // 2 minutes for fallback data
5723
- });
5724
5513
  return;
5725
5514
  } else {
5726
5515
  console.warn("[useWorkspaceDetailedMetrics] No data found for workspace:", workspaceId, "at all");
@@ -5834,11 +5623,6 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
5834
5623
  ...data.sop_check !== void 0 && { sop_check: data.sop_check }
5835
5624
  };
5836
5625
  setMetrics(transformedData);
5837
- cacheService.set(cacheKey, transformedData, {
5838
- storage: "memory",
5839
- duration: 5 * 60 * 1e3
5840
- // 5 minutes
5841
- });
5842
5626
  } catch (err) {
5843
5627
  console.error("Error fetching workspace metrics:", err);
5844
5628
  setError({ message: err.message, code: err.code });
@@ -5851,12 +5635,7 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
5851
5635
  const queueUpdate = useCallback(() => {
5852
5636
  if (!workspaceId || updateQueueRef.current) return;
5853
5637
  updateQueueRef.current = true;
5854
- if (timeoutRef.current) {
5855
- clearTimeout(timeoutRef.current);
5856
- }
5857
- timeoutRef.current = setTimeout(() => {
5858
- fetchMetrics();
5859
- }, 500);
5638
+ fetchMetrics();
5860
5639
  }, [fetchMetrics, workspaceId]);
5861
5640
  const setupSubscription = useCallback(() => {
5862
5641
  if (!workspaceId) return;
@@ -5873,7 +5652,7 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
5873
5652
  },
5874
5653
  async (payload) => {
5875
5654
  console.log(`Received ${metricsTablePrefix} update:`, payload);
5876
- await fetchMetrics(true);
5655
+ await fetchMetrics();
5877
5656
  }
5878
5657
  ).subscribe((status) => {
5879
5658
  console.log(`Workspace detailed metrics subscription status:`, status);
@@ -5907,14 +5686,6 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
5907
5686
  matches: payloadData?.date === operationalDate && payloadData?.shift_id === queryShiftId
5908
5687
  });
5909
5688
  if (payloadData?.date === operationalDate && payloadData?.shift_id === queryShiftId) {
5910
- const cacheKey = cacheService.generateKey(
5911
- "workspace-detailed-metrics",
5912
- workspaceId,
5913
- operationalDate,
5914
- queryShiftId,
5915
- companyId
5916
- );
5917
- cacheService.delete(cacheKey, { storage: "memory" });
5918
5689
  queueUpdate();
5919
5690
  }
5920
5691
  }
@@ -5940,14 +5711,6 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
5940
5711
  matches: payloadData?.date === operationalDate && payloadData?.shift_id === queryShiftId
5941
5712
  });
5942
5713
  if (payloadData?.date === operationalDate && payloadData?.shift_id === queryShiftId) {
5943
- const cacheKey = cacheService.generateKey(
5944
- "workspace-detailed-metrics",
5945
- workspaceId,
5946
- operationalDate,
5947
- queryShiftId,
5948
- companyId
5949
- );
5950
- cacheService.delete(cacheKey, { storage: "memory" });
5951
5714
  queueUpdate();
5952
5715
  }
5953
5716
  }
@@ -5973,14 +5736,6 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
5973
5736
  matches: payloadData?.date === operationalDate && payloadData?.shift_id === queryShiftId
5974
5737
  });
5975
5738
  if (payloadData?.date === operationalDate && payloadData?.shift_id === queryShiftId) {
5976
- const cacheKey = cacheService.generateKey(
5977
- "workspace-detailed-metrics",
5978
- workspaceId,
5979
- operationalDate,
5980
- queryShiftId,
5981
- companyId
5982
- );
5983
- cacheService.delete(cacheKey, { storage: "memory" });
5984
5739
  queueUpdate();
5985
5740
  }
5986
5741
  }
@@ -5991,9 +5746,6 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
5991
5746
  fetchMetrics();
5992
5747
  setupSubscription();
5993
5748
  return () => {
5994
- if (timeoutRef.current) {
5995
- clearTimeout(timeoutRef.current);
5996
- }
5997
5749
  channels.forEach((channel) => {
5998
5750
  console.log("Cleaning up channel subscription");
5999
5751
  supabase.removeChannel(channel);
@@ -6007,7 +5759,7 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
6007
5759
  metrics: metrics2,
6008
5760
  isLoading,
6009
5761
  error,
6010
- refetch: () => fetchMetrics(true)
5762
+ refetch: () => fetchMetrics()
6011
5763
  // Force refresh without cache
6012
5764
  };
6013
5765
  };
@@ -6452,33 +6204,6 @@ var useLeaderboardMetrics = (lineId, topCount = 10) => {
6452
6204
  refetch: fetchLeaderboardData
6453
6205
  };
6454
6206
  };
6455
- var CACHE_KEY_PREFIX = "dashboard_metrics_cache_";
6456
- var CACHE_DURATION = 5 * 60 * 1e3;
6457
- var getCache = (lineId) => {
6458
- if (typeof window === "undefined") return null;
6459
- try {
6460
- const cached = localStorage.getItem(`${CACHE_KEY_PREFIX}${lineId}`);
6461
- if (!cached) return null;
6462
- const parsedCache = JSON.parse(cached);
6463
- if (!parsedCache.lastUpdated || Date.now() - parsedCache.lastUpdated > CACHE_DURATION) {
6464
- localStorage.removeItem(`${CACHE_KEY_PREFIX}${lineId}`);
6465
- return null;
6466
- }
6467
- return parsedCache;
6468
- } catch {
6469
- return null;
6470
- }
6471
- };
6472
- var setCache = (lineId, metrics2) => {
6473
- if (typeof window === "undefined") return;
6474
- try {
6475
- localStorage.setItem(`${CACHE_KEY_PREFIX}${lineId}`, JSON.stringify({
6476
- ...metrics2,
6477
- lastUpdated: Date.now()
6478
- }));
6479
- } catch {
6480
- }
6481
- };
6482
6207
  var useDashboardMetrics = ({ onLineMetricsUpdate, lineId }) => {
6483
6208
  const { supabaseUrl, supabaseKey } = useDashboardConfig();
6484
6209
  const entityConfig = useEntityConfig();
@@ -6489,22 +6214,20 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId }) => {
6489
6214
  const configuredLineMetricsTable = databaseConfig?.tables?.lineMetrics ?? "line_metrics";
6490
6215
  const schema = databaseConfig?.schema ?? "public";
6491
6216
  const supabase = useSupabase();
6492
- const [metrics2, setMetrics] = useState(() => getCache(lineId) || { workspaceMetrics: [], lineMetrics: [] });
6493
- const [isLoading, setIsLoading] = useState(() => !getCache(lineId));
6217
+ const [metrics2, setMetrics] = useState({ workspaceMetrics: [], lineMetrics: [] });
6218
+ const [isLoading, setIsLoading] = useState(true);
6494
6219
  const [error, setError] = useState(null);
6495
6220
  const lineIdRef = useRef(lineId);
6496
6221
  const isFetchingRef = useRef(false);
6497
6222
  const updateQueueRef = useRef(false);
6498
- const timeoutRef = useRef(null);
6499
6223
  const companySpecificMetricsTable = useMemo(
6500
6224
  () => getCompanyMetricsTableName(entityConfig.companyId, "performance_metrics"),
6501
6225
  [entityConfig.companyId]
6502
6226
  );
6503
6227
  useEffect(() => {
6504
6228
  lineIdRef.current = lineId;
6505
- const cachedData = getCache(lineId);
6506
- setMetrics(cachedData || { workspaceMetrics: [], lineMetrics: [] });
6507
- setIsLoading(!cachedData);
6229
+ setMetrics({ workspaceMetrics: [], lineMetrics: [] });
6230
+ setIsLoading(true);
6508
6231
  }, [lineId]);
6509
6232
  const fetchAllMetrics = useCallback(async () => {
6510
6233
  const currentLineIdToUse = lineIdRef.current;
@@ -6516,9 +6239,7 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId }) => {
6516
6239
  return;
6517
6240
  }
6518
6241
  isFetchingRef.current = true;
6519
- if (!getCache(currentLineIdToUse)) {
6520
- setIsLoading(true);
6521
- }
6242
+ setIsLoading(true);
6522
6243
  setError(null);
6523
6244
  try {
6524
6245
  const currentShiftDetails = getCurrentShift(defaultTimezone, shiftConfig);
@@ -6543,7 +6264,6 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId }) => {
6543
6264
  lineMetrics: []
6544
6265
  };
6545
6266
  setMetrics(newMetricsState2);
6546
- setCache(currentLineIdToUse, newMetricsState2);
6547
6267
  return;
6548
6268
  }
6549
6269
  let workspaceQuery = supabase.from(companySpecificMetricsTable).select("company_id,line_id,shift_id,date,workspace_id,workspace_name,total_output,avg_pph,performance_score,avg_cycle_time,trend_score,ideal_output,efficiency,total_day_output").eq("date", operationalDate).eq("shift_id", currentShiftDetails.shiftId).in("workspace_id", enabledWorkspaceIds);
@@ -6595,7 +6315,6 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId }) => {
6595
6315
  lineMetrics: lineData || []
6596
6316
  };
6597
6317
  setMetrics(newMetricsState);
6598
- setCache(currentLineIdToUse, newMetricsState);
6599
6318
  } catch (err) {
6600
6319
  setError({ message: err.message, code: err.code || "FETCH_ERROR" });
6601
6320
  } finally {
@@ -6621,12 +6340,7 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId }) => {
6621
6340
  return;
6622
6341
  }
6623
6342
  updateQueueRef.current = true;
6624
- if (timeoutRef.current) {
6625
- clearTimeout(timeoutRef.current);
6626
- }
6627
- timeoutRef.current = setTimeout(() => {
6628
- fetchAllMetrics();
6629
- }, 500);
6343
+ fetchAllMetrics();
6630
6344
  }, [fetchAllMetrics, supabase]);
6631
6345
  useEffect(() => {
6632
6346
  if (lineId && supabase) {
@@ -6671,9 +6385,6 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId }) => {
6671
6385
  onLineMetricsUpdate?.();
6672
6386
  });
6673
6387
  return () => {
6674
- if (timeoutRef.current) {
6675
- clearTimeout(timeoutRef.current);
6676
- }
6677
6388
  channels.forEach((channel) => {
6678
6389
  supabase?.removeChannel(channel).catch((err) => console.error("[useDashboardMetrics] Error removing channel:", err.message));
6679
6390
  });
@@ -6702,30 +6413,6 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId }) => {
6702
6413
  refetch: fetchAllMetrics
6703
6414
  };
6704
6415
  };
6705
- var CACHE_KEY_PREFIX2 = "line_kpis_cache_";
6706
- var CACHE_DURATION2 = 5 * 60 * 1e3;
6707
- var getCache2 = (lineId) => {
6708
- if (typeof window === "undefined") return null;
6709
- try {
6710
- const cached = localStorage.getItem(`${CACHE_KEY_PREFIX2}${lineId}`);
6711
- if (!cached) return null;
6712
- const parsedCache = JSON.parse(cached);
6713
- if (!parsedCache.timestamp || Date.now() - parsedCache.timestamp > CACHE_DURATION2) {
6714
- localStorage.removeItem(`${CACHE_KEY_PREFIX2}${lineId}`);
6715
- return null;
6716
- }
6717
- return parsedCache.data;
6718
- } catch (error) {
6719
- return null;
6720
- }
6721
- };
6722
- var setCache2 = (lineId, data) => {
6723
- if (typeof window === "undefined") return;
6724
- try {
6725
- localStorage.setItem(`${CACHE_KEY_PREFIX2}${lineId}`, JSON.stringify({ data, timestamp: Date.now() }));
6726
- } catch (error) {
6727
- }
6728
- };
6729
6416
  var useLineKPIs = ({ lineId }) => {
6730
6417
  useDashboardConfig();
6731
6418
  const entityConfig = useEntityConfig();
@@ -6737,13 +6424,12 @@ var useLineKPIs = ({ lineId }) => {
6737
6424
  const dashboardServiceInstance = useMemo(() => {
6738
6425
  return dashboardService;
6739
6426
  }, []);
6740
- const [kpis, setKPIs] = useState(() => getCache2(lineId));
6741
- const [isLoading, setIsLoading] = useState(!getCache2(lineId));
6427
+ const [kpis, setKPIs] = useState(null);
6428
+ const [isLoading, setIsLoading] = useState(true);
6742
6429
  const [error, setError] = useState(null);
6743
6430
  const lineIdRef = useRef(lineId);
6744
6431
  const isFetchingRef = useRef(false);
6745
6432
  const updateQueueRef = useRef(false);
6746
- const timeoutRef = useRef(null);
6747
6433
  const defaultTimezone = dateTimeConfig.defaultTimezone;
6748
6434
  const schema = databaseConfig.schema ?? "public";
6749
6435
  const lineMetricsTable = databaseConfig.tables?.lineMetrics ?? "line_metrics";
@@ -6774,7 +6460,6 @@ var useLineKPIs = ({ lineId }) => {
6774
6460
  if (lineInfo) {
6775
6461
  const newKPIs = dashboardServiceInstance.calculateKPIs(lineInfo);
6776
6462
  setKPIs(newKPIs);
6777
- setCache2(currentLineId, newKPIs);
6778
6463
  } else {
6779
6464
  setKPIs(null);
6780
6465
  }
@@ -6791,12 +6476,7 @@ var useLineKPIs = ({ lineId }) => {
6791
6476
  const queueUpdate = useCallback(() => {
6792
6477
  if (updateQueueRef.current) return;
6793
6478
  updateQueueRef.current = true;
6794
- if (timeoutRef.current) {
6795
- clearTimeout(timeoutRef.current);
6796
- }
6797
- timeoutRef.current = setTimeout(() => {
6798
- fetchKPIs();
6799
- }, 500);
6479
+ fetchKPIs();
6800
6480
  }, [fetchKPIs]);
6801
6481
  useEffect(() => {
6802
6482
  const currentLineId = lineIdRef.current;
@@ -6854,9 +6534,6 @@ var useLineKPIs = ({ lineId }) => {
6854
6534
  activeChannels.push(csChannel);
6855
6535
  }
6856
6536
  return () => {
6857
- if (timeoutRef.current) {
6858
- clearTimeout(timeoutRef.current);
6859
- }
6860
6537
  activeChannels.forEach((ch) => supabase.removeChannel(ch).catch((err) => console.error("[useLineKPIs] Error removing KPI channel:", err)));
6861
6538
  };
6862
6539
  }, [supabase, lineId, fetchKPIs, queueUpdate, dashboardServiceInstance, entityConfig, schema, lineMetricsTable, companySpecificMetricsTable, defaultTimezone, shiftConfig, kpis, isFactoryView]);
@@ -6885,7 +6562,6 @@ var useRealtimeLineMetrics = ({
6885
6562
  const [initialized, setInitialized] = useState(false);
6886
6563
  const lineIdRef = useRef(null);
6887
6564
  const updateQueueRef = useRef(false);
6888
- const timeoutRef = useRef(null);
6889
6565
  const isFetchingRef = useRef(false);
6890
6566
  const channelsRef = useRef([]);
6891
6567
  const currentShift = useMemo(() => getCurrentShift(dateTimeConfig.defaultTimezone || "Asia/Kolkata", shiftConfig), [dateTimeConfig.defaultTimezone, shiftConfig]);
@@ -7098,12 +6774,7 @@ var useRealtimeLineMetrics = ({
7098
6774
  const queueUpdate = useCallback(() => {
7099
6775
  if (updateQueueRef.current) return;
7100
6776
  updateQueueRef.current = true;
7101
- if (timeoutRef.current) {
7102
- clearTimeout(timeoutRef.current);
7103
- }
7104
- timeoutRef.current = setTimeout(() => {
7105
- fetchData();
7106
- }, 500);
6777
+ fetchData();
7107
6778
  }, [fetchData]);
7108
6779
  const setupSubscriptions = useCallback(() => {
7109
6780
  if (channelsRef.current.length > 0) {
@@ -7181,9 +6852,6 @@ var useRealtimeLineMetrics = ({
7181
6852
  }
7182
6853
  setupSubscriptions();
7183
6854
  return () => {
7184
- if (timeoutRef.current) {
7185
- clearTimeout(timeoutRef.current);
7186
- }
7187
6855
  if (channelsRef.current.length > 0) {
7188
6856
  channelsRef.current.forEach((channel) => {
7189
6857
  if (process.env.NODE_ENV === "development") {
@@ -8471,32 +8139,12 @@ var useAllWorkspaceMetrics = (options) => {
8471
8139
  return `${metricsTablePrefix}_${companyId.replace(/-/g, "_")}`;
8472
8140
  }, [entityConfig.companyId]);
8473
8141
  const schema = databaseConfig.schema ?? "public";
8474
- const fetchWorkspaceMetrics = useCallback(async (skipCache = false) => {
8142
+ const fetchWorkspaceMetrics = useCallback(async () => {
8475
8143
  if (!initialized) {
8476
8144
  setLoading(true);
8477
8145
  }
8478
8146
  setError(null);
8479
8147
  try {
8480
- const cacheKey = cacheService.generateKey(
8481
- "all-workspace-metrics",
8482
- entityConfig.companyId,
8483
- queryDate,
8484
- queryShiftId
8485
- );
8486
- if (!skipCache && !loading) {
8487
- const cachedData = cacheService.get(cacheKey, {
8488
- storage: "memory",
8489
- duration: 5 * 60 * 1e3
8490
- // 5 minutes
8491
- });
8492
- if (cachedData) {
8493
- console.log("[useAllWorkspaceMetrics] Using cached data for:", cacheKey);
8494
- setWorkspaces(cachedData);
8495
- setInitialized(true);
8496
- setLoading(false);
8497
- return;
8498
- }
8499
- }
8500
8148
  console.log("Fetching all workspace metrics with params:", {
8501
8149
  queryDate,
8502
8150
  queryShiftId,
@@ -8546,11 +8194,6 @@ var useAllWorkspaceMetrics = (options) => {
8546
8194
  }));
8547
8195
  setWorkspaces(transformedData);
8548
8196
  setInitialized(true);
8549
- cacheService.set(cacheKey, transformedData, {
8550
- storage: "memory",
8551
- duration: 5 * 60 * 1e3
8552
- // 5 minutes
8553
- });
8554
8197
  } catch (err) {
8555
8198
  console.error("Error fetching all workspace metrics:", err);
8556
8199
  setError({ message: err.message, code: err.code || "FETCH_ERROR" });
@@ -8575,14 +8218,7 @@ var useAllWorkspaceMetrics = (options) => {
8575
8218
  },
8576
8219
  async (payload) => {
8577
8220
  console.log("All workspace metrics update received:", payload);
8578
- const cacheKey = cacheService.generateKey(
8579
- "all-workspace-metrics",
8580
- entityConfig.companyId,
8581
- queryDate,
8582
- queryShiftId
8583
- );
8584
- cacheService.delete(cacheKey, { storage: "memory" });
8585
- await fetchWorkspaceMetrics(true);
8221
+ await fetchWorkspaceMetrics();
8586
8222
  }
8587
8223
  ).subscribe();
8588
8224
  return channel2;
@@ -8597,7 +8233,7 @@ var useAllWorkspaceMetrics = (options) => {
8597
8233
  useEffect(() => {
8598
8234
  setInitialized(false);
8599
8235
  }, [queryDate, queryShiftId]);
8600
- const refreshWorkspaces = useCallback(() => fetchWorkspaceMetrics(true), [fetchWorkspaceMetrics]);
8236
+ const refreshWorkspaces = useCallback(() => fetchWorkspaceMetrics(), [fetchWorkspaceMetrics]);
8601
8237
  return useMemo(
8602
8238
  () => ({ workspaces, loading, error, refreshWorkspaces }),
8603
8239
  [workspaces, loading, error, refreshWorkspaces]
@@ -12050,8 +11686,11 @@ var useHourlyTargetAchievements = ({
12050
11686
  targetThreshold,
12051
11687
  enabled
12052
11688
  });
12053
- const currentHourIndex = hourlyData.length - 1;
12054
- if (currentHourIndex < 0 || hourlyData[currentHourIndex] === void 0) {
11689
+ let currentHourIndex = hourlyData.length - 1;
11690
+ while (currentHourIndex >= 0 && (hourlyData[currentHourIndex] === void 0 || hourlyData[currentHourIndex] === 0)) {
11691
+ currentHourIndex--;
11692
+ }
11693
+ if (currentHourIndex < 0) {
12055
11694
  console.log("[HOURLY TARGET CHECK] No hourly data available");
12056
11695
  return;
12057
11696
  }
@@ -12149,8 +11788,11 @@ var useHourlyTargetMisses = ({
12149
11788
  targetThreshold,
12150
11789
  enabled
12151
11790
  });
12152
- const currentHourIndex = hourlyData.length - 1;
12153
- if (currentHourIndex < 0 || hourlyData[currentHourIndex] === void 0) {
11791
+ let currentHourIndex = hourlyData.length - 1;
11792
+ while (currentHourIndex >= 0 && (hourlyData[currentHourIndex] === void 0 || hourlyData[currentHourIndex] === 0)) {
11793
+ currentHourIndex--;
11794
+ }
11795
+ if (currentHourIndex < 0) {
12154
11796
  console.log("[HOURLY TARGET MISS CHECK] No hourly data available");
12155
11797
  return;
12156
11798
  }
@@ -26599,6 +26241,85 @@ var BottlenecksContent = ({
26599
26241
  }, [workspaceId, date, s3ClipsService, shift, dashboardConfig, updateClipCounts, updateVideoIndex]);
26600
26242
  const loadingCategoryRef = useRef(null);
26601
26243
  const videoRetryCountRef = useRef(0);
26244
+ const loadingVideosRef = useRef(/* @__PURE__ */ new Set());
26245
+ const loadedVideosMapRef = useRef(/* @__PURE__ */ new Map());
26246
+ const ensureVideosLoaded = useCallback(async (centerIndex) => {
26247
+ if (!s3ClipsService || !workspaceId || !isMountedRef.current) return;
26248
+ const currentFilter = activeFilterRef.current;
26249
+ const currentVideoIndex = videoIndexRef.current;
26250
+ let effectiveFilter = currentFilter;
26251
+ if (sopCategories && sopCategories.length > 0) {
26252
+ const category = sopCategories.find((cat) => cat.id === currentFilter);
26253
+ if (category && category.s3FolderName) {
26254
+ effectiveFilter = category.s3FolderName;
26255
+ }
26256
+ }
26257
+ const cacheKey = `${effectiveFilter}:${date}:${shift}`;
26258
+ if (!loadedVideosMapRef.current.has(cacheKey)) {
26259
+ loadedVideosMapRef.current.set(cacheKey, /* @__PURE__ */ new Set());
26260
+ }
26261
+ const loadedIndices = loadedVideosMapRef.current.get(cacheKey);
26262
+ const indicesToLoad = [];
26263
+ const rangeBefore = 1;
26264
+ const rangeAfter = 3;
26265
+ for (let i = Math.max(0, centerIndex - rangeBefore); i <= Math.min(clipCounts[effectiveFilter] - 1, centerIndex + rangeAfter); i++) {
26266
+ if (!loadedIndices.has(i) && !loadingVideosRef.current.has(i)) {
26267
+ indicesToLoad.push(i);
26268
+ }
26269
+ }
26270
+ if (indicesToLoad.length === 0) return;
26271
+ console.log(`[ensureVideosLoaded] Preloading ${indicesToLoad.length} videos around index ${centerIndex}: [${indicesToLoad.join(", ")}]`);
26272
+ indicesToLoad.forEach((idx) => loadingVideosRef.current.add(idx));
26273
+ const loadPromises = indicesToLoad.map(async (index) => {
26274
+ try {
26275
+ let video = null;
26276
+ if (currentVideoIndex && currentVideoIndex.byCategory && currentVideoIndex.allVideos.length > 0) {
26277
+ video = await s3ClipsService.getVideoFromIndex(
26278
+ currentVideoIndex,
26279
+ effectiveFilter,
26280
+ index,
26281
+ true,
26282
+ // includeCycleTime - OK for preloading
26283
+ true
26284
+ // includeMetadata - OK for just +3/-1 videos, not ALL videos
26285
+ );
26286
+ }
26287
+ if (!video) {
26288
+ const operationalDate = date || getOperationalDate();
26289
+ const shiftStr = shift?.toString() || "0";
26290
+ video = await s3ClipsService.getClipByIndex(
26291
+ workspaceId,
26292
+ operationalDate,
26293
+ shiftStr,
26294
+ effectiveFilter,
26295
+ index,
26296
+ true,
26297
+ // includeCycleTime - OK for preloading
26298
+ true
26299
+ // includeMetadata - OK for just +3/-1 videos, not ALL videos
26300
+ );
26301
+ }
26302
+ if (video && isMountedRef.current) {
26303
+ setAllVideos((prev) => {
26304
+ const exists = prev.some((v) => v.id === video.id);
26305
+ if (!exists) {
26306
+ return [...prev, video];
26307
+ }
26308
+ return prev;
26309
+ });
26310
+ loadedIndices.add(index);
26311
+ preloadVideoUrl(video.src);
26312
+ }
26313
+ } catch (error2) {
26314
+ console.warn(`[ensureVideosLoaded] Failed to load video at index ${index}:`, error2);
26315
+ } finally {
26316
+ loadingVideosRef.current.delete(index);
26317
+ }
26318
+ });
26319
+ Promise.all(loadPromises).catch((err) => {
26320
+ console.warn("[ensureVideosLoaded] Some videos failed to preload:", err);
26321
+ });
26322
+ }, [s3ClipsService, workspaceId, clipCounts, sopCategories, date, shift]);
26602
26323
  const loadFirstVideoForCategory = useCallback(async (category) => {
26603
26324
  if (!workspaceId || !s3ClipsService || !isMountedRef.current) return;
26604
26325
  const targetCategory = category || activeFilterRef.current;
@@ -26701,9 +26422,11 @@ var BottlenecksContent = ({
26701
26422
  }, [prefetchData, prefetchStatus, updateClipCounts, updateVideoIndex, hasInitialLoad]);
26702
26423
  useEffect(() => {
26703
26424
  if (s3ClipsService && videoIndex && clipCounts[activeFilter] > 0) {
26704
- loadFirstVideoForCategory(activeFilter);
26425
+ if (allVideos.length === 0) {
26426
+ loadFirstVideoForCategory(activeFilter);
26427
+ }
26705
26428
  }
26706
- }, [activeFilter, s3ClipsService, videoIndex, clipCounts, loadFirstVideoForCategory]);
26429
+ }, [activeFilter, s3ClipsService, videoIndex, clipCounts, loadFirstVideoForCategory, allVideos.length]);
26707
26430
  useEffect(() => {
26708
26431
  if (previousFilterRef.current !== activeFilter) {
26709
26432
  console.log(`Filter changed from ${previousFilterRef.current} to ${activeFilter} - resetting to first video`);
@@ -26772,26 +26495,25 @@ var BottlenecksContent = ({
26772
26495
  return new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime();
26773
26496
  });
26774
26497
  }, [activeFilter, allVideos, sopCategories]);
26775
- useEffect(() => {
26776
- if (filteredVideos.length === 0) return;
26777
- const upcoming = [];
26778
- if (currentIndex + 1 < filteredVideos.length && filteredVideos[currentIndex + 1]) {
26779
- upcoming.push(filteredVideos[currentIndex + 1].src);
26780
- }
26781
- if (currentIndex - 1 >= 0 && currentIndex - 1 < filteredVideos.length && filteredVideos[currentIndex - 1]) {
26782
- upcoming.push(filteredVideos[currentIndex - 1].src);
26783
- }
26784
- if (upcoming.length > 0) {
26785
- preloadVideosUrl(upcoming);
26786
- }
26787
- }, [currentIndex, filteredVideos]);
26788
26498
  useEffect(() => {
26789
26499
  if (isNavigating && currentIndex < filteredVideos.length) {
26790
26500
  setIsNavigating(false);
26791
26501
  setError(null);
26792
26502
  videoRetryCountRef.current = 0;
26503
+ ensureVideosLoaded(currentIndex);
26793
26504
  }
26794
26505
  }, [isNavigating, currentIndex, filteredVideos.length]);
26506
+ useEffect(() => {
26507
+ if (!isPlaying || !isMountedRef.current) return;
26508
+ const preloadInterval = setInterval(() => {
26509
+ if (isMountedRef.current) {
26510
+ const currentIdx = currentIndexRef.current;
26511
+ console.log(`[Background Preloader] Ensuring videos loaded around index ${currentIdx}`);
26512
+ ensureVideosLoaded(currentIdx);
26513
+ }
26514
+ }, 2e3);
26515
+ return () => clearInterval(preloadInterval);
26516
+ }, [isPlaying]);
26795
26517
  const handleNext = useCallback(async () => {
26796
26518
  if (!isMountedRef.current) return;
26797
26519
  const currentIdx = currentIndexRef.current;
@@ -26812,6 +26534,7 @@ var BottlenecksContent = ({
26812
26534
  }
26813
26535
  if (nextIndex < filteredVideos.length) {
26814
26536
  setIsNavigating(false);
26537
+ ensureVideosLoaded(nextIndex);
26815
26538
  return;
26816
26539
  }
26817
26540
  if (isMountedRef.current) {
@@ -26829,8 +26552,8 @@ var BottlenecksContent = ({
26829
26552
  nextIndex,
26830
26553
  true,
26831
26554
  // includeCycleTime
26832
- true
26833
- // includeMetadata
26555
+ false
26556
+ // includeMetadata - DON'T fetch metadata during navigation to prevent flooding!
26834
26557
  );
26835
26558
  } else {
26836
26559
  console.warn(`[BottlenecksContent] Video index not ready for navigation: ID: ${currentVideoIndex?._debugId || "NO_ID"}, byCategory exists = ${!!currentVideoIndex?.byCategory}, allVideos = ${currentVideoIndex?.allVideos?.length || 0}`);
@@ -26843,7 +26566,11 @@ var BottlenecksContent = ({
26843
26566
  operationalDate,
26844
26567
  shiftStr,
26845
26568
  effectiveFilter,
26846
- nextIndex
26569
+ nextIndex,
26570
+ true,
26571
+ // includeCycleTime - needed for main video display
26572
+ false
26573
+ // includeMetadata - DON'T fetch metadata during navigation to prevent flooding!
26847
26574
  );
26848
26575
  }
26849
26576
  if (video && isMountedRef.current) {
@@ -26856,26 +26583,7 @@ var BottlenecksContent = ({
26856
26583
  return prev;
26857
26584
  });
26858
26585
  preloadVideoUrl(video.src);
26859
- if (nextIndex + 1 < clipCounts[effectiveFilter]) {
26860
- setTimeout(() => {
26861
- const videoIndexForPreload = videoIndexRef.current;
26862
- if (videoIndexForPreload && s3ClipsService && isMountedRef.current) {
26863
- s3ClipsService.getVideoFromIndex(videoIndexForPreload, effectiveFilter, nextIndex + 1, true, true).then((nextVideo) => {
26864
- if (nextVideo && isMountedRef.current) {
26865
- setAllVideos((prev) => {
26866
- if (!prev.some((v) => v.id === nextVideo.id)) {
26867
- const newVideos = [...prev, nextVideo];
26868
- return newVideos;
26869
- }
26870
- return prev;
26871
- });
26872
- preloadVideoUrl(nextVideo.src);
26873
- }
26874
- }).catch(() => {
26875
- });
26876
- }
26877
- }, 100);
26878
- }
26586
+ ensureVideosLoaded(nextIndex);
26879
26587
  }
26880
26588
  } catch (error2) {
26881
26589
  console.error("Error loading next video:", error2);
@@ -26897,6 +26605,7 @@ var BottlenecksContent = ({
26897
26605
  if (prevIndex < filteredVideos.length) {
26898
26606
  setCurrentIndex(prevIndex);
26899
26607
  setError(null);
26608
+ ensureVideosLoaded(prevIndex);
26900
26609
  }
26901
26610
  }
26902
26611
  }, [filteredVideos.length]);
@@ -26905,6 +26614,8 @@ var BottlenecksContent = ({
26905
26614
  }, []);
26906
26615
  const handleVideoPlay = useCallback((player) => {
26907
26616
  setIsPlaying(true);
26617
+ const currentIdx = currentIndexRef.current;
26618
+ ensureVideosLoaded(currentIdx);
26908
26619
  }, []);
26909
26620
  const handleVideoPause = useCallback((player) => {
26910
26621
  setIsPlaying(false);
@@ -35470,6 +35181,10 @@ var TargetsViewUI = ({
35470
35181
  ),
35471
35182
  /* @__PURE__ */ jsx("div", { className: "h-8 w-px bg-gray-200/80" }),
35472
35183
  /* @__PURE__ */ jsx("div", { className: "flex items-center gap-3", children: /* @__PURE__ */ jsxs("div", { className: "ml-4 text-sm font-medium text-gray-600", children: [
35184
+ line.shiftStartTime,
35185
+ " \u2013 ",
35186
+ line.shiftEndTime,
35187
+ " \u2022 ",
35473
35188
  line.shiftHours,
35474
35189
  " hours"
35475
35190
  ] }) })
@@ -36132,7 +35847,7 @@ var TargetsView = ({
36132
35847
  const handleShiftChange = (shiftId) => {
36133
35848
  setSelectedShift(shiftId);
36134
35849
  const loadShiftHours = async () => {
36135
- const updatedLineWorkspaces = { ...lineWorkspaces };
35850
+ const updatedLineWorkspaces = { ...allShiftsData[shiftId] };
36136
35851
  let hasUpdates = false;
36137
35852
  for (const lineId of lineIds) {
36138
35853
  try {
@@ -36180,7 +35895,10 @@ var TargetsView = ({
36180
35895
  }
36181
35896
  }
36182
35897
  if (hasUpdates) {
36183
- setLineWorkspaces(updatedLineWorkspaces);
35898
+ setAllShiftsData((prev) => ({
35899
+ ...prev,
35900
+ [shiftId]: updatedLineWorkspaces
35901
+ }));
36184
35902
  }
36185
35903
  };
36186
35904
  loadShiftHours();
@@ -37829,4 +37547,4 @@ var streamProxyConfig = {
37829
37547
  }
37830
37548
  };
37831
37549
 
37832
- export { ACTION_NAMES, AIAgentView_default as AIAgentView, AudioService, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedTargetsView, BarChart, BaseHistoryCalendar, BottlenecksContent, BreakNotificationPopup, CachePrefetchStatus, Card2 as Card, CardContent2 as CardContent, CardDescription2 as CardDescription, CardFooter2 as CardFooter, CardHeader2 as CardHeader, CardTitle2 as CardTitle, CongratulationsOverlay, CycleTimeChart, CycleTimeOverTimeChart, DEFAULT_ANALYTICS_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_CONFIG, DEFAULT_DATABASE_CONFIG, DEFAULT_DATE_TIME_CONFIG, DEFAULT_ENDPOINTS_CONFIG, DEFAULT_ENTITY_CONFIG, DEFAULT_SHIFT_CONFIG, DEFAULT_THEME_CONFIG, DEFAULT_VIDEO_CONFIG, DEFAULT_WORKSPACE_CONFIG, DEFAULT_WORKSPACE_POSITIONS, DashboardHeader, DashboardLayout, DashboardOverridesProvider, DashboardProvider, DateDisplay_default as DateDisplay, DateTimeDisplay, DebugAuth, DebugAuthView_default as DebugAuthView, EmptyStateMessage, EncouragementOverlay, FactoryView_default as FactoryView, GaugeChart, GridComponentsPlaceholder, HamburgerButton, Header, HelpView_default as HelpView, HomeView_default as HomeView, HourlyOutputChart2 as HourlyOutputChart, ISTTimer_default as ISTTimer, KPICard, KPIDetailView_default as KPIDetailView, KPIGrid, KPIHeader, KPISection, KPIsOverviewView_default as KPIsOverviewView, LINE_1_UUID, LINE_2_UUID, LargeOutputProgressChart, LeaderboardDetailView_default as LeaderboardDetailView, Legend6 as Legend, LineChart, LineHistoryCalendar, LineMonthlyHistory, LineMonthlyPdfGenerator, LinePdfExportButton, LinePdfGenerator, LineWhatsAppShareButton, LiveTimer, LoadingInline, LoadingOverlay_default as LoadingOverlay, LoadingPage_default as LoadingPage, LoadingSkeleton, LoadingState, LoginPage, LoginView_default as LoginView, MainLayout, MetricCard_default as MetricCard, NoWorkspaceData, OptifyeAgentClient, OptifyeLogoLoader_default as OptifyeLogoLoader, OutputProgressChart, PageHeader, PieChart4 as PieChart, PrefetchConfigurationError, PrefetchError, PrefetchEvents, PrefetchStatus, PrefetchTimeoutError, ProfileView_default as ProfileView, RegistryProvider, S3Service, SKUManagementView, SOPComplianceChart, SSEChatClient, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, ShiftDisplay_default as ShiftDisplay, ShiftsView_default as ShiftsView, SideNavBar, SingleVideoStream_default as SingleVideoStream, Skeleton, SubscriptionManager, SubscriptionManagerProvider, SupabaseProvider, TargetWorkspaceGrid, TargetsView_default as TargetsView, ThreadSidebar, TicketHistory_default as TicketHistory, TicketHistoryService, TimeDisplay_default as TimeDisplay, TimePickerDropdown, VideoCard, VideoGridView, VideoPlayer, VideoPreloader, WORKSPACE_POSITIONS, WhatsAppShareButton, WorkspaceCard, WorkspaceDetailView_default as WorkspaceDetailView, WorkspaceDisplayNameExample, WorkspaceGrid, WorkspaceGridItem, WorkspaceHistoryCalendar, WorkspaceMetricCards, WorkspaceMonthlyDataFetcher, WorkspaceMonthlyPdfGenerator, WorkspacePdfExportButton, WorkspacePdfGenerator, WorkspaceWhatsAppShareButton, actionService, apiUtils, authCoreService, authOTPService, authRateLimitService, cacheService, checkRateLimit2 as checkRateLimit, clearAllRateLimits2 as clearAllRateLimits, clearRateLimit2 as clearRateLimit, clearS3VideoCache, clearS3VideoFromCache, clearWorkspaceDisplayNamesCache, cn, createStreamProxyHandler, createSupabaseClient, createThrottledReload, dashboardService, deleteThread, forceRefreshWorkspaceDisplayNames, formatDateInZone, formatDateTimeInZone, formatISTDate, formatIdleTime, formatTimeInZone, fromUrlFriendlyName, getAllLineDisplayNames, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAnonClient, getCameraNumber, getCompanyMetricsTableName, getConfigurableShortWorkspaceDisplayName, getConfigurableWorkspaceDisplayName, getConfiguredLineIds, getCoreSessionRecordingProperties, getCoreSessionReplayUrl, getCurrentShift, getCurrentTimeInZone, getDashboardHeaderTimeInZone, getDaysDifferenceInZone, getDefaultCameraStreamUrl, getDefaultLineId, getDefaultTabForWorkspace, getLineDisplayName, getManufacturingInsights, getMetricsTablePrefix, getOperationalDate, getS3SignedUrl, getS3VideoSrc, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getSubscriptionManager, getThreadMessages, getUserThreads, getUserThreadsPaginated, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, identifyCoreUser, initializeCoreMixpanel, isLegacyConfiguration, isPrefetchError, isTransitionPeriod, isUrlPermanentlyFailed, isValidFactoryViewConfiguration, isValidLineInfoPayload, isValidPrefetchParams, isValidPrefetchStatus, isValidWorkspaceDetailedMetricsPayload, isValidWorkspaceMetricsPayload, isWorkspaceDisplayNamesLoaded, isWorkspaceDisplayNamesLoading, mergeWithDefaultConfig, migrateLegacyConfiguration, optifyeAgentClient, preInitializeWorkspaceDisplayNames, preloadS3Video, preloadS3VideoUrl, preloadS3VideosUrl, preloadVideoUrl, preloadVideosUrl, qualityService, realtimeService, refreshWorkspaceDisplayNames, resetCoreMixpanel, resetFailedUrl, resetSubscriptionManager, s3VideoPreloader, skuService, startCoreSessionRecording, stopCoreSessionRecording, storeWorkspaceMapping, streamProxyConfig, throttledReloadDashboard, toUrlFriendlyName, trackCoreEvent, trackCorePageView, updateThreadTitle, useActiveBreaks, useAllWorkspaceMetrics, useAnalyticsConfig, useAudioService, useAuth, useAuthConfig, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHistoricWorkspaceMetrics, useHlsStream, useHlsStreamWithCropping, useHookOverride, useHourEndTimer, useHourlyTargetAchievements, useHourlyTargetMisses, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineWorkspaceMetrics, useMessages, useMetrics, useNavigation, useOverrides, usePageOverride, usePrefetchClipCounts, useRealtimeLineMetrics, useRegistry, useSKUs, useShiftConfig, useShifts, useSubscriptionManager, useSubscriptionManagerSafe, useSupabase, useSupabaseClient, useTargets, useTheme, useThemeConfig, useThreads, useTicketHistory, useVideoConfig, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, videoPrefetchManager, videoPreloader, whatsappService, withAuth, withRegistry, workspaceService };
37550
+ export { ACTION_NAMES, AIAgentView_default as AIAgentView, AudioService, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedTargetsView, BarChart, BaseHistoryCalendar, BottlenecksContent, BreakNotificationPopup, CachePrefetchStatus, Card2 as Card, CardContent2 as CardContent, CardDescription2 as CardDescription, CardFooter2 as CardFooter, CardHeader2 as CardHeader, CardTitle2 as CardTitle, CongratulationsOverlay, CycleTimeChart, CycleTimeOverTimeChart, DEFAULT_ANALYTICS_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_CONFIG, DEFAULT_DATABASE_CONFIG, DEFAULT_DATE_TIME_CONFIG, DEFAULT_ENDPOINTS_CONFIG, DEFAULT_ENTITY_CONFIG, DEFAULT_SHIFT_CONFIG, DEFAULT_THEME_CONFIG, DEFAULT_VIDEO_CONFIG, DEFAULT_WORKSPACE_CONFIG, DEFAULT_WORKSPACE_POSITIONS, DashboardHeader, DashboardLayout, DashboardOverridesProvider, DashboardProvider, DateDisplay_default as DateDisplay, DateTimeDisplay, DebugAuth, DebugAuthView_default as DebugAuthView, EmptyStateMessage, EncouragementOverlay, FactoryView_default as FactoryView, GaugeChart, GridComponentsPlaceholder, HamburgerButton, Header, HelpView_default as HelpView, HomeView_default as HomeView, HourlyOutputChart2 as HourlyOutputChart, ISTTimer_default as ISTTimer, KPICard, KPIDetailView_default as KPIDetailView, KPIGrid, KPIHeader, KPISection, KPIsOverviewView_default as KPIsOverviewView, LINE_1_UUID, LINE_2_UUID, LargeOutputProgressChart, LeaderboardDetailView_default as LeaderboardDetailView, Legend6 as Legend, LineChart, LineHistoryCalendar, LineMonthlyHistory, LineMonthlyPdfGenerator, LinePdfExportButton, LinePdfGenerator, LineWhatsAppShareButton, LiveTimer, LoadingInline, LoadingOverlay_default as LoadingOverlay, LoadingPage_default as LoadingPage, LoadingSkeleton, LoadingState, LoginPage, LoginView_default as LoginView, MainLayout, MetricCard_default as MetricCard, NoWorkspaceData, OptifyeAgentClient, OptifyeLogoLoader_default as OptifyeLogoLoader, OutputProgressChart, PageHeader, PieChart4 as PieChart, PrefetchConfigurationError, PrefetchError, PrefetchEvents, PrefetchStatus, PrefetchTimeoutError, ProfileView_default as ProfileView, RegistryProvider, S3Service, SKUManagementView, SOPComplianceChart, SSEChatClient, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, ShiftDisplay_default as ShiftDisplay, ShiftsView_default as ShiftsView, SideNavBar, SingleVideoStream_default as SingleVideoStream, Skeleton, SubscriptionManager, SubscriptionManagerProvider, SupabaseProvider, TargetWorkspaceGrid, TargetsView_default as TargetsView, ThreadSidebar, TicketHistory_default as TicketHistory, TicketHistoryService, TimeDisplay_default as TimeDisplay, TimePickerDropdown, VideoCard, VideoGridView, VideoPlayer, VideoPreloader, WORKSPACE_POSITIONS, WhatsAppShareButton, WorkspaceCard, WorkspaceDetailView_default as WorkspaceDetailView, WorkspaceDisplayNameExample, WorkspaceGrid, WorkspaceGridItem, WorkspaceHistoryCalendar, WorkspaceMetricCards, WorkspaceMonthlyDataFetcher, WorkspaceMonthlyPdfGenerator, WorkspacePdfExportButton, WorkspacePdfGenerator, WorkspaceWhatsAppShareButton, actionService, apiUtils, authCoreService, authOTPService, authRateLimitService, checkRateLimit2 as checkRateLimit, clearAllRateLimits2 as clearAllRateLimits, clearRateLimit2 as clearRateLimit, clearS3VideoCache, clearS3VideoFromCache, clearWorkspaceDisplayNamesCache, cn, createStreamProxyHandler, createSupabaseClient, createThrottledReload, dashboardService, deleteThread, forceRefreshWorkspaceDisplayNames, formatDateInZone, formatDateTimeInZone, formatISTDate, formatIdleTime, formatTimeInZone, fromUrlFriendlyName, getAllLineDisplayNames, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAnonClient, getCameraNumber, getCompanyMetricsTableName, getConfigurableShortWorkspaceDisplayName, getConfigurableWorkspaceDisplayName, getConfiguredLineIds, getCoreSessionRecordingProperties, getCoreSessionReplayUrl, getCurrentShift, getCurrentTimeInZone, getDashboardHeaderTimeInZone, getDaysDifferenceInZone, getDefaultCameraStreamUrl, getDefaultLineId, getDefaultTabForWorkspace, getLineDisplayName, getManufacturingInsights, getMetricsTablePrefix, getOperationalDate, getS3SignedUrl, getS3VideoSrc, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getSubscriptionManager, getThreadMessages, getUserThreads, getUserThreadsPaginated, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, identifyCoreUser, initializeCoreMixpanel, isLegacyConfiguration, isPrefetchError, isTransitionPeriod, isUrlPermanentlyFailed, isValidFactoryViewConfiguration, isValidLineInfoPayload, isValidPrefetchParams, isValidPrefetchStatus, isValidWorkspaceDetailedMetricsPayload, isValidWorkspaceMetricsPayload, isWorkspaceDisplayNamesLoaded, isWorkspaceDisplayNamesLoading, mergeWithDefaultConfig, migrateLegacyConfiguration, optifyeAgentClient, preInitializeWorkspaceDisplayNames, preloadS3Video, preloadS3VideoUrl, preloadS3VideosUrl, preloadVideoUrl, preloadVideosUrl, qualityService, realtimeService, refreshWorkspaceDisplayNames, resetCoreMixpanel, resetFailedUrl, resetSubscriptionManager, s3VideoPreloader, skuService, startCoreSessionRecording, stopCoreSessionRecording, storeWorkspaceMapping, streamProxyConfig, throttledReloadDashboard, toUrlFriendlyName, trackCoreEvent, trackCorePageView, updateThreadTitle, useActiveBreaks, useAllWorkspaceMetrics, useAnalyticsConfig, useAudioService, useAuth, useAuthConfig, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHistoricWorkspaceMetrics, useHlsStream, useHlsStreamWithCropping, useHookOverride, useHourEndTimer, useHourlyTargetAchievements, useHourlyTargetMisses, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineWorkspaceMetrics, useMessages, useMetrics, useNavigation, useOverrides, usePageOverride, usePrefetchClipCounts, useRealtimeLineMetrics, useRegistry, useSKUs, useShiftConfig, useShifts, useSubscriptionManager, useSubscriptionManagerSafe, useSupabase, useSupabaseClient, useTargets, useTheme, useThemeConfig, useThreads, useTicketHistory, useVideoConfig, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, videoPrefetchManager, videoPreloader, whatsappService, withAuth, withRegistry, workspaceService };