@optifye/dashboard-core 6.4.0 → 6.4.2
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.css +4 -12
- package/dist/index.d.mts +72 -3
- package/dist/index.d.ts +72 -3
- package/dist/index.js +429 -276
- package/dist/index.mjs +430 -279
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -18,6 +18,7 @@ var reactSlot = require('@radix-ui/react-slot');
|
|
|
18
18
|
var lucideReact = require('lucide-react');
|
|
19
19
|
var reactDayPicker = require('react-day-picker');
|
|
20
20
|
var outline = require('@heroicons/react/24/outline');
|
|
21
|
+
var solid = require('@heroicons/react/24/solid');
|
|
21
22
|
var html2canvas = require('html2canvas');
|
|
22
23
|
var jsPDF = require('jspdf');
|
|
23
24
|
var SelectPrimitive = require('@radix-ui/react-select');
|
|
@@ -2675,6 +2676,17 @@ var TicketHistoryService = class {
|
|
|
2675
2676
|
}
|
|
2676
2677
|
return data;
|
|
2677
2678
|
}
|
|
2679
|
+
/**
|
|
2680
|
+
* Update ticket serviced status
|
|
2681
|
+
*/
|
|
2682
|
+
static async updateTicketServicedStatus(ticketId, serviced) {
|
|
2683
|
+
const supabase = _getSupabaseInstance();
|
|
2684
|
+
const { data, error } = await supabase.from("support_ticket_history").update({ serviced, updated_at: (/* @__PURE__ */ new Date()).toISOString() }).eq("id", ticketId).select().single();
|
|
2685
|
+
if (error) {
|
|
2686
|
+
throw new Error(`Failed to update ticket serviced status: ${error.message}`);
|
|
2687
|
+
}
|
|
2688
|
+
return data;
|
|
2689
|
+
}
|
|
2678
2690
|
};
|
|
2679
2691
|
|
|
2680
2692
|
// src/lib/services/audioService.ts
|
|
@@ -3859,7 +3871,12 @@ var S3ClipsService = class {
|
|
|
3859
3871
|
*/
|
|
3860
3872
|
async listS3Clips(params) {
|
|
3861
3873
|
const { workspaceId, date, shiftId, maxKeys } = params;
|
|
3874
|
+
if (!isValidShiftId(shiftId)) {
|
|
3875
|
+
console.error(`[S3ClipsService] Invalid shift ID: ${shiftId}. Must be 0 (day) or 1 (night)`);
|
|
3876
|
+
return [];
|
|
3877
|
+
}
|
|
3862
3878
|
const prefix = `sop_violations/${workspaceId}/${date}/${shiftId}/`;
|
|
3879
|
+
console.log(`[S3ClipsService] Listing clips for workspace: ${workspaceId}, date: ${date}, shift: ${shiftId}`);
|
|
3863
3880
|
const deduplicationKey = `list-s3-clips:${prefix}:${maxKeys || "all"}`;
|
|
3864
3881
|
return this.requestCache.deduplicate(
|
|
3865
3882
|
deduplicationKey,
|
|
@@ -4040,6 +4057,10 @@ var S3ClipsService = class {
|
|
|
4040
4057
|
return sopConfig.default;
|
|
4041
4058
|
}
|
|
4042
4059
|
async getClipCounts(workspaceId, date, shiftId, buildIndex) {
|
|
4060
|
+
if (!isValidShiftId(shiftId)) {
|
|
4061
|
+
console.error(`[S3ClipsService] getClipCounts - Invalid shift ID: ${shiftId}. Must be 0 (day) or 1 (night)`);
|
|
4062
|
+
return buildIndex ? { counts: {}, videoIndex: { byCategory: /* @__PURE__ */ new Map(), allVideos: [], counts: {}, workspaceId, date, shiftId: "0", lastUpdated: /* @__PURE__ */ new Date() } } : {};
|
|
4063
|
+
}
|
|
4043
4064
|
const deduplicationKey = `clip-counts:${workspaceId}:${date}:${shiftId}:${buildIndex ? "with-index" : "counts-only"}`;
|
|
4044
4065
|
return this.requestCache.deduplicate(
|
|
4045
4066
|
deduplicationKey,
|
|
@@ -4051,10 +4072,7 @@ var S3ClipsService = class {
|
|
|
4051
4072
|
* Internal implementation of clip counts fetching
|
|
4052
4073
|
*/
|
|
4053
4074
|
async executeGetClipCounts(workspaceId, date, shiftId, buildIndex) {
|
|
4054
|
-
|
|
4055
|
-
this.isIndexBuilding = true;
|
|
4056
|
-
console.log(`[S3ClipsService] Starting index building - metadata fetching disabled`);
|
|
4057
|
-
}
|
|
4075
|
+
const effectiveBuildIndex = false;
|
|
4058
4076
|
try {
|
|
4059
4077
|
const basePrefix = `sop_violations/${workspaceId}/${date}/${shiftId}/`;
|
|
4060
4078
|
const counts = { total: 0 };
|
|
@@ -4069,9 +4087,10 @@ var S3ClipsService = class {
|
|
|
4069
4087
|
"cycle_completion",
|
|
4070
4088
|
"bottleneck"
|
|
4071
4089
|
];
|
|
4072
|
-
|
|
4090
|
+
const shiftName = shiftId === 0 || shiftId === "0" ? "Day" : "Night";
|
|
4091
|
+
console.log(`[S3ClipsService] Fast counting clips for ${workspaceId} on ${date}, shift ${shiftId} (${shiftName} Shift)`);
|
|
4073
4092
|
const startTime = performance.now();
|
|
4074
|
-
const videoIndex =
|
|
4093
|
+
const videoIndex = effectiveBuildIndex ? {
|
|
4075
4094
|
byCategory: /* @__PURE__ */ new Map(),
|
|
4076
4095
|
allVideos: [],
|
|
4077
4096
|
counts: {},
|
|
@@ -4085,53 +4104,7 @@ var S3ClipsService = class {
|
|
|
4085
4104
|
const categoryPrefix = `${basePrefix}${category}/videos/`;
|
|
4086
4105
|
const categoryVideos = [];
|
|
4087
4106
|
try {
|
|
4088
|
-
if (
|
|
4089
|
-
const command = new clientS3.ListObjectsV2Command({
|
|
4090
|
-
Bucket: this.config.s3Config.bucketName,
|
|
4091
|
-
Prefix: categoryPrefix,
|
|
4092
|
-
MaxKeys: 1e3
|
|
4093
|
-
});
|
|
4094
|
-
let continuationToken;
|
|
4095
|
-
do {
|
|
4096
|
-
if (continuationToken) {
|
|
4097
|
-
command.input.ContinuationToken = continuationToken;
|
|
4098
|
-
}
|
|
4099
|
-
const response = await this.s3Client.send(command);
|
|
4100
|
-
if (response.Contents) {
|
|
4101
|
-
for (const obj of response.Contents) {
|
|
4102
|
-
if (obj.Key && obj.Key.endsWith("playlist.m3u8")) {
|
|
4103
|
-
if (obj.Key.includes("missed_qchecks")) {
|
|
4104
|
-
continue;
|
|
4105
|
-
}
|
|
4106
|
-
const s3Uri = `s3://${this.config.s3Config.bucketName}/${obj.Key}`;
|
|
4107
|
-
const sopCategories = this.getSOPCategories(workspaceId);
|
|
4108
|
-
const parsedInfo = parseS3Uri(s3Uri, sopCategories);
|
|
4109
|
-
const belongsToCategory = parsedInfo && (parsedInfo.type === category || // Handle specific mismatches between folder names and parsed types
|
|
4110
|
-
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");
|
|
4111
|
-
if (belongsToCategory) {
|
|
4112
|
-
const videoEntry = {
|
|
4113
|
-
uri: s3Uri,
|
|
4114
|
-
category: parsedInfo.type,
|
|
4115
|
-
// Use the parsed type, not the folder name
|
|
4116
|
-
timestamp: parsedInfo.timestamp,
|
|
4117
|
-
videoId: `${workspaceId}-${parsedInfo.timestamp}`,
|
|
4118
|
-
workspaceId,
|
|
4119
|
-
date,
|
|
4120
|
-
shiftId: shiftId.toString()
|
|
4121
|
-
};
|
|
4122
|
-
categoryVideos.push(videoEntry);
|
|
4123
|
-
}
|
|
4124
|
-
}
|
|
4125
|
-
}
|
|
4126
|
-
}
|
|
4127
|
-
continuationToken = response.NextContinuationToken;
|
|
4128
|
-
} while (continuationToken);
|
|
4129
|
-
categoryVideos.sort((a, b) => b.timestamp.localeCompare(a.timestamp));
|
|
4130
|
-
if (categoryVideos.length > 0) {
|
|
4131
|
-
console.log(`[S3ClipsService] Found ${categoryVideos.length} videos for category '${category}' (parsed types: ${[...new Set(categoryVideos.map((v) => v.category))].join(", ")})`);
|
|
4132
|
-
}
|
|
4133
|
-
return { category, count: categoryVideos.length, videos: categoryVideos };
|
|
4134
|
-
} else {
|
|
4107
|
+
if (effectiveBuildIndex) ; else {
|
|
4135
4108
|
const command = new clientS3.ListObjectsV2Command({
|
|
4136
4109
|
Bucket: this.config.s3Config.bucketName,
|
|
4137
4110
|
Prefix: categoryPrefix,
|
|
@@ -4161,41 +4134,14 @@ var S3ClipsService = class {
|
|
|
4161
4134
|
for (const { category, count, videos } of results) {
|
|
4162
4135
|
counts[category] = count;
|
|
4163
4136
|
counts.total += count;
|
|
4164
|
-
if (
|
|
4165
|
-
if (videos.length > 0) {
|
|
4166
|
-
const parsedType = videos[0].category;
|
|
4167
|
-
videoIndex.byCategory.set(parsedType, videos);
|
|
4168
|
-
console.log(`[S3ClipsService] Indexed ${videos.length} videos under parsed type '${parsedType}'`);
|
|
4169
|
-
if (category !== parsedType) {
|
|
4170
|
-
videoIndex.byCategory.set(category, videos);
|
|
4171
|
-
console.log(`[S3ClipsService] Created alias: S3 folder '${category}' -> parsed type '${parsedType}' (${videos.length} videos)`);
|
|
4172
|
-
}
|
|
4173
|
-
}
|
|
4174
|
-
videoIndex.allVideos.push(...videos);
|
|
4175
|
-
}
|
|
4176
|
-
}
|
|
4177
|
-
if (buildIndex && videoIndex) {
|
|
4178
|
-
videoIndex.allVideos.sort((a, b) => b.timestamp.localeCompare(a.timestamp));
|
|
4179
|
-
videoIndex.counts = { ...counts };
|
|
4137
|
+
if (effectiveBuildIndex && videoIndex && videos) ;
|
|
4180
4138
|
}
|
|
4139
|
+
if (effectiveBuildIndex && videoIndex) ;
|
|
4181
4140
|
const elapsed = performance.now() - startTime;
|
|
4182
|
-
console.log(`[S3ClipsService]
|
|
4183
|
-
if (
|
|
4184
|
-
console.log(`[S3ClipsService] Final video index summary:`);
|
|
4185
|
-
console.log(` - VideoIndex ID: ${videoIndex._debugId}`);
|
|
4186
|
-
console.log(` - Total videos in allVideos: ${videoIndex.allVideos.length}`);
|
|
4187
|
-
console.log(` - Categories in byCategory Map: ${Array.from(videoIndex.byCategory.keys()).join(", ")}`);
|
|
4188
|
-
for (const [cat, vids] of videoIndex.byCategory.entries()) {
|
|
4189
|
-
console.log(` - '${cat}': ${vids.length} videos`);
|
|
4190
|
-
}
|
|
4191
|
-
return { counts, videoIndex };
|
|
4192
|
-
}
|
|
4141
|
+
console.log(`[S3ClipsService] Clip counts completed in ${elapsed.toFixed(2)}ms - Total: ${counts.total}`);
|
|
4142
|
+
if (effectiveBuildIndex && videoIndex) ;
|
|
4193
4143
|
return counts;
|
|
4194
4144
|
} finally {
|
|
4195
|
-
if (buildIndex) {
|
|
4196
|
-
this.isIndexBuilding = false;
|
|
4197
|
-
console.log(`[S3ClipsService] Index building complete - metadata fetching re-enabled`);
|
|
4198
|
-
}
|
|
4199
4145
|
}
|
|
4200
4146
|
}
|
|
4201
4147
|
async getClipCountsCacheFirst(workspaceId, date, shiftId, buildIndex) {
|
|
@@ -4216,6 +4162,10 @@ var S3ClipsService = class {
|
|
|
4216
4162
|
* Get first clip for a specific category with deduplication
|
|
4217
4163
|
*/
|
|
4218
4164
|
async getFirstClipForCategory(workspaceId, date, shiftId, category) {
|
|
4165
|
+
if (!isValidShiftId(shiftId)) {
|
|
4166
|
+
console.error(`[S3ClipsService] getFirstClipForCategory - Invalid shift ID: ${shiftId}. Must be 0 (day) or 1 (night)`);
|
|
4167
|
+
return null;
|
|
4168
|
+
}
|
|
4219
4169
|
const deduplicationKey = `first-clip:${workspaceId}:${date}:${shiftId}:${category}`;
|
|
4220
4170
|
return this.requestCache.deduplicate(
|
|
4221
4171
|
deduplicationKey,
|
|
@@ -4523,6 +4473,75 @@ var S3ClipsService = class {
|
|
|
4523
4473
|
}
|
|
4524
4474
|
return videos;
|
|
4525
4475
|
}
|
|
4476
|
+
/**
|
|
4477
|
+
* Get a page of videos for a specific category using efficient pagination
|
|
4478
|
+
* This method replaces the need for full video indexing
|
|
4479
|
+
* @param workspaceId - Workspace ID
|
|
4480
|
+
* @param date - Date in YYYY-MM-DD format
|
|
4481
|
+
* @param shiftId - Shift ID (0 for day, 1 for night)
|
|
4482
|
+
* @param category - Category to fetch videos from
|
|
4483
|
+
* @param pageSize - Number of videos to fetch per page (default 5)
|
|
4484
|
+
* @param startAfter - Optional key to start after for pagination
|
|
4485
|
+
* @returns Page of videos with continuation token
|
|
4486
|
+
*/
|
|
4487
|
+
async getVideosPage(workspaceId, date, shiftId, category, pageSize = 5, startAfter) {
|
|
4488
|
+
if (!isValidShiftId(shiftId)) {
|
|
4489
|
+
console.error(`[S3ClipsService] getVideosPage - Invalid shift ID: ${shiftId}`);
|
|
4490
|
+
return { videos: [], hasMore: false };
|
|
4491
|
+
}
|
|
4492
|
+
const categoryPrefix = `sop_violations/${workspaceId}/${date}/${shiftId}/${category}/videos/`;
|
|
4493
|
+
const deduplicationKey = `videos-page:${categoryPrefix}:${pageSize}:${startAfter || "first"}`;
|
|
4494
|
+
return this.requestCache.deduplicate(
|
|
4495
|
+
deduplicationKey,
|
|
4496
|
+
async () => {
|
|
4497
|
+
try {
|
|
4498
|
+
console.log(`[S3ClipsService] Fetching page of ${pageSize} videos for category '${category}'`);
|
|
4499
|
+
const command = new clientS3.ListObjectsV2Command({
|
|
4500
|
+
Bucket: this.config.s3Config.bucketName,
|
|
4501
|
+
Prefix: categoryPrefix,
|
|
4502
|
+
MaxKeys: pageSize * 10,
|
|
4503
|
+
// Fetch extra to account for non-playlist files
|
|
4504
|
+
StartAfter: startAfter
|
|
4505
|
+
});
|
|
4506
|
+
const response = await this.s3Client.send(command);
|
|
4507
|
+
const videos = [];
|
|
4508
|
+
if (response.Contents) {
|
|
4509
|
+
const sopCategories = this.getSOPCategories(workspaceId);
|
|
4510
|
+
for (const obj of response.Contents) {
|
|
4511
|
+
if (videos.length >= pageSize) break;
|
|
4512
|
+
if (obj.Key && obj.Key.endsWith("playlist.m3u8")) {
|
|
4513
|
+
if (obj.Key.includes("missed_qchecks")) continue;
|
|
4514
|
+
const s3Uri = `s3://${this.config.s3Config.bucketName}/${obj.Key}`;
|
|
4515
|
+
const parsedInfo = parseS3Uri(s3Uri, sopCategories);
|
|
4516
|
+
if (parsedInfo) {
|
|
4517
|
+
const cloudfrontUrl = this.s3UriToCloudfront(s3Uri);
|
|
4518
|
+
videos.push({
|
|
4519
|
+
id: `${workspaceId}-${date}-${shiftId}-${category}-${videos.length}`,
|
|
4520
|
+
src: cloudfrontUrl,
|
|
4521
|
+
...parsedInfo,
|
|
4522
|
+
originalUri: s3Uri
|
|
4523
|
+
});
|
|
4524
|
+
}
|
|
4525
|
+
}
|
|
4526
|
+
}
|
|
4527
|
+
const lastKey = response.Contents[response.Contents.length - 1]?.Key;
|
|
4528
|
+
const hasMore = !!response.IsTruncated || response.Contents.length === pageSize * 10;
|
|
4529
|
+
console.log(`[S3ClipsService] Fetched ${videos.length} videos, hasMore: ${hasMore}`);
|
|
4530
|
+
return {
|
|
4531
|
+
videos,
|
|
4532
|
+
nextToken: hasMore ? lastKey : void 0,
|
|
4533
|
+
hasMore
|
|
4534
|
+
};
|
|
4535
|
+
}
|
|
4536
|
+
return { videos: [], hasMore: false };
|
|
4537
|
+
} catch (error) {
|
|
4538
|
+
console.error(`[S3ClipsService] Error fetching videos page:`, error);
|
|
4539
|
+
return { videos: [], hasMore: false };
|
|
4540
|
+
}
|
|
4541
|
+
},
|
|
4542
|
+
"VideosPage"
|
|
4543
|
+
);
|
|
4544
|
+
}
|
|
4526
4545
|
/**
|
|
4527
4546
|
* Cleanup method for proper resource management
|
|
4528
4547
|
*/
|
|
@@ -8451,6 +8470,16 @@ function useTicketHistory(companyId) {
|
|
|
8451
8470
|
throw err;
|
|
8452
8471
|
}
|
|
8453
8472
|
}, [refreshTickets]);
|
|
8473
|
+
const updateTicketServicedStatus = React19.useCallback(async (ticketId, serviced) => {
|
|
8474
|
+
setError(null);
|
|
8475
|
+
try {
|
|
8476
|
+
await TicketHistoryService.updateTicketServicedStatus(ticketId, serviced);
|
|
8477
|
+
await refreshTickets();
|
|
8478
|
+
} catch (err) {
|
|
8479
|
+
setError(err instanceof Error ? err.message : "Failed to update ticket serviced status");
|
|
8480
|
+
throw err;
|
|
8481
|
+
}
|
|
8482
|
+
}, [refreshTickets]);
|
|
8454
8483
|
React19.useEffect(() => {
|
|
8455
8484
|
if (companyId) {
|
|
8456
8485
|
refreshTickets();
|
|
@@ -8462,7 +8491,8 @@ function useTicketHistory(companyId) {
|
|
|
8462
8491
|
error,
|
|
8463
8492
|
createTicket,
|
|
8464
8493
|
refreshTickets,
|
|
8465
|
-
updateTicketStatus
|
|
8494
|
+
updateTicketStatus,
|
|
8495
|
+
updateTicketServicedStatus
|
|
8466
8496
|
};
|
|
8467
8497
|
}
|
|
8468
8498
|
|
|
@@ -11614,7 +11644,8 @@ var usePrefetchClipCounts = ({
|
|
|
11614
11644
|
date,
|
|
11615
11645
|
shift,
|
|
11616
11646
|
enabled = true,
|
|
11617
|
-
buildIndex =
|
|
11647
|
+
buildIndex = false,
|
|
11648
|
+
// Default to false for cost efficiency
|
|
11618
11649
|
subscriberId
|
|
11619
11650
|
}) => {
|
|
11620
11651
|
const dashboardConfig = useDashboardConfig();
|
|
@@ -11623,7 +11654,18 @@ var usePrefetchClipCounts = ({
|
|
|
11623
11654
|
}, [subscriberId]);
|
|
11624
11655
|
const prefetchParams = React19.useMemo(() => {
|
|
11625
11656
|
const operationalDate = date || getOperationalDate();
|
|
11626
|
-
|
|
11657
|
+
let shiftStr;
|
|
11658
|
+
if (shift !== void 0 && shift !== null) {
|
|
11659
|
+
shiftStr = shift.toString();
|
|
11660
|
+
console.log(`[usePrefetchClipCounts] Using provided shift: ${shiftStr} for date: ${operationalDate}`);
|
|
11661
|
+
} else if (date) {
|
|
11662
|
+
shiftStr = "0";
|
|
11663
|
+
console.log(`[usePrefetchClipCounts] No shift provided for historical date ${date}, defaulting to day shift (0)`);
|
|
11664
|
+
} else {
|
|
11665
|
+
const currentShift = getCurrentShift2();
|
|
11666
|
+
shiftStr = currentShift.shiftId.toString();
|
|
11667
|
+
console.log(`[usePrefetchClipCounts] Using current operational shift: ${shiftStr} (${currentShift.shiftName})`);
|
|
11668
|
+
}
|
|
11627
11669
|
return {
|
|
11628
11670
|
workspaceId: workspaceId || "",
|
|
11629
11671
|
date: operationalDate,
|
|
@@ -11691,12 +11733,12 @@ var usePrefetchClipCounts = ({
|
|
|
11691
11733
|
}
|
|
11692
11734
|
},
|
|
11693
11735
|
onRenderReady: (key, newData) => {
|
|
11694
|
-
console.log(`[usePrefetchClipCounts] Render ready with ${Object.values(newData.counts).reduce((sum, count) => sum + count, 0)} total clips`);
|
|
11736
|
+
console.log(`[usePrefetchClipCounts] Render ready with ${Object.values(newData.counts || {}).reduce((sum, count) => sum + count, 0)} total clips`);
|
|
11695
11737
|
setData(newData);
|
|
11696
11738
|
setError(null);
|
|
11697
11739
|
},
|
|
11698
11740
|
onFullyIndexed: (key, newData) => {
|
|
11699
|
-
console.log(`[usePrefetchClipCounts] Fully indexed with ${newData.videoIndex
|
|
11741
|
+
console.log(`[usePrefetchClipCounts] Fully indexed with ${newData.videoIndex?.allVideos?.length || 0} videos`);
|
|
11700
11742
|
setData(newData);
|
|
11701
11743
|
setError(null);
|
|
11702
11744
|
},
|
|
@@ -23289,8 +23331,7 @@ var ISTTimer = React19.memo(() => {
|
|
|
23289
23331
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
23290
23332
|
TimeDisplay2,
|
|
23291
23333
|
{
|
|
23292
|
-
variant: "minimal"
|
|
23293
|
-
className: "text-sm font-medium text-gray-700"
|
|
23334
|
+
variant: "minimal"
|
|
23294
23335
|
}
|
|
23295
23336
|
);
|
|
23296
23337
|
});
|
|
@@ -23322,6 +23363,7 @@ var CardFooter2 = (props) => {
|
|
|
23322
23363
|
};
|
|
23323
23364
|
var TicketHistory = ({ companyId }) => {
|
|
23324
23365
|
const { tickets, loading, error } = useTicketHistory(companyId);
|
|
23366
|
+
const [expandedTickets, setExpandedTickets] = React19.useState(/* @__PURE__ */ new Set());
|
|
23325
23367
|
const getCategoryIcon = (category) => {
|
|
23326
23368
|
switch (category) {
|
|
23327
23369
|
case "general":
|
|
@@ -23378,6 +23420,23 @@ var TicketHistory = ({ companyId }) => {
|
|
|
23378
23420
|
return "text-gray-600 bg-gray-50";
|
|
23379
23421
|
}
|
|
23380
23422
|
};
|
|
23423
|
+
const toggleTicketExpansion = (ticketId) => {
|
|
23424
|
+
setExpandedTickets((prev) => {
|
|
23425
|
+
const newSet = new Set(prev);
|
|
23426
|
+
if (newSet.has(ticketId)) {
|
|
23427
|
+
newSet.delete(ticketId);
|
|
23428
|
+
} else {
|
|
23429
|
+
newSet.add(ticketId);
|
|
23430
|
+
}
|
|
23431
|
+
return newSet;
|
|
23432
|
+
});
|
|
23433
|
+
};
|
|
23434
|
+
const isTicketExpanded = (ticketId) => {
|
|
23435
|
+
return expandedTickets.has(ticketId);
|
|
23436
|
+
};
|
|
23437
|
+
const shouldShowExpandButton = (description) => {
|
|
23438
|
+
return description.length > 100 || description.includes("\n");
|
|
23439
|
+
};
|
|
23381
23440
|
if (loading) {
|
|
23382
23441
|
return /* @__PURE__ */ jsxRuntime.jsxs(Card2, { className: "h-full", children: [
|
|
23383
23442
|
/* @__PURE__ */ jsxRuntime.jsx(CardHeader2, { children: /* @__PURE__ */ jsxRuntime.jsx(CardTitle2, { className: "text-lg font-semibold text-gray-800", children: "History of Tickets" }) }),
|
|
@@ -23418,12 +23477,14 @@ var TicketHistory = ({ companyId }) => {
|
|
|
23418
23477
|
tickets.map((ticket, index) => {
|
|
23419
23478
|
const CategoryIcon = getCategoryIcon(ticket.category);
|
|
23420
23479
|
const StatusIcon = getStatusIcon(ticket.status);
|
|
23480
|
+
const isExpanded = isTicketExpanded(ticket.id);
|
|
23481
|
+
const showExpandButton = shouldShowExpandButton(ticket.description);
|
|
23421
23482
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
23422
23483
|
motion.div,
|
|
23423
23484
|
{
|
|
23424
23485
|
initial: { opacity: 0, y: 10 },
|
|
23425
23486
|
animate: { opacity: 1, y: 0 },
|
|
23426
|
-
className: `border-b border-gray-100 p-4 hover:bg-gray-50 transition-colors
|
|
23487
|
+
className: `border-b border-gray-100 p-4 hover:bg-gray-50 transition-colors ${index === 0 ? "border-t-0" : ""}`,
|
|
23427
23488
|
children: [
|
|
23428
23489
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-start justify-between mb-2", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 flex-1 min-w-0", children: [
|
|
23429
23490
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-1 bg-gray-100 rounded", children: /* @__PURE__ */ jsxRuntime.jsx(CategoryIcon, { className: "h-3 w-3 text-gray-600" }) }),
|
|
@@ -23434,9 +23495,42 @@ var TicketHistory = ({ companyId }) => {
|
|
|
23434
23495
|
/* @__PURE__ */ jsxRuntime.jsx(StatusIcon, { className: "h-2.5 w-2.5 mr-1" }),
|
|
23435
23496
|
ticket.status === "submitted" ? "New" : ticket.status.replace("_", " ")
|
|
23436
23497
|
] }),
|
|
23437
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `inline-flex items-center px-2 py-1 rounded-full text-xs font-medium ${getPriorityColor(ticket.priority)}`, children: ticket.priority === "normal" ? "Standard" : ticket.priority })
|
|
23498
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `inline-flex items-center px-2 py-1 rounded-full text-xs font-medium ${getPriorityColor(ticket.priority)}`, children: ticket.priority === "normal" ? "Standard" : ticket.priority }),
|
|
23499
|
+
ticket.serviced && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center px-2 py-1 rounded-full text-xs font-medium text-green-700 bg-green-100 border border-green-200", children: [
|
|
23500
|
+
/* @__PURE__ */ jsxRuntime.jsx(solid.CheckIcon, { className: "h-2.5 w-2.5 mr-1" }),
|
|
23501
|
+
"Serviced"
|
|
23502
|
+
] })
|
|
23503
|
+
] }),
|
|
23504
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-3", children: [
|
|
23505
|
+
/* @__PURE__ */ jsxRuntime.jsx(AnimatePresence, { mode: "wait", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
23506
|
+
motion.div,
|
|
23507
|
+
{
|
|
23508
|
+
initial: { opacity: 0 },
|
|
23509
|
+
animate: { opacity: 1 },
|
|
23510
|
+
exit: { opacity: 0 },
|
|
23511
|
+
transition: { duration: 0.2 },
|
|
23512
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: `text-xs text-gray-600 leading-relaxed whitespace-pre-wrap ${!isExpanded && showExpandButton ? "line-clamp-2" : ""}`, children: ticket.description })
|
|
23513
|
+
},
|
|
23514
|
+
isExpanded ? "expanded" : "collapsed"
|
|
23515
|
+
) }),
|
|
23516
|
+
showExpandButton && /* @__PURE__ */ jsxRuntime.jsx(
|
|
23517
|
+
"button",
|
|
23518
|
+
{
|
|
23519
|
+
onClick: (e) => {
|
|
23520
|
+
e.stopPropagation();
|
|
23521
|
+
toggleTicketExpansion(ticket.id);
|
|
23522
|
+
},
|
|
23523
|
+
className: "mt-2 flex items-center gap-1 text-xs text-blue-600 hover:text-blue-700 font-medium transition-colors",
|
|
23524
|
+
children: isExpanded ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
23525
|
+
/* @__PURE__ */ jsxRuntime.jsx(outline.ChevronUpIcon, { className: "h-3 w-3" }),
|
|
23526
|
+
"Show less"
|
|
23527
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
23528
|
+
/* @__PURE__ */ jsxRuntime.jsx(outline.ChevronDownIcon, { className: "h-3 w-3" }),
|
|
23529
|
+
"Show more"
|
|
23530
|
+
] })
|
|
23531
|
+
}
|
|
23532
|
+
)
|
|
23438
23533
|
] }),
|
|
23439
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-gray-600 mb-3 line-clamp-2 leading-relaxed", children: ticket.description }),
|
|
23440
23534
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between text-xs", children: [
|
|
23441
23535
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-gray-500 capitalize font-medium", children: ticket.category }),
|
|
23442
23536
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 text-gray-500", children: [
|
|
@@ -26209,6 +26303,127 @@ var VideoPlayer = React19__namespace.default.forwardRef(({
|
|
|
26209
26303
|
] });
|
|
26210
26304
|
});
|
|
26211
26305
|
VideoPlayer.displayName = "VideoPlayer";
|
|
26306
|
+
var BackButton = ({
|
|
26307
|
+
onClick,
|
|
26308
|
+
text = "Back",
|
|
26309
|
+
className,
|
|
26310
|
+
size = "default",
|
|
26311
|
+
disabled = false,
|
|
26312
|
+
"aria-label": ariaLabel
|
|
26313
|
+
}) => {
|
|
26314
|
+
const sizeClasses = {
|
|
26315
|
+
sm: {
|
|
26316
|
+
container: "gap-1 px-2 py-1.5",
|
|
26317
|
+
icon: "w-3.5 h-3.5",
|
|
26318
|
+
text: "text-xs"
|
|
26319
|
+
},
|
|
26320
|
+
default: {
|
|
26321
|
+
container: "gap-2 px-3 py-2",
|
|
26322
|
+
icon: "w-4 h-4",
|
|
26323
|
+
text: "text-sm"
|
|
26324
|
+
},
|
|
26325
|
+
lg: {
|
|
26326
|
+
container: "gap-2 px-4 py-2.5",
|
|
26327
|
+
icon: "w-5 h-5",
|
|
26328
|
+
text: "text-base"
|
|
26329
|
+
}
|
|
26330
|
+
};
|
|
26331
|
+
const currentSize = sizeClasses[size];
|
|
26332
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
26333
|
+
"button",
|
|
26334
|
+
{
|
|
26335
|
+
onClick,
|
|
26336
|
+
disabled,
|
|
26337
|
+
"aria-label": ariaLabel || `${text} button`,
|
|
26338
|
+
className: cn(
|
|
26339
|
+
// Base styles
|
|
26340
|
+
"flex items-center font-medium rounded-lg transition-all duration-200",
|
|
26341
|
+
// Size-specific styles
|
|
26342
|
+
currentSize.container,
|
|
26343
|
+
// Color and interaction styles
|
|
26344
|
+
disabled ? "text-gray-400 cursor-not-allowed" : "text-gray-600 hover:text-gray-900 hover:bg-gray-50 active:bg-gray-100",
|
|
26345
|
+
// Focus styles for accessibility
|
|
26346
|
+
"focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2",
|
|
26347
|
+
className
|
|
26348
|
+
),
|
|
26349
|
+
children: [
|
|
26350
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
26351
|
+
lucideReact.ArrowLeft,
|
|
26352
|
+
{
|
|
26353
|
+
className: cn(
|
|
26354
|
+
"flex-shrink-0",
|
|
26355
|
+
currentSize.icon,
|
|
26356
|
+
disabled && "opacity-50"
|
|
26357
|
+
)
|
|
26358
|
+
}
|
|
26359
|
+
),
|
|
26360
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
|
|
26361
|
+
"font-medium select-none",
|
|
26362
|
+
currentSize.text,
|
|
26363
|
+
disabled && "opacity-50"
|
|
26364
|
+
), children: text })
|
|
26365
|
+
]
|
|
26366
|
+
}
|
|
26367
|
+
);
|
|
26368
|
+
};
|
|
26369
|
+
var BackButtonMinimal = ({
|
|
26370
|
+
onClick,
|
|
26371
|
+
text = "Back",
|
|
26372
|
+
className,
|
|
26373
|
+
size = "default",
|
|
26374
|
+
disabled = false,
|
|
26375
|
+
"aria-label": ariaLabel
|
|
26376
|
+
}) => {
|
|
26377
|
+
const sizeClasses = {
|
|
26378
|
+
sm: {
|
|
26379
|
+
icon: "w-3.5 h-3.5",
|
|
26380
|
+
text: "text-xs ml-1"
|
|
26381
|
+
},
|
|
26382
|
+
default: {
|
|
26383
|
+
icon: "w-4 h-4",
|
|
26384
|
+
text: "text-sm ml-2"
|
|
26385
|
+
},
|
|
26386
|
+
lg: {
|
|
26387
|
+
icon: "w-5 h-5",
|
|
26388
|
+
text: "text-base ml-2"
|
|
26389
|
+
}
|
|
26390
|
+
};
|
|
26391
|
+
const currentSize = sizeClasses[size];
|
|
26392
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
26393
|
+
"button",
|
|
26394
|
+
{
|
|
26395
|
+
onClick,
|
|
26396
|
+
disabled,
|
|
26397
|
+
"aria-label": ariaLabel || `${text} button`,
|
|
26398
|
+
className: cn(
|
|
26399
|
+
// Base styles - minimal padding for tight spaces
|
|
26400
|
+
"flex items-center transition-colors duration-200",
|
|
26401
|
+
// Color and interaction styles
|
|
26402
|
+
disabled ? "text-gray-400 cursor-not-allowed" : "text-gray-600 hover:text-gray-900",
|
|
26403
|
+
// Focus styles for accessibility
|
|
26404
|
+
"focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 rounded",
|
|
26405
|
+
className
|
|
26406
|
+
),
|
|
26407
|
+
children: [
|
|
26408
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
26409
|
+
lucideReact.ArrowLeft,
|
|
26410
|
+
{
|
|
26411
|
+
className: cn(
|
|
26412
|
+
"flex-shrink-0",
|
|
26413
|
+
currentSize.icon,
|
|
26414
|
+
disabled && "opacity-50"
|
|
26415
|
+
)
|
|
26416
|
+
}
|
|
26417
|
+
),
|
|
26418
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
|
|
26419
|
+
"font-medium select-none",
|
|
26420
|
+
currentSize.text,
|
|
26421
|
+
disabled && "opacity-50"
|
|
26422
|
+
), children: text })
|
|
26423
|
+
]
|
|
26424
|
+
}
|
|
26425
|
+
);
|
|
26426
|
+
};
|
|
26212
26427
|
var BottlenecksContent = ({
|
|
26213
26428
|
workspaceId,
|
|
26214
26429
|
workspaceName,
|
|
@@ -26228,7 +26443,6 @@ var BottlenecksContent = ({
|
|
|
26228
26443
|
const videoRef = React19.useRef(null);
|
|
26229
26444
|
const timestampFilterRef = React19.useRef(null);
|
|
26230
26445
|
const initialFilter = sopCategories && sopCategories.length > 0 ? sopCategories[0].id : "low_value";
|
|
26231
|
-
const videoIndexRef = React19.useRef(null);
|
|
26232
26446
|
const currentIndexRef = React19.useRef(0);
|
|
26233
26447
|
const activeFilterRef = React19.useRef(initialFilter);
|
|
26234
26448
|
const isMountedRef = React19.useRef(true);
|
|
@@ -26246,15 +26460,6 @@ var BottlenecksContent = ({
|
|
|
26246
26460
|
const [isNavigating, setIsNavigating] = React19.useState(false);
|
|
26247
26461
|
const [error, setError] = React19.useState(null);
|
|
26248
26462
|
const [clipCounts, setClipCounts] = React19.useState({});
|
|
26249
|
-
const [videoIndex, setVideoIndex] = React19.useState(null);
|
|
26250
|
-
const updateVideoIndex = React19.useCallback((newIndex) => {
|
|
26251
|
-
console.log(`[BottlenecksContent] Updating video index - ID: ${newIndex?._debugId || "NO_ID"}, total videos: ${newIndex?.allVideos.length || 0}, categories: ${newIndex?.byCategory.size || 0}`);
|
|
26252
|
-
if (newIndex) {
|
|
26253
|
-
console.log(`[BottlenecksContent] VideoIndex categories: [${Array.from(newIndex.byCategory.keys()).join(", ")}]`);
|
|
26254
|
-
}
|
|
26255
|
-
setVideoIndex(newIndex);
|
|
26256
|
-
videoIndexRef.current = newIndex;
|
|
26257
|
-
}, []);
|
|
26258
26463
|
const updateActiveFilter = React19.useCallback((newFilter) => {
|
|
26259
26464
|
console.log(`[BottlenecksContent] Updating active filter: ${activeFilterRef.current} -> ${newFilter}`);
|
|
26260
26465
|
setActiveFilter(newFilter);
|
|
@@ -26290,6 +26495,21 @@ var BottlenecksContent = ({
|
|
|
26290
26495
|
}
|
|
26291
26496
|
return videoPrefetchManager.getS3Service(dashboardConfig);
|
|
26292
26497
|
}, [dashboardConfig]);
|
|
26498
|
+
const effectiveShift = React19.useMemo(() => {
|
|
26499
|
+
if (shift !== void 0 && shift !== null) {
|
|
26500
|
+
const shiftStr = shift.toString();
|
|
26501
|
+
console.log(`[BottlenecksContent] Using provided shift: ${shiftStr} for date: ${date}`);
|
|
26502
|
+
return shiftStr;
|
|
26503
|
+
}
|
|
26504
|
+
if (date) {
|
|
26505
|
+
console.log(`[BottlenecksContent] No shift provided for historical date ${date}, defaulting to day shift (0)`);
|
|
26506
|
+
return "0";
|
|
26507
|
+
} else {
|
|
26508
|
+
const currentShift = getCurrentShift2();
|
|
26509
|
+
console.log(`[BottlenecksContent] Using current operational shift: ${currentShift.shiftId} (${currentShift.shiftName})`);
|
|
26510
|
+
return currentShift.shiftId.toString();
|
|
26511
|
+
}
|
|
26512
|
+
}, [shift, date]);
|
|
26293
26513
|
const {
|
|
26294
26514
|
data: prefetchData,
|
|
26295
26515
|
isFullyIndexed,
|
|
@@ -26298,9 +26518,10 @@ var BottlenecksContent = ({
|
|
|
26298
26518
|
} = usePrefetchClipCounts({
|
|
26299
26519
|
workspaceId,
|
|
26300
26520
|
date: date || getOperationalDate(),
|
|
26301
|
-
shift:
|
|
26521
|
+
shift: effectiveShift,
|
|
26302
26522
|
enabled: !!workspaceId && !!s3ClipsService,
|
|
26303
|
-
buildIndex:
|
|
26523
|
+
buildIndex: false
|
|
26524
|
+
// Disabled to reduce S3 costs - use pagination instead
|
|
26304
26525
|
});
|
|
26305
26526
|
const fetchClipCounts = React19.useCallback(async () => {
|
|
26306
26527
|
if (!workspaceId || !s3ClipsService || !dashboardConfig?.s3Config || !isMountedRef.current) return;
|
|
@@ -26312,14 +26533,13 @@ var BottlenecksContent = ({
|
|
|
26312
26533
|
fetchInProgressRef.current.add(operationKey);
|
|
26313
26534
|
try {
|
|
26314
26535
|
const operationalDate = date || getOperationalDate();
|
|
26315
|
-
const shiftStr =
|
|
26536
|
+
const shiftStr = effectiveShift;
|
|
26316
26537
|
console.log(`[BottlenecksContent] Fetching clip counts directly for ${workspaceId}`);
|
|
26317
26538
|
const cacheKey = `clip-counts:${workspaceId}:${operationalDate}:${shiftStr}`;
|
|
26318
26539
|
const cachedResult = await smartVideoCache.getClipCounts(cacheKey);
|
|
26319
26540
|
if (cachedResult) {
|
|
26320
26541
|
console.log(`[BottlenecksContent] Using cached clip counts`);
|
|
26321
26542
|
updateClipCounts(cachedResult.counts);
|
|
26322
|
-
updateVideoIndex(cachedResult.videoIndex);
|
|
26323
26543
|
setIsLoading(false);
|
|
26324
26544
|
setHasInitialLoad(true);
|
|
26325
26545
|
return;
|
|
@@ -26328,19 +26548,13 @@ var BottlenecksContent = ({
|
|
|
26328
26548
|
const fullResult = await s3ClipsService.getClipCounts(
|
|
26329
26549
|
workspaceId,
|
|
26330
26550
|
operationalDate,
|
|
26331
|
-
shiftStr
|
|
26332
|
-
|
|
26333
|
-
// Build index
|
|
26551
|
+
shiftStr
|
|
26552
|
+
// Don't build index - use pagination for cost efficiency
|
|
26334
26553
|
);
|
|
26335
|
-
if (fullResult
|
|
26336
|
-
updateClipCounts(fullResult.counts);
|
|
26337
|
-
updateVideoIndex(fullResult.videoIndex);
|
|
26338
|
-
await smartVideoCache.setClipCounts(cacheKey, fullResult, 5);
|
|
26339
|
-
console.log(`[BottlenecksContent] Fetched and cached clip counts with ${fullResult.videoIndex.allVideos.length} videos`);
|
|
26340
|
-
} else if (fullResult) {
|
|
26554
|
+
if (fullResult) {
|
|
26341
26555
|
const counts = fullResult;
|
|
26342
26556
|
updateClipCounts(counts);
|
|
26343
|
-
console.log(`[BottlenecksContent] Fetched clip counts
|
|
26557
|
+
console.log(`[BottlenecksContent] Fetched and cached clip counts`);
|
|
26344
26558
|
}
|
|
26345
26559
|
setIsLoading(false);
|
|
26346
26560
|
setHasInitialLoad(true);
|
|
@@ -26353,7 +26567,7 @@ var BottlenecksContent = ({
|
|
|
26353
26567
|
} finally {
|
|
26354
26568
|
fetchInProgressRef.current.delete(operationKey);
|
|
26355
26569
|
}
|
|
26356
|
-
}, [workspaceId, date, s3ClipsService,
|
|
26570
|
+
}, [workspaceId, date, s3ClipsService, effectiveShift, dashboardConfig, updateClipCounts]);
|
|
26357
26571
|
const loadingCategoryRef = React19.useRef(null);
|
|
26358
26572
|
const videoRetryCountRef = React19.useRef(0);
|
|
26359
26573
|
const loadingVideosRef = React19.useRef(/* @__PURE__ */ new Set());
|
|
@@ -26361,7 +26575,6 @@ var BottlenecksContent = ({
|
|
|
26361
26575
|
const ensureVideosLoaded = React19.useCallback(async (centerIndex) => {
|
|
26362
26576
|
if (!s3ClipsService || !workspaceId || !isMountedRef.current) return;
|
|
26363
26577
|
const currentFilter = activeFilterRef.current;
|
|
26364
|
-
const currentVideoIndex = videoIndexRef.current;
|
|
26365
26578
|
let effectiveFilter = currentFilter;
|
|
26366
26579
|
if (sopCategories && sopCategories.length > 0) {
|
|
26367
26580
|
const category = sopCategories.find((cat) => cat.id === currentFilter);
|
|
@@ -26388,20 +26601,9 @@ var BottlenecksContent = ({
|
|
|
26388
26601
|
const loadPromises = indicesToLoad.map(async (index) => {
|
|
26389
26602
|
try {
|
|
26390
26603
|
let video = null;
|
|
26391
|
-
if (currentVideoIndex && currentVideoIndex.byCategory && currentVideoIndex.allVideos.length > 0) {
|
|
26392
|
-
video = await s3ClipsService.getVideoFromIndex(
|
|
26393
|
-
currentVideoIndex,
|
|
26394
|
-
effectiveFilter,
|
|
26395
|
-
index,
|
|
26396
|
-
true,
|
|
26397
|
-
// includeCycleTime - OK for preloading
|
|
26398
|
-
false
|
|
26399
|
-
// includeMetadata - NO metadata during bulk preloading to prevent flooding
|
|
26400
|
-
);
|
|
26401
|
-
}
|
|
26402
26604
|
if (!video) {
|
|
26403
26605
|
const operationalDate = date || getOperationalDate();
|
|
26404
|
-
const shiftStr =
|
|
26606
|
+
const shiftStr = effectiveShift;
|
|
26405
26607
|
video = await s3ClipsService.getClipByIndex(
|
|
26406
26608
|
workspaceId,
|
|
26407
26609
|
operationalDate,
|
|
@@ -26434,7 +26636,7 @@ var BottlenecksContent = ({
|
|
|
26434
26636
|
Promise.all(loadPromises).catch((err) => {
|
|
26435
26637
|
console.warn("[ensureVideosLoaded] Some videos failed to preload:", err);
|
|
26436
26638
|
});
|
|
26437
|
-
}, [s3ClipsService, workspaceId, clipCounts, sopCategories, date,
|
|
26639
|
+
}, [s3ClipsService, workspaceId, clipCounts, sopCategories, date, effectiveShift]);
|
|
26438
26640
|
const loadFirstVideoForCategory = React19.useCallback(async (category) => {
|
|
26439
26641
|
if (!workspaceId || !s3ClipsService || !isMountedRef.current) return;
|
|
26440
26642
|
const targetCategory = category || activeFilterRef.current;
|
|
@@ -26450,13 +26652,12 @@ var BottlenecksContent = ({
|
|
|
26450
26652
|
}
|
|
26451
26653
|
try {
|
|
26452
26654
|
const operationalDate = date || getOperationalDate();
|
|
26453
|
-
const shiftStr =
|
|
26454
|
-
if (!clipCounts[targetCategory]
|
|
26655
|
+
const shiftStr = effectiveShift;
|
|
26656
|
+
if (!clipCounts[targetCategory]) {
|
|
26455
26657
|
const cacheKey = `clip-counts:${workspaceId}:${operationalDate}:${shiftStr}`;
|
|
26456
26658
|
const cachedResult = await smartVideoCache.getClipCounts(cacheKey);
|
|
26457
26659
|
if (cachedResult && cachedResult.counts[targetCategory] > 0) {
|
|
26458
26660
|
updateClipCounts(cachedResult.counts);
|
|
26459
|
-
updateVideoIndex(cachedResult.videoIndex);
|
|
26460
26661
|
setHasInitialLoad(true);
|
|
26461
26662
|
console.log(`[BottlenecksContent] Used cached data for loadFirstVideoForCategory - ${targetCategory}`);
|
|
26462
26663
|
}
|
|
@@ -26488,11 +26689,14 @@ var BottlenecksContent = ({
|
|
|
26488
26689
|
} catch (directError) {
|
|
26489
26690
|
console.warn(`[BottlenecksContent] Direct S3 loading failed, trying video index:`, directError);
|
|
26490
26691
|
}
|
|
26491
|
-
|
|
26492
|
-
if (clipCounts[targetCategory] > 0 && currentVideoIndex && currentVideoIndex.allVideos.length > 0) {
|
|
26692
|
+
if (clipCounts[targetCategory] > 0) {
|
|
26493
26693
|
try {
|
|
26494
|
-
const
|
|
26495
|
-
|
|
26694
|
+
const operationalDate2 = date || getOperationalDate();
|
|
26695
|
+
const shiftStr2 = effectiveShift;
|
|
26696
|
+
const firstVideo = await s3ClipsService.getClipByIndex(
|
|
26697
|
+
workspaceId,
|
|
26698
|
+
operationalDate2,
|
|
26699
|
+
shiftStr2,
|
|
26496
26700
|
targetCategory,
|
|
26497
26701
|
0,
|
|
26498
26702
|
// First video (index 0)
|
|
@@ -26532,25 +26736,22 @@ var BottlenecksContent = ({
|
|
|
26532
26736
|
loadingCategoryRef.current = null;
|
|
26533
26737
|
fetchInProgressRef.current.delete(operationKey);
|
|
26534
26738
|
}
|
|
26535
|
-
}, [workspaceId, date, s3ClipsService, clipCounts,
|
|
26739
|
+
}, [workspaceId, date, s3ClipsService, clipCounts, effectiveShift, updateClipCounts]);
|
|
26536
26740
|
React19.useEffect(() => {
|
|
26537
26741
|
if (s3ClipsService && !prefetchData) {
|
|
26538
26742
|
fetchClipCounts();
|
|
26539
26743
|
}
|
|
26540
|
-
}, [workspaceId, date,
|
|
26744
|
+
}, [workspaceId, date, effectiveShift, s3ClipsService, fetchClipCounts, updateClipCounts, prefetchData]);
|
|
26541
26745
|
React19.useEffect(() => {
|
|
26542
|
-
if (prefetchData) {
|
|
26543
|
-
console.log(`[BottlenecksContent] Received prefetch update - status: ${prefetchStatus}
|
|
26746
|
+
if (prefetchData && prefetchData.counts) {
|
|
26747
|
+
console.log(`[BottlenecksContent] Received prefetch update - status: ${prefetchStatus}`);
|
|
26544
26748
|
updateClipCounts(prefetchData.counts);
|
|
26545
|
-
if (
|
|
26546
|
-
updateVideoIndex(prefetchData.videoIndex);
|
|
26547
|
-
}
|
|
26548
|
-
if (!hasInitialLoad && prefetchData.videoIndex.allVideos.length > 0) {
|
|
26749
|
+
if (!hasInitialLoad) {
|
|
26549
26750
|
setIsLoading(false);
|
|
26550
26751
|
setHasInitialLoad(true);
|
|
26551
26752
|
}
|
|
26552
26753
|
}
|
|
26553
|
-
}, [prefetchData, prefetchStatus, updateClipCounts,
|
|
26754
|
+
}, [prefetchData, prefetchStatus, updateClipCounts, hasInitialLoad]);
|
|
26554
26755
|
React19.useEffect(() => {
|
|
26555
26756
|
if (s3ClipsService && clipCounts[activeFilter] > 0) {
|
|
26556
26757
|
const hasVideosForCurrentFilter = allVideos.some((video) => {
|
|
@@ -26590,7 +26791,7 @@ var BottlenecksContent = ({
|
|
|
26590
26791
|
setIsCategoryLoading(false);
|
|
26591
26792
|
}
|
|
26592
26793
|
}
|
|
26593
|
-
}, [activeFilter, s3ClipsService,
|
|
26794
|
+
}, [activeFilter, s3ClipsService, clipCounts, loadFirstVideoForCategory, allVideos, sopCategories]);
|
|
26594
26795
|
React19.useEffect(() => {
|
|
26595
26796
|
if (previousFilterRef.current !== activeFilter) {
|
|
26596
26797
|
console.log(`Filter changed from ${previousFilterRef.current} to ${activeFilter} - resetting to first video`);
|
|
@@ -26706,25 +26907,9 @@ var BottlenecksContent = ({
|
|
|
26706
26907
|
}
|
|
26707
26908
|
try {
|
|
26708
26909
|
let video = null;
|
|
26709
|
-
|
|
26710
|
-
if (currentVideoIndex && currentVideoIndex.byCategory && currentVideoIndex.allVideos.length > 0 && s3ClipsService) {
|
|
26711
|
-
console.log(`[BottlenecksContent] Using video index for navigation - ID: ${currentVideoIndex._debugId || "NO_ID"}, total categories: ${currentVideoIndex.byCategory.size}, total videos: ${currentVideoIndex.allVideos.length}, filter: ${currentFilter}`);
|
|
26712
|
-
console.log(`[BottlenecksContent] VideoIndex categories in handleNext: [${Array.from(currentVideoIndex.byCategory.keys()).join(", ")}]`);
|
|
26713
|
-
video = await s3ClipsService.getVideoFromIndex(
|
|
26714
|
-
currentVideoIndex,
|
|
26715
|
-
effectiveFilter,
|
|
26716
|
-
nextIndex,
|
|
26717
|
-
true,
|
|
26718
|
-
// includeCycleTime
|
|
26719
|
-
false
|
|
26720
|
-
// includeMetadata - DON'T fetch metadata during navigation to prevent flooding!
|
|
26721
|
-
);
|
|
26722
|
-
} else {
|
|
26723
|
-
console.warn(`[BottlenecksContent] Video index not ready for navigation: ID: ${currentVideoIndex?._debugId || "NO_ID"}, byCategory exists = ${!!currentVideoIndex?.byCategory}, allVideos = ${currentVideoIndex?.allVideos?.length || 0}`);
|
|
26724
|
-
}
|
|
26725
|
-
if (!video && s3ClipsService) {
|
|
26910
|
+
if (s3ClipsService) {
|
|
26726
26911
|
const operationalDate = date || getOperationalDate();
|
|
26727
|
-
const shiftStr =
|
|
26912
|
+
const shiftStr = effectiveShift;
|
|
26728
26913
|
video = await s3ClipsService.getClipByIndex(
|
|
26729
26914
|
workspaceId,
|
|
26730
26915
|
operationalDate,
|
|
@@ -26760,7 +26945,7 @@ var BottlenecksContent = ({
|
|
|
26760
26945
|
}
|
|
26761
26946
|
}
|
|
26762
26947
|
}
|
|
26763
|
-
}, [clipCounts, filteredVideos.length, s3ClipsService, workspaceId, date,
|
|
26948
|
+
}, [clipCounts, filteredVideos.length, s3ClipsService, workspaceId, date, effectiveShift]);
|
|
26764
26949
|
const handlePrevious = React19.useCallback(() => {
|
|
26765
26950
|
if (!isMountedRef.current) return;
|
|
26766
26951
|
const currentIdx = currentIndexRef.current;
|
|
@@ -30780,16 +30965,13 @@ var AIAgentView = () => {
|
|
|
30780
30965
|
} }),
|
|
30781
30966
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex-1 flex flex-col h-screen transition-all duration-300 ${isSidebarOpen ? "mr-80" : "mr-0"}`, children: [
|
|
30782
30967
|
/* @__PURE__ */ jsxRuntime.jsx("header", { className: "flex-shrink-0 bg-white px-8 py-6 shadow-sm border-b border-gray-200/80 sticky top-0 z-10", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between relative", children: [
|
|
30783
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-0", children: /* @__PURE__ */ jsxRuntime.
|
|
30784
|
-
|
|
30968
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
30969
|
+
BackButtonMinimal,
|
|
30785
30970
|
{
|
|
30786
30971
|
onClick: () => navigate("/"),
|
|
30787
|
-
|
|
30788
|
-
|
|
30789
|
-
|
|
30790
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowLeft, { className: "h-5 w-5" }),
|
|
30791
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-2", children: "Back" })
|
|
30792
|
-
]
|
|
30972
|
+
text: "Back",
|
|
30973
|
+
size: "default",
|
|
30974
|
+
"aria-label": "Navigate back to dashboard"
|
|
30793
30975
|
}
|
|
30794
30976
|
) }),
|
|
30795
30977
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 text-center mx-auto", children: [
|
|
@@ -31458,15 +31640,13 @@ var HelpView = ({
|
|
|
31458
31640
|
transition: { duration: 0.3 },
|
|
31459
31641
|
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
|
|
31460
31642
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-white px-8 py-6 shadow-sm border-b border-gray-200/80", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between relative", children: [
|
|
31461
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-0", children: /* @__PURE__ */ jsxRuntime.
|
|
31462
|
-
|
|
31643
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
31644
|
+
BackButtonMinimal,
|
|
31463
31645
|
{
|
|
31464
31646
|
onClick: handleBackClick,
|
|
31465
|
-
|
|
31466
|
-
|
|
31467
|
-
|
|
31468
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-2", children: "Back" })
|
|
31469
|
-
]
|
|
31647
|
+
text: "Back",
|
|
31648
|
+
size: "default",
|
|
31649
|
+
"aria-label": "Navigate back to dashboard"
|
|
31470
31650
|
}
|
|
31471
31651
|
) }),
|
|
31472
31652
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 text-center mx-auto", children: [
|
|
@@ -31496,10 +31676,7 @@ var HelpView = ({
|
|
|
31496
31676
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "xl:col-span-3 order-1", children: /* @__PURE__ */ jsxRuntime.jsxs(Card2, { className: "shadow-lg border-gray-200 bg-white", children: [
|
|
31497
31677
|
/* @__PURE__ */ jsxRuntime.jsx(CardHeader2, { className: "bg-gradient-to-r from-blue-50 to-indigo-50 border-b border-gray-100 p-4 sm:p-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 sm:gap-3", children: [
|
|
31498
31678
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-1.5 sm:p-2 bg-blue-100 rounded-lg", children: /* @__PURE__ */ jsxRuntime.jsx(outline.DocumentTextIcon, { className: "h-4 w-4 sm:h-5 sm:w-5 text-blue-600" }) }),
|
|
31499
|
-
/* @__PURE__ */ jsxRuntime.
|
|
31500
|
-
/* @__PURE__ */ jsxRuntime.jsx(CardTitle2, { className: "text-lg sm:text-xl font-bold text-gray-900", children: "Submit Support Request" }),
|
|
31501
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs sm:text-sm text-gray-600 mt-1", children: "Direct line to our engineering team \u2022 Avg. response time: <30 minutes" })
|
|
31502
|
-
] })
|
|
31679
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(CardTitle2, { className: "text-lg sm:text-xl font-bold text-gray-900", children: "Submit Support Request" }) })
|
|
31503
31680
|
] }) }),
|
|
31504
31681
|
/* @__PURE__ */ jsxRuntime.jsx(CardContent2, { className: "p-4 sm:p-6", children: /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleSubmit, className: "space-y-4 sm:space-y-5", children: [
|
|
31505
31682
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4 sm:space-y-5", children: [
|
|
@@ -32593,17 +32770,15 @@ var KPIDetailView = ({
|
|
|
32593
32770
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-h-screen bg-gray-50 flex flex-col", children: [
|
|
32594
32771
|
/* @__PURE__ */ jsxRuntime.jsx("header", { className: "sticky top-0 z-10 bg-white border-b flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-4 py-3", children: [
|
|
32595
32772
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center relative", children: [
|
|
32596
|
-
/* @__PURE__ */ jsxRuntime.
|
|
32597
|
-
|
|
32773
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
32774
|
+
BackButtonMinimal,
|
|
32598
32775
|
{
|
|
32599
32776
|
onClick: handleBackClick,
|
|
32600
|
-
|
|
32601
|
-
|
|
32602
|
-
|
|
32603
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-2", children: "Back" })
|
|
32604
|
-
]
|
|
32777
|
+
text: "Back",
|
|
32778
|
+
size: "default",
|
|
32779
|
+
"aria-label": "Navigate back to previous page"
|
|
32605
32780
|
}
|
|
32606
|
-
),
|
|
32781
|
+
) }),
|
|
32607
32782
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
32608
32783
|
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-3xl font-semibold text-gray-900", children: lineInfo?.line_name || "Line" }),
|
|
32609
32784
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-2 w-2 rounded-full bg-green-500 animate-pulse ring-2 ring-green-500/30 ring-offset-1" })
|
|
@@ -32965,17 +33140,15 @@ var KPIsOverviewView = ({
|
|
|
32965
33140
|
if (error) {
|
|
32966
33141
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-h-screen bg-gray-50 flex flex-col", children: [
|
|
32967
33142
|
/* @__PURE__ */ jsxRuntime.jsx("header", { className: "sticky top-0 z-10 bg-white border-b flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 py-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center relative", children: [
|
|
32968
|
-
/* @__PURE__ */ jsxRuntime.
|
|
32969
|
-
|
|
33143
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
33144
|
+
BackButtonMinimal,
|
|
32970
33145
|
{
|
|
32971
33146
|
onClick: handleBackClick,
|
|
32972
|
-
|
|
32973
|
-
|
|
32974
|
-
|
|
32975
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-2", children: "Back" })
|
|
32976
|
-
]
|
|
33147
|
+
text: "Back",
|
|
33148
|
+
size: "default",
|
|
33149
|
+
"aria-label": "Navigate back to previous page"
|
|
32977
33150
|
}
|
|
32978
|
-
),
|
|
33151
|
+
) }),
|
|
32979
33152
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
32980
33153
|
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-3xl font-semibold text-gray-900", children: "Shop-floor overview" }),
|
|
32981
33154
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-2 w-2 rounded-full bg-green-500 animate-pulse ring-2 ring-green-500/30 ring-offset-1" })
|
|
@@ -32987,17 +33160,15 @@ var KPIsOverviewView = ({
|
|
|
32987
33160
|
if (lines.length === 0) {
|
|
32988
33161
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-h-screen bg-gray-50 flex flex-col", children: [
|
|
32989
33162
|
/* @__PURE__ */ jsxRuntime.jsx("header", { className: "sticky top-0 z-10 bg-white border-b flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 py-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center relative", children: [
|
|
32990
|
-
/* @__PURE__ */ jsxRuntime.
|
|
32991
|
-
|
|
33163
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
33164
|
+
BackButtonMinimal,
|
|
32992
33165
|
{
|
|
32993
33166
|
onClick: handleBackClick,
|
|
32994
|
-
|
|
32995
|
-
|
|
32996
|
-
|
|
32997
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-2", children: "Back" })
|
|
32998
|
-
]
|
|
33167
|
+
text: "Back",
|
|
33168
|
+
size: "default",
|
|
33169
|
+
"aria-label": "Navigate back to previous page"
|
|
32999
33170
|
}
|
|
33000
|
-
),
|
|
33171
|
+
) }),
|
|
33001
33172
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
33002
33173
|
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-3xl font-semibold text-gray-900", children: "Shop-floor overview" }),
|
|
33003
33174
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-2 w-2 rounded-full bg-green-500 animate-pulse ring-2 ring-green-500/30 ring-offset-1" })
|
|
@@ -33012,17 +33183,15 @@ var KPIsOverviewView = ({
|
|
|
33012
33183
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-h-screen bg-gray-50 flex flex-col", children: [
|
|
33013
33184
|
/* @__PURE__ */ jsxRuntime.jsx("header", { className: "sticky top-0 z-10 bg-white border-b flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-4 py-3", children: [
|
|
33014
33185
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center relative", children: [
|
|
33015
|
-
/* @__PURE__ */ jsxRuntime.
|
|
33016
|
-
|
|
33186
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
33187
|
+
BackButtonMinimal,
|
|
33017
33188
|
{
|
|
33018
33189
|
onClick: handleBackClick,
|
|
33019
|
-
|
|
33020
|
-
|
|
33021
|
-
|
|
33022
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-2", children: "Back" })
|
|
33023
|
-
]
|
|
33190
|
+
text: "Back",
|
|
33191
|
+
size: "default",
|
|
33192
|
+
"aria-label": "Navigate back to previous page"
|
|
33024
33193
|
}
|
|
33025
|
-
),
|
|
33194
|
+
) }),
|
|
33026
33195
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
33027
33196
|
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-3xl font-semibold text-gray-900", children: "Shop-floor overview" }),
|
|
33028
33197
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-2 w-2 rounded-full bg-green-500 animate-pulse ring-2 ring-green-500/30 ring-offset-1" })
|
|
@@ -33306,18 +33475,13 @@ var LeaderboardDetailView = React19.memo(({
|
|
|
33306
33475
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `min-h-screen bg-slate-50 flex flex-col ${className}`, children: [
|
|
33307
33476
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "sticky top-0 z-20 bg-white shadow-sm border-b border-gray-200/80", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-3 sm:px-8 py-2 sm:py-2.5", children: [
|
|
33308
33477
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
|
|
33309
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-auto sm:w-32", children: /* @__PURE__ */ jsxRuntime.
|
|
33310
|
-
|
|
33478
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-auto sm:w-32", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
33479
|
+
BackButtonMinimal,
|
|
33311
33480
|
{
|
|
33312
33481
|
onClick: handleBackClick,
|
|
33313
|
-
|
|
33314
|
-
|
|
33315
|
-
|
|
33316
|
-
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M19 12H5" }),
|
|
33317
|
-
/* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "12 19 5 12 12 5" })
|
|
33318
|
-
] }),
|
|
33319
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs sm:text-sm font-medium", children: "Back" })
|
|
33320
|
-
]
|
|
33482
|
+
text: "Back",
|
|
33483
|
+
size: "default",
|
|
33484
|
+
"aria-label": "Navigate back to previous page"
|
|
33321
33485
|
}
|
|
33322
33486
|
) }),
|
|
33323
33487
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 sm:gap-3", children: [
|
|
@@ -34378,18 +34542,15 @@ var ShiftsView = ({
|
|
|
34378
34542
|
}, [lineConfigs, supabase, showToast]);
|
|
34379
34543
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `min-h-screen bg-slate-50 ${className}`, children: [
|
|
34380
34544
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "sticky top-0 z-10 bg-white border-b border-gray-200/80 shadow-sm", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 sm:px-8 py-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center relative", children: [
|
|
34381
|
-
/* @__PURE__ */ jsxRuntime.
|
|
34382
|
-
|
|
34545
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
34546
|
+
BackButtonMinimal,
|
|
34383
34547
|
{
|
|
34384
34548
|
onClick: () => onBackClick ? onBackClick() : window.history.back(),
|
|
34385
|
-
|
|
34386
|
-
|
|
34387
|
-
|
|
34388
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowLeft, { className: "w-5 h-5" }),
|
|
34389
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: "Back" })
|
|
34390
|
-
]
|
|
34549
|
+
text: "Back",
|
|
34550
|
+
size: "default",
|
|
34551
|
+
"aria-label": "Navigate back to previous page"
|
|
34391
34552
|
}
|
|
34392
|
-
),
|
|
34553
|
+
) }),
|
|
34393
34554
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 flex flex-col items-center", children: [
|
|
34394
34555
|
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-3xl font-semibold text-gray-900", children: "Shift Management" }),
|
|
34395
34556
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-gray-500 mt-1", children: "Configure day and night shift timings and breaks for each production line" })
|
|
@@ -35298,15 +35459,13 @@ var TargetsViewUI = ({
|
|
|
35298
35459
|
}
|
|
35299
35460
|
return /* @__PURE__ */ jsxRuntime.jsxs("main", { className: "min-h-screen flex-1 bg-gray-50", children: [
|
|
35300
35461
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-white px-8 py-6 shadow-sm border-b border-gray-200/80", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between relative", children: [
|
|
35301
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-0", children: /* @__PURE__ */ jsxRuntime.
|
|
35302
|
-
|
|
35462
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
35463
|
+
BackButtonMinimal,
|
|
35303
35464
|
{
|
|
35304
35465
|
onClick: onBack,
|
|
35305
|
-
|
|
35306
|
-
|
|
35307
|
-
|
|
35308
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-2", children: "Back" })
|
|
35309
|
-
]
|
|
35466
|
+
text: "Back",
|
|
35467
|
+
size: "default",
|
|
35468
|
+
"aria-label": "Navigate back to previous page"
|
|
35310
35469
|
}
|
|
35311
35470
|
) }),
|
|
35312
35471
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute right-0", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -36623,15 +36782,13 @@ var WorkspaceDetailView = ({
|
|
|
36623
36782
|
"Error: ",
|
|
36624
36783
|
error.message
|
|
36625
36784
|
] }),
|
|
36626
|
-
/* @__PURE__ */ jsxRuntime.
|
|
36627
|
-
|
|
36785
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
36786
|
+
BackButton,
|
|
36628
36787
|
{
|
|
36629
36788
|
onClick: () => onNavigate && onNavigate("/"),
|
|
36630
|
-
|
|
36631
|
-
|
|
36632
|
-
|
|
36633
|
-
"Return to Dashboard"
|
|
36634
|
-
]
|
|
36789
|
+
text: "Return to Dashboard",
|
|
36790
|
+
size: "default",
|
|
36791
|
+
"aria-label": "Return to dashboard"
|
|
36635
36792
|
}
|
|
36636
36793
|
)
|
|
36637
36794
|
] });
|
|
@@ -36639,15 +36796,13 @@ var WorkspaceDetailView = ({
|
|
|
36639
36796
|
if (!workspace) {
|
|
36640
36797
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-h-screen p-8 bg-slate-50", children: [
|
|
36641
36798
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-4 text-xl text-gray-600", children: "Workspace not found" }),
|
|
36642
|
-
/* @__PURE__ */ jsxRuntime.
|
|
36643
|
-
|
|
36799
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
36800
|
+
BackButton,
|
|
36644
36801
|
{
|
|
36645
36802
|
onClick: () => onNavigate && onNavigate("/"),
|
|
36646
|
-
|
|
36647
|
-
|
|
36648
|
-
|
|
36649
|
-
"Return to Dashboard"
|
|
36650
|
-
]
|
|
36803
|
+
text: "Return to Dashboard",
|
|
36804
|
+
size: "default",
|
|
36805
|
+
"aria-label": "Return to dashboard"
|
|
36651
36806
|
}
|
|
36652
36807
|
)
|
|
36653
36808
|
] });
|
|
@@ -36662,17 +36817,15 @@ var WorkspaceDetailView = ({
|
|
|
36662
36817
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-h-screen w-full flex flex-col bg-slate-50", children: [
|
|
36663
36818
|
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "sticky top-0 z-10 px-2 sm:px-2.5 lg:px-3 py-1.5 sm:py-2 lg:py-3 flex flex-col shadow-sm bg-white", children: [
|
|
36664
36819
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex items-center", children: [
|
|
36665
|
-
/* @__PURE__ */ jsxRuntime.
|
|
36666
|
-
|
|
36820
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-0 z-10", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
36821
|
+
BackButtonMinimal,
|
|
36667
36822
|
{
|
|
36668
36823
|
onClick: handleBackNavigation,
|
|
36669
|
-
|
|
36670
|
-
|
|
36671
|
-
|
|
36672
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm sm:text-sm lg:text-base", children: previousView === "line_monthly_history" ? "Back to Line History" : returnUrl && returnUrl.includes("monthly_history") ? "Back to Line History" : returnUrl && returnUrl.includes("/kpis/") ? "Back to KPIs" : returnUrl && returnUrl.includes("/leaderboard/") ? "Back to Leaderboard" : date || shift ? "Back to Monthly History" : "Back" })
|
|
36673
|
-
]
|
|
36824
|
+
text: previousView === "line_monthly_history" ? "Back to Line History" : returnUrl && returnUrl.includes("monthly_history") ? "Back to Line History" : returnUrl && returnUrl.includes("/kpis/") ? "Back to KPIs" : returnUrl && returnUrl.includes("/leaderboard/") ? "Back to Leaderboard" : date || shift ? "Back to Monthly History" : "Back",
|
|
36825
|
+
size: "default",
|
|
36826
|
+
"aria-label": "Navigate back to previous page"
|
|
36674
36827
|
}
|
|
36675
|
-
),
|
|
36828
|
+
) }),
|
|
36676
36829
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute left-1/2 transform -translate-x-1/2 flex items-center gap-3", children: [
|
|
36677
36830
|
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-3xl font-semibold text-gray-900", children: formattedWorkspaceName }),
|
|
36678
36831
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-2 w-2 rounded-full bg-green-500 animate-pulse ring-2 ring-green-500/30 ring-offset-1" })
|
|
@@ -37180,17 +37333,15 @@ var SKUManagementView = () => {
|
|
|
37180
37333
|
}
|
|
37181
37334
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-h-screen bg-slate-50", children: [
|
|
37182
37335
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "sticky top-0 z-10 bg-white border-b border-gray-200/80 shadow-sm", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 sm:px-8 py-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center relative", children: [
|
|
37183
|
-
/* @__PURE__ */ jsxRuntime.
|
|
37184
|
-
|
|
37336
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
37337
|
+
BackButtonMinimal,
|
|
37185
37338
|
{
|
|
37186
37339
|
onClick: handleBack,
|
|
37187
|
-
|
|
37188
|
-
|
|
37189
|
-
|
|
37190
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Back" })
|
|
37191
|
-
]
|
|
37340
|
+
text: "Back",
|
|
37341
|
+
size: "default",
|
|
37342
|
+
"aria-label": "Navigate back to previous page"
|
|
37192
37343
|
}
|
|
37193
|
-
),
|
|
37344
|
+
) }),
|
|
37194
37345
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 text-center mx-auto", children: [
|
|
37195
37346
|
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-3xl font-semibold text-gray-900", children: "SKU Management" }),
|
|
37196
37347
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-sm text-gray-500", children: "Manage Stock Keeping Units (SKUs) for production planning" })
|
|
@@ -37708,6 +37859,8 @@ exports.AuthenticatedHelpView = AuthenticatedHelpView;
|
|
|
37708
37859
|
exports.AuthenticatedHomeView = AuthenticatedHomeView;
|
|
37709
37860
|
exports.AuthenticatedShiftsView = AuthenticatedShiftsView;
|
|
37710
37861
|
exports.AuthenticatedTargetsView = AuthenticatedTargetsView;
|
|
37862
|
+
exports.BackButton = BackButton;
|
|
37863
|
+
exports.BackButtonMinimal = BackButtonMinimal;
|
|
37711
37864
|
exports.BarChart = BarChart;
|
|
37712
37865
|
exports.BaseHistoryCalendar = BaseHistoryCalendar;
|
|
37713
37866
|
exports.BottlenecksContent = BottlenecksContent;
|