@optifye/dashboard-core 6.3.5 → 6.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +137 -9
- package/dist/index.d.ts +137 -9
- package/dist/index.js +680 -519
- package/dist/index.mjs +688 -528
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -14,9 +14,9 @@ import { noop, warning, invariant, progress, secondsToMilliseconds, milliseconds
|
|
|
14
14
|
import { getValueTransition, hover, press, isPrimaryPointer, GroupPlaybackControls, setDragLock, supportsLinearEasing, attachTimeline, isGenerator, calcGeneratorDuration, isWaapiSupportedEasing, mapEasingToNativeEasing, maxGeneratorDuration, generateLinearEasing, isBezierDefinition } from 'motion-dom';
|
|
15
15
|
import { BarChart as BarChart$1, CartesianGrid, XAxis, YAxis, Tooltip, Legend, Bar, LabelList, ResponsiveContainer, LineChart as LineChart$1, Line, PieChart, Pie, Cell, ReferenceLine, ComposedChart, Area, ScatterChart, Scatter } from 'recharts';
|
|
16
16
|
import { Slot } from '@radix-ui/react-slot';
|
|
17
|
-
import { Camera, ChevronDown, ChevronUp, Check, ShieldCheck, Star, Award, X, Coffee, Plus, Clock, Minus, ArrowDown, ArrowUp, Search, CheckCircle, AlertTriangle, Info, Share2, Trophy, Target, Download, User, XCircle, ChevronLeft, ChevronRight, AlertCircle, Sun, Moon, MessageSquare, Trash2,
|
|
17
|
+
import { Camera, ChevronDown, ChevronUp, Check, ShieldCheck, Star, Award, X, Coffee, Plus, Clock, ArrowLeft, Calendar, Save, Minus, ArrowDown, ArrowUp, ArrowLeftIcon, Settings2, CheckCircle2, Search, CheckCircle, AlertTriangle, Info, Share2, Trophy, Target, Download, User, XCircle, ChevronLeft, ChevronRight, AlertCircle, Sun, Moon, MessageSquare, Trash2, RefreshCw, Menu, Send, Copy, Edit2, UserCheck, LogOut, Package, Settings, LifeBuoy, EyeOff, Eye, Zap, UserCircle } from 'lucide-react';
|
|
18
18
|
import { DayPicker, useNavigation as useNavigation$1 } from 'react-day-picker';
|
|
19
|
-
import { XMarkIcon, ArrowRightIcon, HomeIcon, TrophyIcon, ChartBarIcon, AdjustmentsHorizontalIcon, ClockIcon, CubeIcon, SparklesIcon, QuestionMarkCircleIcon, UserCircleIcon, ExclamationCircleIcon, EnvelopeIcon, DocumentTextIcon, Bars3Icon, ArrowLeftIcon, CheckCircleIcon, ChatBubbleLeftRightIcon, XCircleIcon, InformationCircleIcon, ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/24/outline';
|
|
19
|
+
import { XMarkIcon, ArrowRightIcon, HomeIcon, TrophyIcon, ChartBarIcon, AdjustmentsHorizontalIcon, ClockIcon, CubeIcon, SparklesIcon, QuestionMarkCircleIcon, UserCircleIcon, ExclamationCircleIcon, EnvelopeIcon, DocumentTextIcon, Bars3Icon, ArrowLeftIcon as ArrowLeftIcon$1, CheckCircleIcon, ChatBubbleLeftRightIcon, XCircleIcon, InformationCircleIcon, ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/24/outline';
|
|
20
20
|
import html2canvas from 'html2canvas';
|
|
21
21
|
import jsPDF, { jsPDF as jsPDF$1 } from 'jspdf';
|
|
22
22
|
import * as SelectPrimitive from '@radix-ui/react-select';
|
|
@@ -3779,6 +3779,11 @@ var S3ClipsService = class {
|
|
|
3779
3779
|
this.requestCache = new RequestDeduplicationCache();
|
|
3780
3780
|
// Flag to prevent metadata fetching during index building
|
|
3781
3781
|
this.isIndexBuilding = false;
|
|
3782
|
+
// Flag to prevent metadata fetching during entire prefetch operation
|
|
3783
|
+
this.isPrefetching = false;
|
|
3784
|
+
// Global safeguard: limit concurrent metadata fetches to prevent flooding
|
|
3785
|
+
this.currentMetadataFetches = 0;
|
|
3786
|
+
this.MAX_CONCURRENT_METADATA = 3;
|
|
3782
3787
|
this.config = config;
|
|
3783
3788
|
if (!config.s3Config) {
|
|
3784
3789
|
throw new Error("S3 configuration is required");
|
|
@@ -3824,7 +3829,12 @@ var S3ClipsService = class {
|
|
|
3824
3829
|
*/
|
|
3825
3830
|
async listS3Clips(params) {
|
|
3826
3831
|
const { workspaceId, date, shiftId, maxKeys } = params;
|
|
3832
|
+
if (!isValidShiftId(shiftId)) {
|
|
3833
|
+
console.error(`[S3ClipsService] Invalid shift ID: ${shiftId}. Must be 0 (day) or 1 (night)`);
|
|
3834
|
+
return [];
|
|
3835
|
+
}
|
|
3827
3836
|
const prefix = `sop_violations/${workspaceId}/${date}/${shiftId}/`;
|
|
3837
|
+
console.log(`[S3ClipsService] Listing clips for workspace: ${workspaceId}, date: ${date}, shift: ${shiftId}`);
|
|
3828
3838
|
const deduplicationKey = `list-s3-clips:${prefix}:${maxKeys || "all"}`;
|
|
3829
3839
|
return this.requestCache.deduplicate(
|
|
3830
3840
|
deduplicationKey,
|
|
@@ -3926,20 +3936,36 @@ var S3ClipsService = class {
|
|
|
3926
3936
|
return null;
|
|
3927
3937
|
}
|
|
3928
3938
|
}
|
|
3939
|
+
/**
|
|
3940
|
+
* Control prefetch mode to prevent metadata fetching during background operations
|
|
3941
|
+
*/
|
|
3942
|
+
setPrefetchMode(enabled) {
|
|
3943
|
+
this.isPrefetching = enabled;
|
|
3944
|
+
console.log(`[S3ClipsService] Prefetch mode ${enabled ? "enabled" : "disabled"} - metadata fetching ${enabled ? "blocked" : "allowed"}`);
|
|
3945
|
+
}
|
|
3929
3946
|
/**
|
|
3930
3947
|
* Fetches full metadata including timestamps with deduplication
|
|
3931
3948
|
*/
|
|
3932
3949
|
async getFullMetadata(playlistUri) {
|
|
3933
|
-
if (this.isIndexBuilding) {
|
|
3934
|
-
console.warn(`[S3ClipsService] Skipping metadata fetch
|
|
3950
|
+
if (this.isIndexBuilding || this.isPrefetching) {
|
|
3951
|
+
console.warn(`[S3ClipsService] Skipping metadata fetch - building: ${this.isIndexBuilding}, prefetching: ${this.isPrefetching}`);
|
|
3935
3952
|
return null;
|
|
3936
3953
|
}
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3954
|
+
if (this.currentMetadataFetches >= this.MAX_CONCURRENT_METADATA) {
|
|
3955
|
+
console.warn(`[S3ClipsService] Skipping metadata - max concurrent fetches (${this.MAX_CONCURRENT_METADATA}) reached`);
|
|
3956
|
+
return null;
|
|
3957
|
+
}
|
|
3958
|
+
this.currentMetadataFetches++;
|
|
3959
|
+
try {
|
|
3960
|
+
const deduplicationKey = `full-metadata:${playlistUri}`;
|
|
3961
|
+
return await this.requestCache.deduplicate(
|
|
3962
|
+
deduplicationKey,
|
|
3963
|
+
() => this.executeGetFullMetadata(playlistUri),
|
|
3964
|
+
"FullMetadata"
|
|
3965
|
+
);
|
|
3966
|
+
} finally {
|
|
3967
|
+
this.currentMetadataFetches--;
|
|
3968
|
+
}
|
|
3943
3969
|
}
|
|
3944
3970
|
/**
|
|
3945
3971
|
* Internal implementation of full metadata fetching
|
|
@@ -3989,6 +4015,10 @@ var S3ClipsService = class {
|
|
|
3989
4015
|
return sopConfig.default;
|
|
3990
4016
|
}
|
|
3991
4017
|
async getClipCounts(workspaceId, date, shiftId, buildIndex) {
|
|
4018
|
+
if (!isValidShiftId(shiftId)) {
|
|
4019
|
+
console.error(`[S3ClipsService] getClipCounts - Invalid shift ID: ${shiftId}. Must be 0 (day) or 1 (night)`);
|
|
4020
|
+
return buildIndex ? { counts: {}, videoIndex: { byCategory: /* @__PURE__ */ new Map(), allVideos: [], counts: {}, workspaceId, date, shiftId: "0", lastUpdated: /* @__PURE__ */ new Date() } } : {};
|
|
4021
|
+
}
|
|
3992
4022
|
const deduplicationKey = `clip-counts:${workspaceId}:${date}:${shiftId}:${buildIndex ? "with-index" : "counts-only"}`;
|
|
3993
4023
|
return this.requestCache.deduplicate(
|
|
3994
4024
|
deduplicationKey,
|
|
@@ -4018,7 +4048,8 @@ var S3ClipsService = class {
|
|
|
4018
4048
|
"cycle_completion",
|
|
4019
4049
|
"bottleneck"
|
|
4020
4050
|
];
|
|
4021
|
-
|
|
4051
|
+
const shiftName = shiftId === 0 || shiftId === "0" ? "Day" : "Night";
|
|
4052
|
+
console.log(`[S3ClipsService] ${buildIndex ? "Building video index and counting" : "Fast counting"} clips for ${workspaceId} on ${date}, shift ${shiftId} (${shiftName} Shift)`);
|
|
4022
4053
|
const startTime = performance.now();
|
|
4023
4054
|
const videoIndex = buildIndex ? {
|
|
4024
4055
|
byCategory: /* @__PURE__ */ new Map(),
|
|
@@ -4165,6 +4196,10 @@ var S3ClipsService = class {
|
|
|
4165
4196
|
* Get first clip for a specific category with deduplication
|
|
4166
4197
|
*/
|
|
4167
4198
|
async getFirstClipForCategory(workspaceId, date, shiftId, category) {
|
|
4199
|
+
if (!isValidShiftId(shiftId)) {
|
|
4200
|
+
console.error(`[S3ClipsService] getFirstClipForCategory - Invalid shift ID: ${shiftId}. Must be 0 (day) or 1 (night)`);
|
|
4201
|
+
return null;
|
|
4202
|
+
}
|
|
4168
4203
|
const deduplicationKey = `first-clip:${workspaceId}:${date}:${shiftId}:${category}`;
|
|
4169
4204
|
return this.requestCache.deduplicate(
|
|
4170
4205
|
deduplicationKey,
|
|
@@ -4441,7 +4476,8 @@ var S3ClipsService = class {
|
|
|
4441
4476
|
date,
|
|
4442
4477
|
shiftId.toString(),
|
|
4443
4478
|
includeCycleTime || false,
|
|
4444
|
-
includeMetadata ||
|
|
4479
|
+
includeMetadata || false
|
|
4480
|
+
// Never fetch metadata for timestamp filtering to prevent flooding
|
|
4445
4481
|
);
|
|
4446
4482
|
});
|
|
4447
4483
|
const videoResults = await Promise.all(videoPromises);
|
|
@@ -4512,6 +4548,7 @@ var VideoPrefetchManager = class extends EventEmitter {
|
|
|
4512
4548
|
}
|
|
4513
4549
|
/**
|
|
4514
4550
|
* Get or create S3 service instance for dashboard config
|
|
4551
|
+
* Public method to allow sharing the same S3Service instance across components
|
|
4515
4552
|
*/
|
|
4516
4553
|
getS3Service(dashboardConfig) {
|
|
4517
4554
|
const configKey = JSON.stringify(dashboardConfig.s3Config);
|
|
@@ -4581,75 +4618,80 @@ var VideoPrefetchManager = class extends EventEmitter {
|
|
|
4581
4618
|
* Perform the actual prefetch work
|
|
4582
4619
|
*/
|
|
4583
4620
|
async performPrefetchWork(key, params, s3Service, buildIndex) {
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
|
|
4587
|
-
|
|
4588
|
-
|
|
4589
|
-
|
|
4590
|
-
|
|
4591
|
-
|
|
4592
|
-
|
|
4621
|
+
s3Service.setPrefetchMode(true);
|
|
4622
|
+
try {
|
|
4623
|
+
const cacheKey = `clip-counts:${params.workspaceId}:${params.date}:${params.shift}`;
|
|
4624
|
+
const cachedResult = await smartVideoCache.getClipCounts(cacheKey);
|
|
4625
|
+
if (cachedResult) {
|
|
4626
|
+
console.log(`[VideoPrefetchManager] Found cached data for ${key}`);
|
|
4627
|
+
this.updateRequestStatus(key, "fully_indexed" /* FULLY_INDEXED */, cachedResult);
|
|
4628
|
+
return cachedResult;
|
|
4629
|
+
}
|
|
4630
|
+
if (buildIndex) {
|
|
4631
|
+
const countsOnly = await s3Service.getClipCounts(
|
|
4632
|
+
params.workspaceId,
|
|
4633
|
+
params.date,
|
|
4634
|
+
params.shift
|
|
4635
|
+
);
|
|
4636
|
+
if (typeof countsOnly === "object" && countsOnly !== null) {
|
|
4637
|
+
const renderReadyData = {
|
|
4638
|
+
counts: countsOnly,
|
|
4639
|
+
videoIndex: {
|
|
4640
|
+
byCategory: /* @__PURE__ */ new Map(),
|
|
4641
|
+
allVideos: [],
|
|
4642
|
+
counts: countsOnly,
|
|
4643
|
+
workspaceId: params.workspaceId,
|
|
4644
|
+
date: params.date,
|
|
4645
|
+
shiftId: params.shift,
|
|
4646
|
+
lastUpdated: /* @__PURE__ */ new Date(),
|
|
4647
|
+
_debugId: `vid_RENDER_READY_${Date.now()}_${Math.random().toString(36).substring(7)}`
|
|
4648
|
+
}
|
|
4649
|
+
};
|
|
4650
|
+
this.updateRequestStatus(key, "render_ready" /* RENDER_READY */, renderReadyData);
|
|
4651
|
+
console.log(`[VideoPrefetchManager] Render ready, building full index for ${key}`);
|
|
4652
|
+
}
|
|
4653
|
+
}
|
|
4654
|
+
const fullResult = await s3Service.getClipCountsCacheFirst(
|
|
4593
4655
|
params.workspaceId,
|
|
4594
4656
|
params.date,
|
|
4595
|
-
params.shift
|
|
4657
|
+
params.shift,
|
|
4658
|
+
true
|
|
4596
4659
|
);
|
|
4597
|
-
if (typeof
|
|
4598
|
-
const
|
|
4599
|
-
|
|
4660
|
+
if (fullResult && typeof fullResult === "object" && "videoIndex" in fullResult) {
|
|
4661
|
+
const clipCountsWithIndex = fullResult;
|
|
4662
|
+
if (clipCountsWithIndex.videoIndex.allVideos.length > 0) {
|
|
4663
|
+
console.log(`[VideoPrefetchManager] Video index properly populated with ${clipCountsWithIndex.videoIndex.allVideos.length} videos`);
|
|
4664
|
+
} else {
|
|
4665
|
+
console.warn(`[VideoPrefetchManager] Video index is empty, but counts available:`, clipCountsWithIndex.counts);
|
|
4666
|
+
}
|
|
4667
|
+
await smartVideoCache.setClipCounts(cacheKey, clipCountsWithIndex, 5 * 60);
|
|
4668
|
+
this.updateRequestStatus(key, "fully_indexed" /* FULLY_INDEXED */, clipCountsWithIndex);
|
|
4669
|
+
console.log(`[VideoPrefetchManager] Fully indexed: ${key} (${clipCountsWithIndex.videoIndex.allVideos.length} videos)`);
|
|
4670
|
+
return clipCountsWithIndex;
|
|
4671
|
+
} else if (fullResult && typeof fullResult === "object") {
|
|
4672
|
+
console.log(`[VideoPrefetchManager] Received counts only, building fallback data structure`);
|
|
4673
|
+
const countsResult = fullResult;
|
|
4674
|
+
const fallbackData = {
|
|
4675
|
+
counts: countsResult,
|
|
4600
4676
|
videoIndex: {
|
|
4601
4677
|
byCategory: /* @__PURE__ */ new Map(),
|
|
4602
4678
|
allVideos: [],
|
|
4603
|
-
counts:
|
|
4679
|
+
counts: countsResult,
|
|
4604
4680
|
workspaceId: params.workspaceId,
|
|
4605
4681
|
date: params.date,
|
|
4606
4682
|
shiftId: params.shift,
|
|
4607
4683
|
lastUpdated: /* @__PURE__ */ new Date(),
|
|
4608
|
-
_debugId: `
|
|
4684
|
+
_debugId: `vid_FALLBACK_${Date.now()}_${Math.random().toString(36).substring(7)}`
|
|
4609
4685
|
}
|
|
4610
4686
|
};
|
|
4611
|
-
this.updateRequestStatus(key, "render_ready" /* RENDER_READY */,
|
|
4612
|
-
|
|
4613
|
-
}
|
|
4614
|
-
}
|
|
4615
|
-
const fullResult = await s3Service.getClipCountsCacheFirst(
|
|
4616
|
-
params.workspaceId,
|
|
4617
|
-
params.date,
|
|
4618
|
-
params.shift,
|
|
4619
|
-
true
|
|
4620
|
-
);
|
|
4621
|
-
if (fullResult && typeof fullResult === "object" && "videoIndex" in fullResult) {
|
|
4622
|
-
const clipCountsWithIndex = fullResult;
|
|
4623
|
-
if (clipCountsWithIndex.videoIndex.allVideos.length > 0) {
|
|
4624
|
-
console.log(`[VideoPrefetchManager] Video index properly populated with ${clipCountsWithIndex.videoIndex.allVideos.length} videos`);
|
|
4687
|
+
this.updateRequestStatus(key, "render_ready" /* RENDER_READY */, fallbackData);
|
|
4688
|
+
return fallbackData;
|
|
4625
4689
|
} else {
|
|
4626
|
-
console.
|
|
4627
|
-
|
|
4628
|
-
|
|
4629
|
-
|
|
4630
|
-
|
|
4631
|
-
return clipCountsWithIndex;
|
|
4632
|
-
} else if (fullResult && typeof fullResult === "object") {
|
|
4633
|
-
console.log(`[VideoPrefetchManager] Received counts only, building fallback data structure`);
|
|
4634
|
-
const countsResult = fullResult;
|
|
4635
|
-
const fallbackData = {
|
|
4636
|
-
counts: countsResult,
|
|
4637
|
-
videoIndex: {
|
|
4638
|
-
byCategory: /* @__PURE__ */ new Map(),
|
|
4639
|
-
allVideos: [],
|
|
4640
|
-
counts: countsResult,
|
|
4641
|
-
workspaceId: params.workspaceId,
|
|
4642
|
-
date: params.date,
|
|
4643
|
-
shiftId: params.shift,
|
|
4644
|
-
lastUpdated: /* @__PURE__ */ new Date(),
|
|
4645
|
-
_debugId: `vid_FALLBACK_${Date.now()}_${Math.random().toString(36).substring(7)}`
|
|
4646
|
-
}
|
|
4647
|
-
};
|
|
4648
|
-
this.updateRequestStatus(key, "render_ready" /* RENDER_READY */, fallbackData);
|
|
4649
|
-
return fallbackData;
|
|
4650
|
-
} else {
|
|
4651
|
-
console.error(`[VideoPrefetchManager] Received null/undefined result from S3 service`);
|
|
4652
|
-
throw new Error("Failed to fetch clip counts from S3 service");
|
|
4690
|
+
console.error(`[VideoPrefetchManager] Received null/undefined result from S3 service`);
|
|
4691
|
+
throw new Error("Failed to fetch clip counts from S3 service");
|
|
4692
|
+
}
|
|
4693
|
+
} finally {
|
|
4694
|
+
s3Service.setPrefetchMode(false);
|
|
4653
4695
|
}
|
|
4654
4696
|
}
|
|
4655
4697
|
/**
|
|
@@ -4912,9 +4954,13 @@ var AuthProvider = ({ children }) => {
|
|
|
4912
4954
|
const [loading, setLoading] = useState(true);
|
|
4913
4955
|
const [error, setError] = useState(null);
|
|
4914
4956
|
const router = useRouter();
|
|
4915
|
-
|
|
4916
|
-
|
|
4957
|
+
authConfig?.userProfileTable;
|
|
4958
|
+
authConfig?.roleColumn || "role";
|
|
4917
4959
|
const fetchUserDetails = useCallback(async (supabaseUser) => {
|
|
4960
|
+
console.log("[fetchUserDetails] Called for user:", supabaseUser.id, {
|
|
4961
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4962
|
+
stackTrace: new Error().stack?.split("\n").slice(1, 4).join(" -> ")
|
|
4963
|
+
});
|
|
4918
4964
|
if (!supabaseUser) return null;
|
|
4919
4965
|
const basicUser = {
|
|
4920
4966
|
id: supabaseUser.id,
|
|
@@ -4923,42 +4969,34 @@ var AuthProvider = ({ children }) => {
|
|
|
4923
4969
|
if (!supabase) return basicUser;
|
|
4924
4970
|
try {
|
|
4925
4971
|
const timeoutPromise = new Promise(
|
|
4926
|
-
(_, reject) => setTimeout(() =>
|
|
4972
|
+
(_, reject) => setTimeout(() => {
|
|
4973
|
+
console.log("[fetchUserDetails] Timeout triggered after 2 seconds");
|
|
4974
|
+
reject(new Error("Profile fetch timeout"));
|
|
4975
|
+
}, 2e3)
|
|
4927
4976
|
);
|
|
4928
4977
|
const rolePromise = supabase.from("user_roles").select("role_level").eq("user_id", supabaseUser.id).single();
|
|
4929
|
-
|
|
4930
|
-
|
|
4931
|
-
|
|
4932
|
-
|
|
4933
|
-
const [roleResult, profileResult] = await Promise.race([
|
|
4934
|
-
Promise.all([
|
|
4935
|
-
rolePromise,
|
|
4936
|
-
profilePromise || Promise.resolve(null)
|
|
4937
|
-
]),
|
|
4938
|
-
timeoutPromise.then(() => {
|
|
4939
|
-
throw new Error("Timeout");
|
|
4940
|
-
})
|
|
4978
|
+
const roleResult = await Promise.race([
|
|
4979
|
+
rolePromise,
|
|
4980
|
+
timeoutPromise
|
|
4981
|
+
// Fixed: removed .then() which was causing the bug
|
|
4941
4982
|
]);
|
|
4942
4983
|
let roleLevel = void 0;
|
|
4943
4984
|
if (roleResult && !roleResult.error && roleResult.data) {
|
|
4944
4985
|
roleLevel = roleResult.data.role_level;
|
|
4945
|
-
} else if (roleResult?.error) {
|
|
4986
|
+
} else if (roleResult?.error && roleResult.error.code !== "PGRST116") {
|
|
4946
4987
|
console.log("Error fetching role_level:", roleResult.error.message);
|
|
4947
4988
|
}
|
|
4948
|
-
let roleValue = void 0;
|
|
4949
|
-
if (profileResult && !profileResult.error && profileResult.data) {
|
|
4950
|
-
roleValue = profileResult.data[roleColumn];
|
|
4951
|
-
}
|
|
4952
4989
|
return {
|
|
4953
4990
|
...basicUser,
|
|
4954
|
-
role: roleValue,
|
|
4955
4991
|
role_level: roleLevel
|
|
4956
4992
|
};
|
|
4957
4993
|
} catch (err) {
|
|
4958
|
-
|
|
4994
|
+
if (err instanceof Error && err.message.includes("timeout")) {
|
|
4995
|
+
console.warn("Auth fetch timeout - using basic user info");
|
|
4996
|
+
}
|
|
4959
4997
|
return basicUser;
|
|
4960
4998
|
}
|
|
4961
|
-
}, [supabase
|
|
4999
|
+
}, [supabase]);
|
|
4962
5000
|
useEffect(() => {
|
|
4963
5001
|
if (!supabase) return;
|
|
4964
5002
|
let mounted = true;
|
|
@@ -4969,6 +5007,7 @@ var AuthProvider = ({ children }) => {
|
|
|
4969
5007
|
}
|
|
4970
5008
|
}, 1e4);
|
|
4971
5009
|
const initializeAuth = async () => {
|
|
5010
|
+
const startTime = performance.now();
|
|
4972
5011
|
try {
|
|
4973
5012
|
const { data: { session: initialSession }, error: sessionError } = await supabase.auth.getSession();
|
|
4974
5013
|
if (!mounted) return;
|
|
@@ -5011,12 +5050,38 @@ var AuthProvider = ({ children }) => {
|
|
|
5011
5050
|
if (mounted) {
|
|
5012
5051
|
setLoading(false);
|
|
5013
5052
|
clearTimeout(safetyTimeout);
|
|
5053
|
+
const duration = performance.now() - startTime;
|
|
5054
|
+
if (duration > 3e3) {
|
|
5055
|
+
console.warn(`[Auth] Initialization took ${duration.toFixed(0)}ms - consider optimization`);
|
|
5056
|
+
} else if (process.env.NODE_ENV === "development") {
|
|
5057
|
+
console.log(`[Auth] Initialized in ${duration.toFixed(0)}ms`);
|
|
5058
|
+
}
|
|
5014
5059
|
}
|
|
5015
5060
|
}
|
|
5016
5061
|
};
|
|
5017
5062
|
initializeAuth();
|
|
5018
|
-
const { data: { subscription } } = supabase.auth.onAuthStateChange(async (
|
|
5063
|
+
const { data: { subscription } } = supabase.auth.onAuthStateChange(async (event, currentSession) => {
|
|
5019
5064
|
if (!mounted) return;
|
|
5065
|
+
console.log("[AuthContext] Auth event fired:", {
|
|
5066
|
+
event,
|
|
5067
|
+
sessionId: currentSession?.user?.id,
|
|
5068
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5069
|
+
currentPath: typeof window !== "undefined" ? window.location.pathname : "unknown"
|
|
5070
|
+
});
|
|
5071
|
+
if (event === "TOKEN_REFRESHED") {
|
|
5072
|
+
if (session?.user?.id === currentSession?.user?.id && session?.user?.email === currentSession?.user?.email) {
|
|
5073
|
+
console.log("[AuthContext] Skipping TOKEN_REFRESHED - session unchanged");
|
|
5074
|
+
return;
|
|
5075
|
+
}
|
|
5076
|
+
}
|
|
5077
|
+
if (event !== "TOKEN_REFRESHED" && currentSession?.user) {
|
|
5078
|
+
console.log("[AuthContext] Non-TOKEN_REFRESHED event will trigger fetchUserDetails:", event);
|
|
5079
|
+
}
|
|
5080
|
+
const sessionChanged = session?.user?.id !== currentSession?.user?.id || session?.user?.email !== currentSession?.user?.email;
|
|
5081
|
+
if (!sessionChanged && user) {
|
|
5082
|
+
console.log("[AuthContext] Session and user unchanged, skipping update");
|
|
5083
|
+
return;
|
|
5084
|
+
}
|
|
5020
5085
|
setSession(currentSession);
|
|
5021
5086
|
setUser(null);
|
|
5022
5087
|
setLoading(false);
|
|
@@ -6937,16 +7002,12 @@ var useTargets = (options) => {
|
|
|
6937
7002
|
};
|
|
6938
7003
|
var DEFAULT_SHIFTS_TABLE_NAME = "shift_configurations";
|
|
6939
7004
|
var useShifts = () => {
|
|
6940
|
-
const { supabaseUrl, supabaseKey } = useDashboardConfig();
|
|
6941
7005
|
const { companyId } = useEntityConfig();
|
|
6942
7006
|
const { tables } = useDatabaseConfig();
|
|
7007
|
+
const supabase = useSupabase();
|
|
6943
7008
|
const [shifts, setShifts] = useState([]);
|
|
6944
7009
|
const [isLoading, setIsLoading] = useState(true);
|
|
6945
7010
|
const [error, setError] = useState(null);
|
|
6946
|
-
const supabase = useMemo(() => {
|
|
6947
|
-
if (!supabaseUrl || !supabaseKey) return null;
|
|
6948
|
-
return createClient(supabaseUrl, supabaseKey);
|
|
6949
|
-
}, [supabaseUrl, supabaseKey]);
|
|
6950
7011
|
const shiftsTable = tables?.shiftConfigurations || DEFAULT_SHIFTS_TABLE_NAME;
|
|
6951
7012
|
const fetchData = useCallback(async () => {
|
|
6952
7013
|
if (!supabase) {
|
|
@@ -7645,6 +7706,7 @@ var runtimeWorkspaceDisplayNames = {};
|
|
|
7645
7706
|
var isInitialized = false;
|
|
7646
7707
|
var isInitializing = false;
|
|
7647
7708
|
var initializedWithLineIds = [];
|
|
7709
|
+
var initializationPromise = null;
|
|
7648
7710
|
function getCurrentLineIds() {
|
|
7649
7711
|
try {
|
|
7650
7712
|
const config = _getDashboardConfigInstance();
|
|
@@ -7665,52 +7727,79 @@ function getCurrentLineIds() {
|
|
|
7665
7727
|
}
|
|
7666
7728
|
async function initializeWorkspaceDisplayNames(explicitLineId) {
|
|
7667
7729
|
console.log("\u{1F504} initializeWorkspaceDisplayNames called", { isInitialized, isInitializing, explicitLineId });
|
|
7668
|
-
if (isInitialized
|
|
7669
|
-
|
|
7670
|
-
|
|
7671
|
-
|
|
7672
|
-
|
|
7673
|
-
|
|
7674
|
-
|
|
7675
|
-
|
|
7676
|
-
|
|
7730
|
+
if (isInitialized) return;
|
|
7731
|
+
if (initializationPromise) {
|
|
7732
|
+
console.log("\u{1F504} Already initializing, waiting for existing initialization...");
|
|
7733
|
+
await initializationPromise;
|
|
7734
|
+
return;
|
|
7735
|
+
}
|
|
7736
|
+
initializationPromise = (async () => {
|
|
7737
|
+
isInitializing = true;
|
|
7738
|
+
try {
|
|
7739
|
+
console.log("\u{1F504} Starting Supabase workspace display names initialization...");
|
|
7740
|
+
let targetLineIds = [];
|
|
7741
|
+
if (explicitLineId) {
|
|
7742
|
+
targetLineIds = [explicitLineId];
|
|
7743
|
+
} else {
|
|
7744
|
+
targetLineIds = getCurrentLineIds();
|
|
7745
|
+
}
|
|
7746
|
+
console.log("\u{1F504} Target line IDs for workspace filtering:", targetLineIds);
|
|
7747
|
+
runtimeWorkspaceDisplayNames = {};
|
|
7748
|
+
if (targetLineIds.length > 0) {
|
|
7749
|
+
for (const lineId of targetLineIds) {
|
|
7750
|
+
console.log(`\u{1F504} Fetching workspaces for line: ${lineId}`);
|
|
7751
|
+
const lineDisplayNamesMap = await workspaceService.getWorkspaceDisplayNames(void 0, lineId);
|
|
7752
|
+
runtimeWorkspaceDisplayNames[lineId] = {};
|
|
7753
|
+
lineDisplayNamesMap.forEach((displayName, workspaceId) => {
|
|
7754
|
+
runtimeWorkspaceDisplayNames[lineId][workspaceId] = displayName;
|
|
7755
|
+
});
|
|
7756
|
+
console.log(`\u2705 Stored ${lineDisplayNamesMap.size} workspaces for line ${lineId}`);
|
|
7757
|
+
}
|
|
7758
|
+
} else {
|
|
7759
|
+
console.warn("\u26A0\uFE0F No line IDs found, fetching all workspaces (less efficient)");
|
|
7760
|
+
const allWorkspacesMap = await workspaceService.getWorkspaceDisplayNames();
|
|
7761
|
+
runtimeWorkspaceDisplayNames["global"] = {};
|
|
7762
|
+
allWorkspacesMap.forEach((displayName, workspaceId) => {
|
|
7763
|
+
runtimeWorkspaceDisplayNames["global"][workspaceId] = displayName;
|
|
7764
|
+
});
|
|
7765
|
+
}
|
|
7766
|
+
isInitialized = true;
|
|
7767
|
+
initializedWithLineIds = targetLineIds;
|
|
7768
|
+
console.log("\u2705 Workspace display names initialized from Supabase:", runtimeWorkspaceDisplayNames);
|
|
7769
|
+
console.log("\u2705 Initialized with line IDs:", initializedWithLineIds);
|
|
7770
|
+
} catch (error) {
|
|
7771
|
+
console.error("\u274C Failed to initialize workspace display names from Supabase:", error);
|
|
7772
|
+
} finally {
|
|
7773
|
+
isInitializing = false;
|
|
7774
|
+
initializationPromise = null;
|
|
7677
7775
|
}
|
|
7678
|
-
|
|
7679
|
-
|
|
7680
|
-
|
|
7681
|
-
|
|
7682
|
-
|
|
7776
|
+
})();
|
|
7777
|
+
await initializationPromise;
|
|
7778
|
+
}
|
|
7779
|
+
var preInitializeWorkspaceDisplayNames = async (lineId) => {
|
|
7780
|
+
console.log("\u{1F504} preInitializeWorkspaceDisplayNames called for lineId:", lineId);
|
|
7781
|
+
if (isInitialized) {
|
|
7782
|
+
console.log("\u{1F504} Already initialized");
|
|
7783
|
+
if (lineId && !runtimeWorkspaceDisplayNames[lineId]) {
|
|
7784
|
+
console.log(`\u{1F504} Line ${lineId} not in cache, fetching...`);
|
|
7785
|
+
try {
|
|
7683
7786
|
const lineDisplayNamesMap = await workspaceService.getWorkspaceDisplayNames(void 0, lineId);
|
|
7684
7787
|
runtimeWorkspaceDisplayNames[lineId] = {};
|
|
7685
7788
|
lineDisplayNamesMap.forEach((displayName, workspaceId) => {
|
|
7686
7789
|
runtimeWorkspaceDisplayNames[lineId][workspaceId] = displayName;
|
|
7687
7790
|
});
|
|
7688
|
-
console.log(`\u2705
|
|
7791
|
+
console.log(`\u2705 Added ${lineDisplayNamesMap.size} workspaces for line ${lineId}`);
|
|
7792
|
+
} catch (error) {
|
|
7793
|
+
console.error(`\u274C Failed to fetch workspaces for line ${lineId}:`, error);
|
|
7689
7794
|
}
|
|
7690
|
-
} else {
|
|
7691
|
-
console.warn("\u26A0\uFE0F No line IDs found, fetching all workspaces (less efficient)");
|
|
7692
|
-
const allWorkspacesMap = await workspaceService.getWorkspaceDisplayNames();
|
|
7693
|
-
runtimeWorkspaceDisplayNames["global"] = {};
|
|
7694
|
-
allWorkspacesMap.forEach((displayName, workspaceId) => {
|
|
7695
|
-
runtimeWorkspaceDisplayNames["global"][workspaceId] = displayName;
|
|
7696
|
-
});
|
|
7697
7795
|
}
|
|
7698
|
-
|
|
7699
|
-
initializedWithLineIds = targetLineIds;
|
|
7700
|
-
console.log("\u2705 Workspace display names initialized from Supabase:", runtimeWorkspaceDisplayNames);
|
|
7701
|
-
console.log("\u2705 Initialized with line IDs:", initializedWithLineIds);
|
|
7702
|
-
} catch (error) {
|
|
7703
|
-
console.error("\u274C Failed to initialize workspace display names from Supabase:", error);
|
|
7704
|
-
} finally {
|
|
7705
|
-
isInitializing = false;
|
|
7796
|
+
return;
|
|
7706
7797
|
}
|
|
7707
|
-
|
|
7708
|
-
|
|
7709
|
-
|
|
7710
|
-
if (isInitialized || isInitializing) {
|
|
7711
|
-
console.log("\u{1F504} Already initialized or initializing");
|
|
7798
|
+
if (initializationPromise) {
|
|
7799
|
+
console.log("\u{1F504} Already initializing, waiting for completion...");
|
|
7800
|
+
await initializationPromise;
|
|
7712
7801
|
if (lineId && !runtimeWorkspaceDisplayNames[lineId]) {
|
|
7713
|
-
console.log(`\u{1F504} Line ${lineId} not in cache, fetching...`);
|
|
7802
|
+
console.log(`\u{1F504} Line ${lineId} not in cache after init, fetching...`);
|
|
7714
7803
|
try {
|
|
7715
7804
|
const lineDisplayNamesMap = await workspaceService.getWorkspaceDisplayNames(void 0, lineId);
|
|
7716
7805
|
runtimeWorkspaceDisplayNames[lineId] = {};
|
|
@@ -7728,7 +7817,12 @@ var preInitializeWorkspaceDisplayNames = async (lineId) => {
|
|
|
7728
7817
|
};
|
|
7729
7818
|
var forceRefreshWorkspaceDisplayNames = async (lineId) => {
|
|
7730
7819
|
console.log("\u{1F504} forceRefreshWorkspaceDisplayNames called for lineId:", lineId);
|
|
7820
|
+
if (initializationPromise) {
|
|
7821
|
+
console.log("\u{1F504} Waiting for existing initialization to complete before refresh...");
|
|
7822
|
+
await initializationPromise;
|
|
7823
|
+
}
|
|
7731
7824
|
clearWorkspaceDisplayNamesCache();
|
|
7825
|
+
initializationPromise = null;
|
|
7732
7826
|
await initializeWorkspaceDisplayNames(lineId);
|
|
7733
7827
|
};
|
|
7734
7828
|
console.log("\u{1F504} Module loaded, will initialize lazily when first function is called");
|
|
@@ -7876,6 +7970,7 @@ var clearWorkspaceDisplayNamesCache = () => {
|
|
|
7876
7970
|
isInitialized = false;
|
|
7877
7971
|
isInitializing = false;
|
|
7878
7972
|
initializedWithLineIds = [];
|
|
7973
|
+
initializationPromise = null;
|
|
7879
7974
|
};
|
|
7880
7975
|
|
|
7881
7976
|
// src/lib/hooks/useWorkspaceDisplayNames.ts
|
|
@@ -11512,7 +11607,18 @@ var usePrefetchClipCounts = ({
|
|
|
11512
11607
|
}, [subscriberId]);
|
|
11513
11608
|
const prefetchParams = useMemo(() => {
|
|
11514
11609
|
const operationalDate = date || getOperationalDate();
|
|
11515
|
-
|
|
11610
|
+
let shiftStr;
|
|
11611
|
+
if (shift !== void 0 && shift !== null) {
|
|
11612
|
+
shiftStr = shift.toString();
|
|
11613
|
+
console.log(`[usePrefetchClipCounts] Using provided shift: ${shiftStr} for date: ${operationalDate}`);
|
|
11614
|
+
} else if (date) {
|
|
11615
|
+
shiftStr = "0";
|
|
11616
|
+
console.log(`[usePrefetchClipCounts] No shift provided for historical date ${date}, defaulting to day shift (0)`);
|
|
11617
|
+
} else {
|
|
11618
|
+
const currentShift = getCurrentShift2();
|
|
11619
|
+
shiftStr = currentShift.shiftId.toString();
|
|
11620
|
+
console.log(`[usePrefetchClipCounts] Using current operational shift: ${shiftStr} (${currentShift.shiftName})`);
|
|
11621
|
+
}
|
|
11516
11622
|
return {
|
|
11517
11623
|
workspaceId: workspaceId || "",
|
|
11518
11624
|
date: operationalDate,
|
|
@@ -19516,11 +19622,13 @@ var withAuth = (WrappedComponent2, options) => {
|
|
|
19516
19622
|
requireAuth: true,
|
|
19517
19623
|
...options
|
|
19518
19624
|
};
|
|
19519
|
-
|
|
19625
|
+
const WithAuthComponent = React19.memo(function WithAuthComponent2(props) {
|
|
19520
19626
|
const { session, loading } = useAuth();
|
|
19521
19627
|
const router = useRouter();
|
|
19522
19628
|
React19.useEffect(() => {
|
|
19523
|
-
|
|
19629
|
+
if (process.env.NODE_ENV === "development" && process.env.DEBUG_AUTH === "true") {
|
|
19630
|
+
console.log("withAuth state:", { loading, hasSession: !!session, requireAuth: defaultOptions.requireAuth });
|
|
19631
|
+
}
|
|
19524
19632
|
}, [session, loading]);
|
|
19525
19633
|
React19.useEffect(() => {
|
|
19526
19634
|
if (!loading && defaultOptions.requireAuth && !session) {
|
|
@@ -19535,7 +19643,9 @@ var withAuth = (WrappedComponent2, options) => {
|
|
|
19535
19643
|
return null;
|
|
19536
19644
|
}
|
|
19537
19645
|
return /* @__PURE__ */ jsx(WrappedComponent2, { ...props });
|
|
19538
|
-
};
|
|
19646
|
+
});
|
|
19647
|
+
WithAuthComponent.displayName = `withAuth(${WrappedComponent2.displayName || WrappedComponent2.name || "Component"})`;
|
|
19648
|
+
return WithAuthComponent;
|
|
19539
19649
|
};
|
|
19540
19650
|
var LoginPage = ({
|
|
19541
19651
|
onRateLimitCheck,
|
|
@@ -26123,7 +26233,7 @@ var BottlenecksContent = ({
|
|
|
26123
26233
|
const [duration, setDuration] = useState(0);
|
|
26124
26234
|
const [currentIndex, setCurrentIndex] = useState(0);
|
|
26125
26235
|
const [activeFilter, setActiveFilter] = useState(initialFilter);
|
|
26126
|
-
const previousFilterRef = useRef(
|
|
26236
|
+
const previousFilterRef = useRef("");
|
|
26127
26237
|
const [allVideos, setAllVideos] = useState([]);
|
|
26128
26238
|
const [isLoading, setIsLoading] = useState(true);
|
|
26129
26239
|
const [isCategoryLoading, setIsCategoryLoading] = useState(false);
|
|
@@ -26173,8 +26283,23 @@ var BottlenecksContent = ({
|
|
|
26173
26283
|
console.warn("S3 configuration not found in dashboard config");
|
|
26174
26284
|
return null;
|
|
26175
26285
|
}
|
|
26176
|
-
return
|
|
26286
|
+
return videoPrefetchManager.getS3Service(dashboardConfig);
|
|
26177
26287
|
}, [dashboardConfig]);
|
|
26288
|
+
const effectiveShift = useMemo(() => {
|
|
26289
|
+
if (shift !== void 0 && shift !== null) {
|
|
26290
|
+
const shiftStr = shift.toString();
|
|
26291
|
+
console.log(`[BottlenecksContent] Using provided shift: ${shiftStr} for date: ${date}`);
|
|
26292
|
+
return shiftStr;
|
|
26293
|
+
}
|
|
26294
|
+
if (date) {
|
|
26295
|
+
console.log(`[BottlenecksContent] No shift provided for historical date ${date}, defaulting to day shift (0)`);
|
|
26296
|
+
return "0";
|
|
26297
|
+
} else {
|
|
26298
|
+
const currentShift = getCurrentShift2();
|
|
26299
|
+
console.log(`[BottlenecksContent] Using current operational shift: ${currentShift.shiftId} (${currentShift.shiftName})`);
|
|
26300
|
+
return currentShift.shiftId.toString();
|
|
26301
|
+
}
|
|
26302
|
+
}, [shift, date]);
|
|
26178
26303
|
const {
|
|
26179
26304
|
data: prefetchData,
|
|
26180
26305
|
isFullyIndexed,
|
|
@@ -26183,7 +26308,7 @@ var BottlenecksContent = ({
|
|
|
26183
26308
|
} = usePrefetchClipCounts({
|
|
26184
26309
|
workspaceId,
|
|
26185
26310
|
date: date || getOperationalDate(),
|
|
26186
|
-
shift:
|
|
26311
|
+
shift: effectiveShift,
|
|
26187
26312
|
enabled: !!workspaceId && !!s3ClipsService,
|
|
26188
26313
|
buildIndex: true
|
|
26189
26314
|
});
|
|
@@ -26197,7 +26322,7 @@ var BottlenecksContent = ({
|
|
|
26197
26322
|
fetchInProgressRef.current.add(operationKey);
|
|
26198
26323
|
try {
|
|
26199
26324
|
const operationalDate = date || getOperationalDate();
|
|
26200
|
-
const shiftStr =
|
|
26325
|
+
const shiftStr = effectiveShift;
|
|
26201
26326
|
console.log(`[BottlenecksContent] Fetching clip counts directly for ${workspaceId}`);
|
|
26202
26327
|
const cacheKey = `clip-counts:${workspaceId}:${operationalDate}:${shiftStr}`;
|
|
26203
26328
|
const cachedResult = await smartVideoCache.getClipCounts(cacheKey);
|
|
@@ -26238,7 +26363,7 @@ var BottlenecksContent = ({
|
|
|
26238
26363
|
} finally {
|
|
26239
26364
|
fetchInProgressRef.current.delete(operationKey);
|
|
26240
26365
|
}
|
|
26241
|
-
}, [workspaceId, date, s3ClipsService,
|
|
26366
|
+
}, [workspaceId, date, s3ClipsService, effectiveShift, dashboardConfig, updateClipCounts, updateVideoIndex]);
|
|
26242
26367
|
const loadingCategoryRef = useRef(null);
|
|
26243
26368
|
const videoRetryCountRef = useRef(0);
|
|
26244
26369
|
const loadingVideosRef = useRef(/* @__PURE__ */ new Set());
|
|
@@ -26280,13 +26405,13 @@ var BottlenecksContent = ({
|
|
|
26280
26405
|
index,
|
|
26281
26406
|
true,
|
|
26282
26407
|
// includeCycleTime - OK for preloading
|
|
26283
|
-
|
|
26284
|
-
// includeMetadata -
|
|
26408
|
+
false
|
|
26409
|
+
// includeMetadata - NO metadata during bulk preloading to prevent flooding
|
|
26285
26410
|
);
|
|
26286
26411
|
}
|
|
26287
26412
|
if (!video) {
|
|
26288
26413
|
const operationalDate = date || getOperationalDate();
|
|
26289
|
-
const shiftStr =
|
|
26414
|
+
const shiftStr = effectiveShift;
|
|
26290
26415
|
video = await s3ClipsService.getClipByIndex(
|
|
26291
26416
|
workspaceId,
|
|
26292
26417
|
operationalDate,
|
|
@@ -26295,8 +26420,8 @@ var BottlenecksContent = ({
|
|
|
26295
26420
|
index,
|
|
26296
26421
|
true,
|
|
26297
26422
|
// includeCycleTime - OK for preloading
|
|
26298
|
-
|
|
26299
|
-
// includeMetadata -
|
|
26423
|
+
false
|
|
26424
|
+
// includeMetadata - NO metadata during bulk preloading to prevent flooding
|
|
26300
26425
|
);
|
|
26301
26426
|
}
|
|
26302
26427
|
if (video && isMountedRef.current) {
|
|
@@ -26319,7 +26444,7 @@ var BottlenecksContent = ({
|
|
|
26319
26444
|
Promise.all(loadPromises).catch((err) => {
|
|
26320
26445
|
console.warn("[ensureVideosLoaded] Some videos failed to preload:", err);
|
|
26321
26446
|
});
|
|
26322
|
-
}, [s3ClipsService, workspaceId, clipCounts, sopCategories, date,
|
|
26447
|
+
}, [s3ClipsService, workspaceId, clipCounts, sopCategories, date, effectiveShift]);
|
|
26323
26448
|
const loadFirstVideoForCategory = useCallback(async (category) => {
|
|
26324
26449
|
if (!workspaceId || !s3ClipsService || !isMountedRef.current) return;
|
|
26325
26450
|
const targetCategory = category || activeFilterRef.current;
|
|
@@ -26335,7 +26460,7 @@ var BottlenecksContent = ({
|
|
|
26335
26460
|
}
|
|
26336
26461
|
try {
|
|
26337
26462
|
const operationalDate = date || getOperationalDate();
|
|
26338
|
-
const shiftStr =
|
|
26463
|
+
const shiftStr = effectiveShift;
|
|
26339
26464
|
if (!clipCounts[targetCategory] && !videoIndex) {
|
|
26340
26465
|
const cacheKey = `clip-counts:${workspaceId}:${operationalDate}:${shiftStr}`;
|
|
26341
26466
|
const cachedResult = await smartVideoCache.getClipCounts(cacheKey);
|
|
@@ -26356,8 +26481,16 @@ var BottlenecksContent = ({
|
|
|
26356
26481
|
);
|
|
26357
26482
|
if (firstVideo) {
|
|
26358
26483
|
console.log(`[BottlenecksContent] Successfully loaded first video via direct S3 method`);
|
|
26359
|
-
setAllVideos(
|
|
26484
|
+
setAllVideos((prev) => {
|
|
26485
|
+
const exists = prev.some((v) => v.id === firstVideo.id);
|
|
26486
|
+
if (!exists) {
|
|
26487
|
+
return [...prev, firstVideo];
|
|
26488
|
+
}
|
|
26489
|
+
return prev;
|
|
26490
|
+
});
|
|
26360
26491
|
preloadVideoUrl(firstVideo.src);
|
|
26492
|
+
setIsLoading(false);
|
|
26493
|
+
setHasInitialLoad(true);
|
|
26361
26494
|
loadingCategoryRef.current = null;
|
|
26362
26495
|
setIsCategoryLoading(false);
|
|
26363
26496
|
return;
|
|
@@ -26380,7 +26513,13 @@ var BottlenecksContent = ({
|
|
|
26380
26513
|
);
|
|
26381
26514
|
if (firstVideo && isMountedRef.current) {
|
|
26382
26515
|
console.log(`[BottlenecksContent] Successfully loaded first video via video index`);
|
|
26383
|
-
setAllVideos(
|
|
26516
|
+
setAllVideos((prev) => {
|
|
26517
|
+
const exists = prev.some((v) => v.id === firstVideo.id);
|
|
26518
|
+
if (!exists) {
|
|
26519
|
+
return [...prev, firstVideo];
|
|
26520
|
+
}
|
|
26521
|
+
return prev;
|
|
26522
|
+
});
|
|
26384
26523
|
preloadVideoUrl(firstVideo.src);
|
|
26385
26524
|
setIsCategoryLoading(false);
|
|
26386
26525
|
return;
|
|
@@ -26403,17 +26542,19 @@ var BottlenecksContent = ({
|
|
|
26403
26542
|
loadingCategoryRef.current = null;
|
|
26404
26543
|
fetchInProgressRef.current.delete(operationKey);
|
|
26405
26544
|
}
|
|
26406
|
-
}, [workspaceId, date, s3ClipsService, clipCounts, videoIndex,
|
|
26545
|
+
}, [workspaceId, date, s3ClipsService, clipCounts, videoIndex, effectiveShift, updateClipCounts, updateVideoIndex]);
|
|
26407
26546
|
useEffect(() => {
|
|
26408
|
-
if (s3ClipsService) {
|
|
26547
|
+
if (s3ClipsService && !prefetchData) {
|
|
26409
26548
|
fetchClipCounts();
|
|
26410
26549
|
}
|
|
26411
|
-
}, [workspaceId, date,
|
|
26550
|
+
}, [workspaceId, date, effectiveShift, s3ClipsService, fetchClipCounts, updateClipCounts, updateVideoIndex, prefetchData]);
|
|
26412
26551
|
useEffect(() => {
|
|
26413
26552
|
if (prefetchData) {
|
|
26414
26553
|
console.log(`[BottlenecksContent] Received prefetch update - status: ${prefetchStatus}, videos: ${prefetchData.videoIndex.allVideos.length}, ID: ${prefetchData.videoIndex._debugId || "NO_ID"}`);
|
|
26415
26554
|
updateClipCounts(prefetchData.counts);
|
|
26416
|
-
|
|
26555
|
+
if (prefetchData.videoIndex.allVideos.length > 0) {
|
|
26556
|
+
updateVideoIndex(prefetchData.videoIndex);
|
|
26557
|
+
}
|
|
26417
26558
|
if (!hasInitialLoad && prefetchData.videoIndex.allVideos.length > 0) {
|
|
26418
26559
|
setIsLoading(false);
|
|
26419
26560
|
setHasInitialLoad(true);
|
|
@@ -26421,12 +26562,45 @@ var BottlenecksContent = ({
|
|
|
26421
26562
|
}
|
|
26422
26563
|
}, [prefetchData, prefetchStatus, updateClipCounts, updateVideoIndex, hasInitialLoad]);
|
|
26423
26564
|
useEffect(() => {
|
|
26424
|
-
if (s3ClipsService &&
|
|
26425
|
-
|
|
26565
|
+
if (s3ClipsService && clipCounts[activeFilter] > 0) {
|
|
26566
|
+
const hasVideosForCurrentFilter = allVideos.some((video) => {
|
|
26567
|
+
if (sopCategories && sopCategories.length > 0) {
|
|
26568
|
+
const selectedCategory = sopCategories.find((cat) => cat.id === activeFilter);
|
|
26569
|
+
if (selectedCategory) {
|
|
26570
|
+
return video.type === selectedCategory.id;
|
|
26571
|
+
}
|
|
26572
|
+
}
|
|
26573
|
+
if (activeFilter === "all") return true;
|
|
26574
|
+
if (activeFilter === "low_value") {
|
|
26575
|
+
return video.type === "low_value";
|
|
26576
|
+
}
|
|
26577
|
+
if (activeFilter === "idle_time") {
|
|
26578
|
+
return video.type === "idle_time";
|
|
26579
|
+
}
|
|
26580
|
+
if (activeFilter === "sop_deviations") {
|
|
26581
|
+
return video.type === "missing_quality_check";
|
|
26582
|
+
}
|
|
26583
|
+
if (activeFilter === "best_cycle_time") {
|
|
26584
|
+
return video.type === "best_cycle_time";
|
|
26585
|
+
}
|
|
26586
|
+
if (activeFilter === "worst_cycle_time") {
|
|
26587
|
+
return video.type === "worst_cycle_time";
|
|
26588
|
+
}
|
|
26589
|
+
if (activeFilter === "cycle_completion") {
|
|
26590
|
+
return video.type === "cycle_completion";
|
|
26591
|
+
}
|
|
26592
|
+
if (activeFilter === "long_cycle_time") {
|
|
26593
|
+
return video.type === "long_cycle_time";
|
|
26594
|
+
}
|
|
26595
|
+
return video.type === "bottleneck" && video.severity === activeFilter;
|
|
26596
|
+
});
|
|
26597
|
+
if (!hasVideosForCurrentFilter) {
|
|
26426
26598
|
loadFirstVideoForCategory(activeFilter);
|
|
26599
|
+
} else {
|
|
26600
|
+
setIsCategoryLoading(false);
|
|
26427
26601
|
}
|
|
26428
26602
|
}
|
|
26429
|
-
}, [activeFilter, s3ClipsService, videoIndex, clipCounts, loadFirstVideoForCategory, allVideos
|
|
26603
|
+
}, [activeFilter, s3ClipsService, videoIndex, clipCounts, loadFirstVideoForCategory, allVideos, sopCategories]);
|
|
26430
26604
|
useEffect(() => {
|
|
26431
26605
|
if (previousFilterRef.current !== activeFilter) {
|
|
26432
26606
|
console.log(`Filter changed from ${previousFilterRef.current} to ${activeFilter} - resetting to first video`);
|
|
@@ -26560,7 +26734,7 @@ var BottlenecksContent = ({
|
|
|
26560
26734
|
}
|
|
26561
26735
|
if (!video && s3ClipsService) {
|
|
26562
26736
|
const operationalDate = date || getOperationalDate();
|
|
26563
|
-
const shiftStr =
|
|
26737
|
+
const shiftStr = effectiveShift;
|
|
26564
26738
|
video = await s3ClipsService.getClipByIndex(
|
|
26565
26739
|
workspaceId,
|
|
26566
26740
|
operationalDate,
|
|
@@ -26596,7 +26770,7 @@ var BottlenecksContent = ({
|
|
|
26596
26770
|
}
|
|
26597
26771
|
}
|
|
26598
26772
|
}
|
|
26599
|
-
}, [clipCounts, filteredVideos.length, s3ClipsService, workspaceId, date,
|
|
26773
|
+
}, [clipCounts, filteredVideos.length, s3ClipsService, workspaceId, date, effectiveShift]);
|
|
26600
26774
|
const handlePrevious = useCallback(() => {
|
|
26601
26775
|
if (!isMountedRef.current) return;
|
|
26602
26776
|
const currentIdx = currentIndexRef.current;
|
|
@@ -26609,14 +26783,39 @@ var BottlenecksContent = ({
|
|
|
26609
26783
|
}
|
|
26610
26784
|
}
|
|
26611
26785
|
}, [filteredVideos.length]);
|
|
26786
|
+
const currentVideo = useMemo(() => {
|
|
26787
|
+
if (!filteredVideos || filteredVideos.length === 0 || currentIndex >= filteredVideos.length) {
|
|
26788
|
+
return null;
|
|
26789
|
+
}
|
|
26790
|
+
return filteredVideos[currentIndex];
|
|
26791
|
+
}, [filteredVideos, currentIndex]);
|
|
26612
26792
|
const handleVideoReady = useCallback((player) => {
|
|
26613
26793
|
console.log("Video.js player ready");
|
|
26614
26794
|
}, []);
|
|
26615
|
-
const handleVideoPlay = useCallback((player) => {
|
|
26795
|
+
const handleVideoPlay = useCallback(async (player) => {
|
|
26616
26796
|
setIsPlaying(true);
|
|
26617
26797
|
const currentIdx = currentIndexRef.current;
|
|
26618
26798
|
ensureVideosLoaded(currentIdx);
|
|
26619
|
-
|
|
26799
|
+
if (currentVideo && !currentVideo.creation_timestamp && s3ClipsService) {
|
|
26800
|
+
try {
|
|
26801
|
+
const originalUri = currentVideo.originalUri || currentVideo.src;
|
|
26802
|
+
if (originalUri && originalUri.includes("s3://")) {
|
|
26803
|
+
const metadata = await s3ClipsService.getFullMetadata(originalUri);
|
|
26804
|
+
if (metadata && isMountedRef.current) {
|
|
26805
|
+
setAllVideos((prev) => prev.map(
|
|
26806
|
+
(v) => v.id === currentVideo.id ? {
|
|
26807
|
+
...v,
|
|
26808
|
+
creation_timestamp: metadata.upload_timestamp || metadata.original_task_metadata?.timestamp || metadata.creation_timestamp,
|
|
26809
|
+
cycle_time_seconds: metadata.original_task_metadata?.cycle_time || v.cycle_time_seconds
|
|
26810
|
+
} : v
|
|
26811
|
+
));
|
|
26812
|
+
}
|
|
26813
|
+
}
|
|
26814
|
+
} catch (error2) {
|
|
26815
|
+
console.warn("[BottlenecksContent] Failed to load metadata for current video:", error2);
|
|
26816
|
+
}
|
|
26817
|
+
}
|
|
26818
|
+
}, [currentVideo, s3ClipsService]);
|
|
26620
26819
|
const handleVideoPause = useCallback((player) => {
|
|
26621
26820
|
setIsPlaying(false);
|
|
26622
26821
|
}, []);
|
|
@@ -26643,13 +26842,6 @@ var BottlenecksContent = ({
|
|
|
26643
26842
|
fetchInProgressRef.current.clear();
|
|
26644
26843
|
setIsCategoryLoading(false);
|
|
26645
26844
|
setIsNavigating(false);
|
|
26646
|
-
if (s3ClipsService) {
|
|
26647
|
-
try {
|
|
26648
|
-
s3ClipsService.dispose();
|
|
26649
|
-
} catch (error2) {
|
|
26650
|
-
console.warn("[BottlenecksContent] Error disposing S3 service:", error2);
|
|
26651
|
-
}
|
|
26652
|
-
}
|
|
26653
26845
|
};
|
|
26654
26846
|
}, [s3ClipsService]);
|
|
26655
26847
|
useEffect(() => {
|
|
@@ -26690,12 +26882,6 @@ var BottlenecksContent = ({
|
|
|
26690
26882
|
counts.bottlenecks = counts.bottleneck || counts.bottlenecks || 0;
|
|
26691
26883
|
return counts;
|
|
26692
26884
|
}, [clipCounts]);
|
|
26693
|
-
const currentVideo = useMemo(() => {
|
|
26694
|
-
if (!filteredVideos || filteredVideos.length === 0 || currentIndex >= filteredVideos.length) {
|
|
26695
|
-
return null;
|
|
26696
|
-
}
|
|
26697
|
-
return filteredVideos[currentIndex];
|
|
26698
|
-
}, [filteredVideos, currentIndex]);
|
|
26699
26885
|
const getClipTypeLabel = (video) => {
|
|
26700
26886
|
if (!video) return "";
|
|
26701
26887
|
switch (video.type) {
|
|
@@ -26930,8 +27116,8 @@ var BottlenecksContent = ({
|
|
|
26930
27116
|
] }),
|
|
26931
27117
|
/* Priority 1: Show loading if initial load hasn't completed yet */
|
|
26932
27118
|
isLoading && !hasInitialLoad ? /* @__PURE__ */ jsx("div", { className: "p-4 h-[calc(100%-4rem)]", children: /* @__PURE__ */ jsx("div", { className: "relative h-full", children: /* @__PURE__ */ jsx("div", { className: "relative w-full h-full overflow-hidden rounded-md shadow-inner bg-gray-900 flex items-center justify-center", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading clips..." }) }) }) }) : (
|
|
26933
|
-
/* Priority 2: Show loading if category is loading
|
|
26934
|
-
isCategoryLoading ? /* @__PURE__ */ jsx("div", { className: "p-4 h-[calc(100%-4rem)]", children: /* @__PURE__ */ jsx("div", { className: "relative h-full", children: /* @__PURE__ */ jsx("div", { className: "relative w-full h-full overflow-hidden rounded-md shadow-inner bg-gray-900 flex items-center justify-center", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading videos..." }) }) }) }) : (
|
|
27119
|
+
/* Priority 2: Show loading if category is loading BUT only if no video is available */
|
|
27120
|
+
isCategoryLoading && (!filteredVideos.length || !currentVideo) ? /* @__PURE__ */ jsx("div", { className: "p-4 h-[calc(100%-4rem)]", children: /* @__PURE__ */ jsx("div", { className: "relative h-full", children: /* @__PURE__ */ jsx("div", { className: "relative w-full h-full overflow-hidden rounded-md shadow-inner bg-gray-900 flex items-center justify-center", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading videos..." }) }) }) }) : (
|
|
26935
27121
|
/* Priority 3: Show loading if navigating and current video not available */
|
|
26936
27122
|
isNavigating || currentIndex >= filteredVideos.length && currentIndex < clipCounts[activeFilter] ? /* @__PURE__ */ jsx("div", { className: "p-4 h-[calc(100%-4rem)]", children: /* @__PURE__ */ jsx("div", { className: "relative h-full", children: /* @__PURE__ */ jsx("div", { className: "relative w-full h-full overflow-hidden rounded-md shadow-inner bg-gray-900 flex items-center justify-center", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading video..." }) }) }) }) : (
|
|
26937
27123
|
/* Priority 4: Show video if we have filtered videos and current video */
|
|
@@ -31288,7 +31474,7 @@ var HelpView = ({
|
|
|
31288
31474
|
onClick: handleBackClick,
|
|
31289
31475
|
className: "flex items-center text-gray-600 hover:text-gray-900",
|
|
31290
31476
|
children: [
|
|
31291
|
-
/* @__PURE__ */ jsx(ArrowLeftIcon, { className: "h-5 w-5" }),
|
|
31477
|
+
/* @__PURE__ */ jsx(ArrowLeftIcon$1, { className: "h-5 w-5" }),
|
|
31292
31478
|
/* @__PURE__ */ jsx("span", { className: "ml-2", children: "Back" })
|
|
31293
31479
|
]
|
|
31294
31480
|
}
|
|
@@ -31729,9 +31915,25 @@ function withWorkspaceDisplayNames(Component3, options = {}) {
|
|
|
31729
31915
|
return function WithWorkspaceDisplayNamesWrapper(props) {
|
|
31730
31916
|
const [isInitialized2, setIsInitialized] = useState(false);
|
|
31731
31917
|
const [error, setError] = useState(null);
|
|
31918
|
+
const [lastInitKey, setLastInitKey] = useState("");
|
|
31919
|
+
const lineIdsKey = useMemo(() => {
|
|
31920
|
+
if (!props.lineIds) return "";
|
|
31921
|
+
if (Array.isArray(props.lineIds)) {
|
|
31922
|
+
return props.lineIds.sort().join(",");
|
|
31923
|
+
}
|
|
31924
|
+
const values = Object.values(props.lineIds).filter(Boolean);
|
|
31925
|
+
return values.sort().join(",");
|
|
31926
|
+
}, [props.lineIds]);
|
|
31927
|
+
const initKey = useMemo(() => {
|
|
31928
|
+
return `${lineIdsKey}-${props.selectedLineId || ""}-${props.factoryViewId || ""}-${initializeFor}`;
|
|
31929
|
+
}, [lineIdsKey, props.selectedLineId, props.factoryViewId]);
|
|
31732
31930
|
useEffect(() => {
|
|
31733
|
-
|
|
31734
|
-
|
|
31931
|
+
if (initKey === lastInitKey && isInitialized2) {
|
|
31932
|
+
return;
|
|
31933
|
+
}
|
|
31934
|
+
if (initKey !== lastInitKey) {
|
|
31935
|
+
setError(null);
|
|
31936
|
+
}
|
|
31735
31937
|
const initializeDisplayNames = async () => {
|
|
31736
31938
|
try {
|
|
31737
31939
|
const { lineIds, selectedLineId, factoryViewId } = props;
|
|
@@ -31757,20 +31959,17 @@ function withWorkspaceDisplayNames(Component3, options = {}) {
|
|
|
31757
31959
|
await preInitializeWorkspaceDisplayNames();
|
|
31758
31960
|
}
|
|
31759
31961
|
setIsInitialized(true);
|
|
31962
|
+
setLastInitKey(initKey);
|
|
31760
31963
|
} catch (err) {
|
|
31761
31964
|
console.error("Failed to initialize workspace display names:", err);
|
|
31762
31965
|
setError(err);
|
|
31763
31966
|
setIsInitialized(true);
|
|
31967
|
+
setLastInitKey(initKey);
|
|
31764
31968
|
}
|
|
31765
31969
|
};
|
|
31766
31970
|
initializeDisplayNames();
|
|
31767
|
-
}, [
|
|
31768
|
-
|
|
31769
|
-
props.selectedLineId,
|
|
31770
|
-
props.factoryViewId,
|
|
31771
|
-
initializeFor
|
|
31772
|
-
]);
|
|
31773
|
-
if (!isInitialized2 && showLoading) {
|
|
31971
|
+
}, [initKey]);
|
|
31972
|
+
if (!isInitialized2 && showLoading && lastInitKey === "") {
|
|
31774
31973
|
return /* @__PURE__ */ jsx(LoadingPage, { message: loadingMessage });
|
|
31775
31974
|
}
|
|
31776
31975
|
if (error && showLoading) {
|
|
@@ -32410,7 +32609,7 @@ var KPIDetailView = ({
|
|
|
32410
32609
|
onClick: handleBackClick,
|
|
32411
32610
|
className: "absolute left-0 flex items-center text-gray-600 hover:text-gray-900 cursor-pointer",
|
|
32412
32611
|
children: [
|
|
32413
|
-
/* @__PURE__ */ jsx(ArrowLeftIcon, { className: "h-5 w-5" }),
|
|
32612
|
+
/* @__PURE__ */ jsx(ArrowLeftIcon$1, { className: "h-5 w-5" }),
|
|
32414
32613
|
/* @__PURE__ */ jsx("span", { className: "ml-2", children: "Back" })
|
|
32415
32614
|
]
|
|
32416
32615
|
}
|
|
@@ -32782,7 +32981,7 @@ var KPIsOverviewView = ({
|
|
|
32782
32981
|
onClick: handleBackClick,
|
|
32783
32982
|
className: "absolute left-0 flex items-center text-gray-600 hover:text-gray-900 cursor-pointer",
|
|
32784
32983
|
children: [
|
|
32785
|
-
/* @__PURE__ */ jsx(ArrowLeftIcon, { className: "h-5 w-5" }),
|
|
32984
|
+
/* @__PURE__ */ jsx(ArrowLeftIcon$1, { className: "h-5 w-5" }),
|
|
32786
32985
|
/* @__PURE__ */ jsx("span", { className: "ml-2", children: "Back" })
|
|
32787
32986
|
]
|
|
32788
32987
|
}
|
|
@@ -32804,7 +33003,7 @@ var KPIsOverviewView = ({
|
|
|
32804
33003
|
onClick: handleBackClick,
|
|
32805
33004
|
className: "absolute left-0 flex items-center text-gray-600 hover:text-gray-900 cursor-pointer",
|
|
32806
33005
|
children: [
|
|
32807
|
-
/* @__PURE__ */ jsx(ArrowLeftIcon, { className: "h-5 w-5" }),
|
|
33006
|
+
/* @__PURE__ */ jsx(ArrowLeftIcon$1, { className: "h-5 w-5" }),
|
|
32808
33007
|
/* @__PURE__ */ jsx("span", { className: "ml-2", children: "Back" })
|
|
32809
33008
|
]
|
|
32810
33009
|
}
|
|
@@ -32829,7 +33028,7 @@ var KPIsOverviewView = ({
|
|
|
32829
33028
|
onClick: handleBackClick,
|
|
32830
33029
|
className: "absolute left-0 flex items-center text-gray-600 hover:text-gray-900 cursor-pointer",
|
|
32831
33030
|
children: [
|
|
32832
|
-
/* @__PURE__ */ jsx(ArrowLeftIcon, { className: "h-5 w-5" }),
|
|
33031
|
+
/* @__PURE__ */ jsx(ArrowLeftIcon$1, { className: "h-5 w-5" }),
|
|
32833
33032
|
/* @__PURE__ */ jsx("span", { className: "ml-2", children: "Back" })
|
|
32834
33033
|
]
|
|
32835
33034
|
}
|
|
@@ -33841,7 +34040,15 @@ var ShiftsView = ({
|
|
|
33841
34040
|
className = ""
|
|
33842
34041
|
}) => {
|
|
33843
34042
|
const supabase = useSupabase();
|
|
33844
|
-
|
|
34043
|
+
useEffect(() => {
|
|
34044
|
+
console.log("[ShiftsView] Component mounted/re-rendered", {
|
|
34045
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
34046
|
+
lineIds: lineIds.length
|
|
34047
|
+
});
|
|
34048
|
+
return () => {
|
|
34049
|
+
console.log("[ShiftsView] Component unmounting");
|
|
34050
|
+
};
|
|
34051
|
+
}, []);
|
|
33845
34052
|
const [lineConfigs, setLineConfigs] = useState(
|
|
33846
34053
|
() => lineIds.map((id3) => ({
|
|
33847
34054
|
id: id3,
|
|
@@ -33939,7 +34146,7 @@ var ShiftsView = ({
|
|
|
33939
34146
|
}
|
|
33940
34147
|
};
|
|
33941
34148
|
fetchShiftConfigs();
|
|
33942
|
-
}, [
|
|
34149
|
+
}, [lineIds, showToast]);
|
|
33943
34150
|
useCallback((lineId) => {
|
|
33944
34151
|
setLineConfigs((prev) => {
|
|
33945
34152
|
const typedPrev = prev;
|
|
@@ -34132,7 +34339,6 @@ var ShiftsView = ({
|
|
|
34132
34339
|
}));
|
|
34133
34340
|
}, []);
|
|
34134
34341
|
const handleSaveShifts = useCallback(async (lineId) => {
|
|
34135
|
-
if (!auth.user?.id && false) ;
|
|
34136
34342
|
setLineConfigs((prev) => prev.map(
|
|
34137
34343
|
(config) => config.id === lineId ? { ...config, isSaving: true, saveSuccess: false } : config
|
|
34138
34344
|
));
|
|
@@ -34179,7 +34385,7 @@ var ShiftsView = ({
|
|
|
34179
34385
|
(config) => config.id === lineId ? { ...config, isSaving: false, saveSuccess: false } : config
|
|
34180
34386
|
));
|
|
34181
34387
|
}
|
|
34182
|
-
}, [
|
|
34388
|
+
}, [lineConfigs, supabase, showToast]);
|
|
34183
34389
|
return /* @__PURE__ */ jsxs("div", { className: `min-h-screen bg-slate-50 ${className}`, children: [
|
|
34184
34390
|
/* @__PURE__ */ jsx("div", { className: "sticky top-0 z-10 bg-white border-b border-gray-200/80 shadow-sm", children: /* @__PURE__ */ jsx("div", { className: "px-4 sm:px-8 py-4", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center relative", children: [
|
|
34185
34391
|
/* @__PURE__ */ jsxs(
|
|
@@ -34287,6 +34493,7 @@ var ShiftsView = ({
|
|
|
34287
34493
|
] })
|
|
34288
34494
|
] });
|
|
34289
34495
|
};
|
|
34496
|
+
var AuthenticatedShiftsView = withAuth(React19__default.memo(ShiftsView));
|
|
34290
34497
|
var ShiftsView_default = ShiftsView;
|
|
34291
34498
|
|
|
34292
34499
|
// src/lib/constants/actions.ts
|
|
@@ -35074,6 +35281,7 @@ var TargetsViewUI = ({
|
|
|
35074
35281
|
isLoading,
|
|
35075
35282
|
lineWorkspaces,
|
|
35076
35283
|
lineNames,
|
|
35284
|
+
dropdownStates,
|
|
35077
35285
|
savingLines,
|
|
35078
35286
|
saveSuccess,
|
|
35079
35287
|
selectedShift,
|
|
@@ -35106,7 +35314,7 @@ var TargetsViewUI = ({
|
|
|
35106
35314
|
onClick: onBack,
|
|
35107
35315
|
className: "flex items-center text-gray-600 hover:text-gray-900",
|
|
35108
35316
|
children: [
|
|
35109
|
-
/* @__PURE__ */ jsx(ArrowLeftIcon
|
|
35317
|
+
/* @__PURE__ */ jsx(ArrowLeftIcon, { className: "h-5 w-5" }),
|
|
35110
35318
|
/* @__PURE__ */ jsx("span", { className: "ml-2", children: "Back" })
|
|
35111
35319
|
]
|
|
35112
35320
|
}
|
|
@@ -35159,13 +35367,13 @@ var TargetsViewUI = ({
|
|
|
35159
35367
|
{
|
|
35160
35368
|
onClick: () => onToggleLineDropdown(lineId),
|
|
35161
35369
|
className: "flex items-center gap-3 text-lg font-medium transition-colors duration-200 \n focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 rounded-lg \n hover:bg-blue-50 px-3 py-2 group",
|
|
35162
|
-
"aria-expanded":
|
|
35370
|
+
"aria-expanded": dropdownStates[lineId],
|
|
35163
35371
|
"aria-controls": `line-${lineId}-content`,
|
|
35164
35372
|
children: [
|
|
35165
35373
|
/* @__PURE__ */ jsx(
|
|
35166
35374
|
ChevronDown,
|
|
35167
35375
|
{
|
|
35168
|
-
className: `w-5 h-5 text-blue-500 transform transition-transform duration-200 ${
|
|
35376
|
+
className: `w-5 h-5 text-blue-500 transform transition-transform duration-200 ${dropdownStates[lineId] ? "rotate-180" : ""}`
|
|
35169
35377
|
}
|
|
35170
35378
|
),
|
|
35171
35379
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5", children: [
|
|
@@ -35212,7 +35420,7 @@ var TargetsViewUI = ({
|
|
|
35212
35420
|
)
|
|
35213
35421
|
] })
|
|
35214
35422
|
] }) }),
|
|
35215
|
-
|
|
35423
|
+
dropdownStates[lineId] && /* @__PURE__ */ jsxs("div", { id: `line-${lineId}-content`, className: "border-t border-gray-200", children: [
|
|
35216
35424
|
skuEnabled && /* @__PURE__ */ jsx("div", { className: "px-6 py-4 border-b border-gray-200 bg-gray-50/50", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4", children: [
|
|
35217
35425
|
/* @__PURE__ */ jsx("label", { htmlFor: `sku-${lineId}`, className: "text-sm font-medium text-gray-700", children: "Select SKU:" }),
|
|
35218
35426
|
/* @__PURE__ */ jsx("div", { className: "flex-1 max-w-md", children: /* @__PURE__ */ jsx(
|
|
@@ -35249,68 +35457,71 @@ var TargetsViewUI = ({
|
|
|
35249
35457
|
/* @__PURE__ */ jsx("span", { className: "text-xs text-gray-400", children: "pieces per day" })
|
|
35250
35458
|
] })
|
|
35251
35459
|
] }) }),
|
|
35252
|
-
/* @__PURE__ */ jsx("div", { className: "divide-y divide-gray-100", children: line.workspaces.map((workspace) =>
|
|
35253
|
-
|
|
35254
|
-
|
|
35255
|
-
|
|
35256
|
-
|
|
35257
|
-
|
|
35258
|
-
/* @__PURE__ */
|
|
35259
|
-
"
|
|
35260
|
-
{
|
|
35261
|
-
|
|
35262
|
-
|
|
35263
|
-
|
|
35264
|
-
|
|
35265
|
-
|
|
35266
|
-
|
|
35267
|
-
|
|
35268
|
-
|
|
35269
|
-
|
|
35270
|
-
|
|
35271
|
-
|
|
35272
|
-
|
|
35273
|
-
|
|
35274
|
-
|
|
35275
|
-
|
|
35276
|
-
{
|
|
35277
|
-
|
|
35278
|
-
|
|
35279
|
-
|
|
35280
|
-
|
|
35281
|
-
|
|
35282
|
-
|
|
35283
|
-
|
|
35284
|
-
|
|
35285
|
-
|
|
35286
|
-
|
|
35287
|
-
|
|
35288
|
-
{
|
|
35289
|
-
|
|
35290
|
-
|
|
35291
|
-
|
|
35292
|
-
|
|
35293
|
-
|
|
35294
|
-
|
|
35295
|
-
|
|
35296
|
-
|
|
35297
|
-
|
|
35298
|
-
|
|
35299
|
-
|
|
35300
|
-
{
|
|
35301
|
-
|
|
35302
|
-
|
|
35303
|
-
|
|
35304
|
-
|
|
35305
|
-
|
|
35306
|
-
|
|
35307
|
-
|
|
35308
|
-
|
|
35309
|
-
|
|
35310
|
-
|
|
35311
|
-
|
|
35312
|
-
|
|
35313
|
-
|
|
35460
|
+
/* @__PURE__ */ jsx("div", { className: "divide-y divide-gray-100", children: line.workspaces.map((workspace) => {
|
|
35461
|
+
const formattedName = formatWorkspaceName(workspace.name, lineId);
|
|
35462
|
+
return /* @__PURE__ */ jsx(
|
|
35463
|
+
"div",
|
|
35464
|
+
{
|
|
35465
|
+
className: "px-6 py-4 hover:bg-gray-50 transition-all duration-200",
|
|
35466
|
+
children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-12 gap-6 items-center", children: [
|
|
35467
|
+
/* @__PURE__ */ jsx("div", { className: "col-span-2", children: /* @__PURE__ */ jsx("span", { className: "font-medium text-gray-900", children: formattedName }) }),
|
|
35468
|
+
/* @__PURE__ */ jsx("div", { className: "col-span-2", children: /* @__PURE__ */ jsxs(
|
|
35469
|
+
"select",
|
|
35470
|
+
{
|
|
35471
|
+
value: workspace.actionType,
|
|
35472
|
+
onChange: (e) => {
|
|
35473
|
+
const newActionType = e.target.value;
|
|
35474
|
+
onActionTypeChange(lineId, workspace.id, newActionType);
|
|
35475
|
+
},
|
|
35476
|
+
className: "w-full p-2 border border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm",
|
|
35477
|
+
"aria-label": `Action type for ${formattedName}`,
|
|
35478
|
+
children: [
|
|
35479
|
+
/* @__PURE__ */ jsx("option", { value: "assembly", className: "py-2", children: "Assembly" }),
|
|
35480
|
+
/* @__PURE__ */ jsx("option", { value: "packaging", className: "py-2", children: "Packaging" })
|
|
35481
|
+
]
|
|
35482
|
+
}
|
|
35483
|
+
) }),
|
|
35484
|
+
/* @__PURE__ */ jsx("div", { className: "col-span-3", children: /* @__PURE__ */ jsx(
|
|
35485
|
+
"input",
|
|
35486
|
+
{
|
|
35487
|
+
type: "number",
|
|
35488
|
+
value: workspace.targetCycleTime === 0 ? "" : workspace.targetCycleTime,
|
|
35489
|
+
onChange: (e) => onUpdateWorkspaceTarget(lineId, workspace.id, "targetCycleTime", Number(e.target.value) || ""),
|
|
35490
|
+
className: "block w-full rounded-lg border border-gray-300 bg-white px-3 py-2 text-sm\n shadow-sm focus:border-blue-500 focus:ring-blue-500 \n transition-all duration-200 hover:border-gray-400",
|
|
35491
|
+
min: "0",
|
|
35492
|
+
step: "0.01",
|
|
35493
|
+
placeholder: "Enter cycle time"
|
|
35494
|
+
}
|
|
35495
|
+
) }),
|
|
35496
|
+
/* @__PURE__ */ jsx("div", { className: "col-span-3", children: /* @__PURE__ */ jsx(
|
|
35497
|
+
"input",
|
|
35498
|
+
{
|
|
35499
|
+
type: "number",
|
|
35500
|
+
value: workspace.targetPPH === 0 ? "" : workspace.targetPPH,
|
|
35501
|
+
onChange: (e) => onUpdateWorkspaceTarget(lineId, workspace.id, "targetPPH", Number(e.target.value) || ""),
|
|
35502
|
+
className: "block w-full rounded-lg border border-gray-300 bg-white px-3 py-2 text-sm\n shadow-sm focus:border-blue-500 focus:ring-blue-500 \n transition-all duration-200 hover:border-gray-400 \n placeholder:text-gray-400",
|
|
35503
|
+
min: "0",
|
|
35504
|
+
step: "0.1",
|
|
35505
|
+
placeholder: "Enter PPH"
|
|
35506
|
+
}
|
|
35507
|
+
) }),
|
|
35508
|
+
/* @__PURE__ */ jsx("div", { className: "col-span-2", children: /* @__PURE__ */ jsx(
|
|
35509
|
+
"input",
|
|
35510
|
+
{
|
|
35511
|
+
type: "number",
|
|
35512
|
+
value: workspace.targetDayOutput === 0 ? "" : workspace.targetDayOutput,
|
|
35513
|
+
onChange: (e) => onUpdateWorkspaceTarget(lineId, workspace.id, "targetDayOutput", Number(e.target.value) || ""),
|
|
35514
|
+
className: "block w-full rounded-lg border border-gray-300 bg-white px-3 py-2 text-sm\n shadow-sm focus:border-blue-500 focus:ring-blue-500 \n transition-all duration-200 hover:border-gray-400 \n placeholder:text-gray-400",
|
|
35515
|
+
min: "0",
|
|
35516
|
+
step: "1",
|
|
35517
|
+
placeholder: "Enter day output"
|
|
35518
|
+
}
|
|
35519
|
+
) })
|
|
35520
|
+
] })
|
|
35521
|
+
},
|
|
35522
|
+
workspace.id
|
|
35523
|
+
);
|
|
35524
|
+
}) })
|
|
35314
35525
|
] })
|
|
35315
35526
|
]
|
|
35316
35527
|
},
|
|
@@ -35343,7 +35554,6 @@ var TargetsView = ({
|
|
|
35343
35554
|
return lineIds.reduce((acc, lineId) => ({
|
|
35344
35555
|
...acc,
|
|
35345
35556
|
[lineId]: {
|
|
35346
|
-
isOpen: getStoredLineState2(lineId),
|
|
35347
35557
|
productId: "",
|
|
35348
35558
|
shiftStartTime: "08:00",
|
|
35349
35559
|
shiftEndTime: "19:00",
|
|
@@ -35356,6 +35566,12 @@ var TargetsView = ({
|
|
|
35356
35566
|
}
|
|
35357
35567
|
}), {});
|
|
35358
35568
|
}, [lineIds]);
|
|
35569
|
+
const [dropdownStates, setDropdownStates] = useState(() => {
|
|
35570
|
+
return lineIds.reduce((acc, lineId) => ({
|
|
35571
|
+
...acc,
|
|
35572
|
+
[lineId]: getStoredLineState2(lineId)
|
|
35573
|
+
}), {});
|
|
35574
|
+
});
|
|
35359
35575
|
const [allShiftsData, setAllShiftsData] = useState({
|
|
35360
35576
|
0: initialLineWorkspaces,
|
|
35361
35577
|
// Day shift
|
|
@@ -35373,6 +35589,8 @@ var TargetsView = ({
|
|
|
35373
35589
|
const [isBulkConfigureOpen, setIsBulkConfigureOpen] = useState(false);
|
|
35374
35590
|
const [selectedWorkspaces, setSelectedWorkspaces] = useState([]);
|
|
35375
35591
|
const [selectedShift, setSelectedShift] = useState(0);
|
|
35592
|
+
const [dbValues, setDbValues] = useState({ 0: {}, 1: {} });
|
|
35593
|
+
const [userEditedFields, setUserEditedFields] = useState(/* @__PURE__ */ new Set());
|
|
35376
35594
|
const lineWorkspaces = allShiftsData[selectedShift] || initialLineWorkspaces;
|
|
35377
35595
|
const setLineWorkspaces = useCallback((updater) => {
|
|
35378
35596
|
setAllShiftsData((prev) => ({
|
|
@@ -35381,18 +35599,123 @@ var TargetsView = ({
|
|
|
35381
35599
|
}));
|
|
35382
35600
|
}, [selectedShift]);
|
|
35383
35601
|
const supabase = useSupabase();
|
|
35384
|
-
const
|
|
35385
|
-
userId || auth?.user?.id;
|
|
35602
|
+
const effectiveUserId = userId || "6bf6f271-1e55-4a95-9b89-1c3820b58739";
|
|
35386
35603
|
const dashboardConfig = useDashboardConfig();
|
|
35387
35604
|
const { skus, isLoading: skusLoading } = useSKUs(companyId);
|
|
35388
35605
|
const skuEnabled = dashboardConfig?.skuConfig?.enabled || false;
|
|
35606
|
+
const loadOperatingHours = useCallback(async (lineId, shiftId) => {
|
|
35607
|
+
try {
|
|
35608
|
+
if (!supabase) return null;
|
|
35609
|
+
const { data, error } = await supabase.from("line_operating_hours").select("start_time, end_time, breaks").eq("line_id", lineId).eq("shift_id", shiftId).maybeSingle();
|
|
35610
|
+
if (error) {
|
|
35611
|
+
if (error.code === "PGRST116") {
|
|
35612
|
+
console.log(`No operating hours found for line ${lineId}, shift ${shiftId}`);
|
|
35613
|
+
return {
|
|
35614
|
+
startTime: "08:00",
|
|
35615
|
+
// Default values
|
|
35616
|
+
endTime: "19:00",
|
|
35617
|
+
breaks: []
|
|
35618
|
+
};
|
|
35619
|
+
} else {
|
|
35620
|
+
console.error("Error fetching operating hours:", error);
|
|
35621
|
+
return null;
|
|
35622
|
+
}
|
|
35623
|
+
}
|
|
35624
|
+
let breaks = [];
|
|
35625
|
+
if (data?.breaks) {
|
|
35626
|
+
if (Array.isArray(data.breaks)) {
|
|
35627
|
+
breaks = data.breaks.map((breakItem) => {
|
|
35628
|
+
const startTime = breakItem.start || breakItem.startTime || "00:00";
|
|
35629
|
+
const endTime = breakItem.end || breakItem.endTime || "00:00";
|
|
35630
|
+
const calculateDuration = (start, end) => {
|
|
35631
|
+
const [startHour, startMinute] = start.split(":").map(Number);
|
|
35632
|
+
const [endHour, endMinute] = end.split(":").map(Number);
|
|
35633
|
+
let startMinutes = startHour * 60 + startMinute;
|
|
35634
|
+
let endMinutes = endHour * 60 + endMinute;
|
|
35635
|
+
if (endMinutes < startMinutes) {
|
|
35636
|
+
endMinutes += 24 * 60;
|
|
35637
|
+
}
|
|
35638
|
+
return endMinutes - startMinutes;
|
|
35639
|
+
};
|
|
35640
|
+
return {
|
|
35641
|
+
startTime,
|
|
35642
|
+
endTime,
|
|
35643
|
+
duration: breakItem.duration || calculateDuration(startTime, endTime)
|
|
35644
|
+
};
|
|
35645
|
+
});
|
|
35646
|
+
} else if (typeof data.breaks === "object" && data.breaks.breaks) {
|
|
35647
|
+
breaks = data.breaks.breaks.map((breakItem) => {
|
|
35648
|
+
const startTime = breakItem.start || breakItem.startTime || "00:00";
|
|
35649
|
+
const endTime = breakItem.end || breakItem.endTime || "00:00";
|
|
35650
|
+
const calculateDuration = (start, end) => {
|
|
35651
|
+
const [startHour, startMinute] = start.split(":").map(Number);
|
|
35652
|
+
const [endHour, endMinute] = end.split(":").map(Number);
|
|
35653
|
+
let startMinutes = startHour * 60 + startMinute;
|
|
35654
|
+
let endMinutes = endHour * 60 + endMinute;
|
|
35655
|
+
if (endMinutes < startMinutes) {
|
|
35656
|
+
endMinutes += 24 * 60;
|
|
35657
|
+
}
|
|
35658
|
+
return endMinutes - startMinutes;
|
|
35659
|
+
};
|
|
35660
|
+
return {
|
|
35661
|
+
startTime,
|
|
35662
|
+
endTime,
|
|
35663
|
+
duration: breakItem.duration || calculateDuration(startTime, endTime)
|
|
35664
|
+
};
|
|
35665
|
+
});
|
|
35666
|
+
} else if (typeof data.breaks === "string") {
|
|
35667
|
+
try {
|
|
35668
|
+
const parsedBreaks = JSON.parse(data.breaks);
|
|
35669
|
+
if (Array.isArray(parsedBreaks)) {
|
|
35670
|
+
breaks = parsedBreaks.map((breakItem) => ({
|
|
35671
|
+
startTime: breakItem.start || breakItem.startTime || "00:00",
|
|
35672
|
+
endTime: breakItem.end || breakItem.endTime || "00:00",
|
|
35673
|
+
duration: breakItem.duration || 0
|
|
35674
|
+
}));
|
|
35675
|
+
} else if (parsedBreaks.breaks && Array.isArray(parsedBreaks.breaks)) {
|
|
35676
|
+
breaks = parsedBreaks.breaks.map((breakItem) => ({
|
|
35677
|
+
startTime: breakItem.start || breakItem.startTime || "00:00",
|
|
35678
|
+
endTime: breakItem.end || breakItem.endTime || "00:00",
|
|
35679
|
+
duration: breakItem.duration || 0
|
|
35680
|
+
}));
|
|
35681
|
+
}
|
|
35682
|
+
} catch (e) {
|
|
35683
|
+
console.error("Error parsing breaks data:", e);
|
|
35684
|
+
}
|
|
35685
|
+
}
|
|
35686
|
+
}
|
|
35687
|
+
return {
|
|
35688
|
+
startTime: data?.start_time || "08:00",
|
|
35689
|
+
endTime: data?.end_time || "19:00",
|
|
35690
|
+
breaks
|
|
35691
|
+
};
|
|
35692
|
+
} catch (e) {
|
|
35693
|
+
console.error("Exception when loading operating hours:", e);
|
|
35694
|
+
return {
|
|
35695
|
+
startTime: "08:00",
|
|
35696
|
+
endTime: "19:00",
|
|
35697
|
+
breaks: []
|
|
35698
|
+
};
|
|
35699
|
+
}
|
|
35700
|
+
}, [supabase]);
|
|
35701
|
+
useEffect(() => {
|
|
35702
|
+
console.log("[TargetsView] Component mounted/re-rendered", {
|
|
35703
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
35704
|
+
lineIds: lineIds.length,
|
|
35705
|
+
effectiveUserId
|
|
35706
|
+
});
|
|
35707
|
+
return () => {
|
|
35708
|
+
console.log("[TargetsView] Component unmounting");
|
|
35709
|
+
};
|
|
35710
|
+
}, []);
|
|
35389
35711
|
useEffect(() => {
|
|
35390
35712
|
let timeoutId;
|
|
35391
35713
|
let retryCount = 0;
|
|
35392
35714
|
const MAX_RETRIES2 = 2;
|
|
35393
35715
|
const LOADING_TIMEOUT = 15e3;
|
|
35394
35716
|
const fetchInitialData = async () => {
|
|
35395
|
-
if (
|
|
35717
|
+
if (lineIds.length === 0) return;
|
|
35718
|
+
console.log("[TargetsView] Starting fetchInitialData");
|
|
35396
35719
|
setIsLoading(true);
|
|
35397
35720
|
timeoutId = setTimeout(() => {
|
|
35398
35721
|
console.error("Loading timeout reached");
|
|
@@ -35456,10 +35779,32 @@ var TargetsView = ({
|
|
|
35456
35779
|
const actionThresholds = await workspaceService.getActionThresholds(
|
|
35457
35780
|
lineId,
|
|
35458
35781
|
currentDate,
|
|
35459
|
-
|
|
35782
|
+
0
|
|
35783
|
+
// Always use day shift for initial load
|
|
35460
35784
|
);
|
|
35785
|
+
const operatingHoursData = await loadOperatingHours(lineId, 0);
|
|
35786
|
+
if (operatingHoursData) {
|
|
35787
|
+
updatedLineWorkspaces[lineId].shiftStartTime = operatingHoursData.startTime;
|
|
35788
|
+
updatedLineWorkspaces[lineId].shiftEndTime = operatingHoursData.endTime;
|
|
35789
|
+
updatedLineWorkspaces[lineId].breaks = operatingHoursData.breaks;
|
|
35790
|
+
updatedLineWorkspaces[lineId].shiftHours = calculateShiftHours2(
|
|
35791
|
+
operatingHoursData.startTime,
|
|
35792
|
+
operatingHoursData.endTime,
|
|
35793
|
+
operatingHoursData.breaks
|
|
35794
|
+
);
|
|
35795
|
+
}
|
|
35461
35796
|
const mappedWorkspaces = enabledWorkspaces.map((ws) => {
|
|
35462
35797
|
const threshold = actionThresholds.find((t) => t.workspace_id === ws.id);
|
|
35798
|
+
if (!dbValues[0][lineId]) {
|
|
35799
|
+
dbValues[0][lineId] = {};
|
|
35800
|
+
}
|
|
35801
|
+
if (threshold) {
|
|
35802
|
+
dbValues[0][lineId][ws.id] = {
|
|
35803
|
+
targetPPH: threshold.pph_threshold,
|
|
35804
|
+
targetCycleTime: threshold.ideal_cycle_time,
|
|
35805
|
+
targetDayOutput: threshold.total_day_output
|
|
35806
|
+
};
|
|
35807
|
+
}
|
|
35463
35808
|
return {
|
|
35464
35809
|
id: ws.id,
|
|
35465
35810
|
name: ws.workspace_id,
|
|
@@ -35500,90 +35845,7 @@ var TargetsView = ({
|
|
|
35500
35845
|
return () => {
|
|
35501
35846
|
clearTimeout(timeoutId);
|
|
35502
35847
|
};
|
|
35503
|
-
}, [
|
|
35504
|
-
useCallback(async (shiftId) => {
|
|
35505
|
-
try {
|
|
35506
|
-
if (!supabase) return;
|
|
35507
|
-
const currentDate = getOperationalDate();
|
|
35508
|
-
const updatedLineWorkspaces = { ...lineWorkspaces };
|
|
35509
|
-
let hasUpdates = false;
|
|
35510
|
-
for (const lineId of lineIds) {
|
|
35511
|
-
const lineState = lineWorkspaces[lineId];
|
|
35512
|
-
if (!lineState || !lineState.factoryId) {
|
|
35513
|
-
console.warn(`Skipping line thresholds for ${lineId} as factoryId is not yet available.`);
|
|
35514
|
-
continue;
|
|
35515
|
-
}
|
|
35516
|
-
const currentFactoryId = lineState.factoryId;
|
|
35517
|
-
try {
|
|
35518
|
-
const { data: lineThresholdsRows, error: thresholdError } = await supabase.from("line_thresholds").select("product_code").eq("line_id", lineId).eq("date", currentDate).eq("shift_id", selectedShift).eq("factory_id", currentFactoryId);
|
|
35519
|
-
if (thresholdError) {
|
|
35520
|
-
console.error(`Error fetching line threshold for line ${lineId}, factory ${currentFactoryId}:`, thresholdError);
|
|
35521
|
-
continue;
|
|
35522
|
-
}
|
|
35523
|
-
let determinedProductId = updatedLineWorkspaces[lineId]?.productId || "";
|
|
35524
|
-
if (lineThresholdsRows && lineThresholdsRows.length > 0) {
|
|
35525
|
-
if (lineThresholdsRows.length > 1) {
|
|
35526
|
-
console.warn(
|
|
35527
|
-
`Multiple line_thresholds records found for line ${lineId}, factory ${currentFactoryId}, date ${currentDate}, shift ${selectedShift}. Using product_code from the first record. Rows:`,
|
|
35528
|
-
lineThresholdsRows
|
|
35529
|
-
);
|
|
35530
|
-
}
|
|
35531
|
-
determinedProductId = lineThresholdsRows[0].product_code;
|
|
35532
|
-
} else {
|
|
35533
|
-
console.log(
|
|
35534
|
-
`No line_thresholds record found for line ${lineId}, factory ${currentFactoryId}, date ${currentDate}, shift ${selectedShift}. Using existing/default product ID.`
|
|
35535
|
-
);
|
|
35536
|
-
}
|
|
35537
|
-
const { data: operatingHours, error: hoursError } = await supabase.from("line_operating_hours").select("start_time, end_time, breaks").eq("line_id", lineId).eq("shift_id", selectedShift).maybeSingle();
|
|
35538
|
-
if (hoursError) {
|
|
35539
|
-
console.error(`Error fetching operating hours for line ${lineId}:`, hoursError);
|
|
35540
|
-
continue;
|
|
35541
|
-
}
|
|
35542
|
-
const startTime = operatingHours?.start_time || updatedLineWorkspaces[lineId]?.shiftStartTime || "08:00";
|
|
35543
|
-
const endTime = operatingHours?.end_time || updatedLineWorkspaces[lineId]?.shiftEndTime || "19:00";
|
|
35544
|
-
let breaks = [];
|
|
35545
|
-
if (operatingHours?.breaks) {
|
|
35546
|
-
if (Array.isArray(operatingHours.breaks)) {
|
|
35547
|
-
breaks = operatingHours.breaks.map((breakItem) => ({
|
|
35548
|
-
startTime: breakItem.start || breakItem.startTime || "00:00",
|
|
35549
|
-
endTime: breakItem.end || breakItem.endTime || "00:00",
|
|
35550
|
-
duration: breakItem.duration || calculateShiftHours2(breakItem.start || breakItem.startTime || "00:00", breakItem.end || breakItem.endTime || "00:00", []) * 60
|
|
35551
|
-
}));
|
|
35552
|
-
} else if (typeof operatingHours.breaks === "object" && operatingHours.breaks.breaks) {
|
|
35553
|
-
breaks = operatingHours.breaks.breaks.map((breakItem) => ({
|
|
35554
|
-
startTime: breakItem.start || breakItem.startTime || "00:00",
|
|
35555
|
-
endTime: breakItem.end || breakItem.endTime || "00:00",
|
|
35556
|
-
duration: breakItem.duration || calculateShiftHours2(breakItem.start || breakItem.startTime || "00:00", breakItem.end || breakItem.endTime || "00:00", []) * 60
|
|
35557
|
-
}));
|
|
35558
|
-
}
|
|
35559
|
-
}
|
|
35560
|
-
const shiftHours = calculateShiftHours2(startTime, endTime, breaks);
|
|
35561
|
-
const currentLineStateFromLoop = updatedLineWorkspaces[lineId];
|
|
35562
|
-
if (determinedProductId !== currentLineStateFromLoop?.productId || startTime !== currentLineStateFromLoop?.shiftStartTime || endTime !== currentLineStateFromLoop?.shiftEndTime || shiftHours !== currentLineStateFromLoop?.shiftHours || JSON.stringify(breaks) !== JSON.stringify(currentLineStateFromLoop?.breaks)) {
|
|
35563
|
-
updatedLineWorkspaces[lineId] = {
|
|
35564
|
-
...currentLineStateFromLoop || {},
|
|
35565
|
-
factoryId: currentFactoryId,
|
|
35566
|
-
// Ensure factoryId is preserved
|
|
35567
|
-
productId: determinedProductId,
|
|
35568
|
-
shiftStartTime: startTime,
|
|
35569
|
-
shiftEndTime: endTime,
|
|
35570
|
-
breaks,
|
|
35571
|
-
shiftHours: Number(shiftHours),
|
|
35572
|
-
workspaces: currentLineStateFromLoop?.workspaces || []
|
|
35573
|
-
};
|
|
35574
|
-
hasUpdates = true;
|
|
35575
|
-
}
|
|
35576
|
-
} catch (lineError) {
|
|
35577
|
-
console.error(`Error processing line ${lineId}:`, lineError);
|
|
35578
|
-
}
|
|
35579
|
-
}
|
|
35580
|
-
if (hasUpdates) {
|
|
35581
|
-
setLineWorkspaces(updatedLineWorkspaces);
|
|
35582
|
-
}
|
|
35583
|
-
} catch (error) {
|
|
35584
|
-
console.error("Error in fetchLineThresholds outer try-catch:", error);
|
|
35585
|
-
}
|
|
35586
|
-
}, [selectedShift, supabase, lineIds, lineWorkspaces, allShiftsData]);
|
|
35848
|
+
}, [lineIds, companyId, loadOperatingHours]);
|
|
35587
35849
|
const fetchAllShiftsData = useCallback(async (currentWorkspaces) => {
|
|
35588
35850
|
if (!supabase) return;
|
|
35589
35851
|
const currentDate = getOperationalDate();
|
|
@@ -35593,32 +35855,25 @@ var TargetsView = ({
|
|
|
35593
35855
|
1: JSON.parse(JSON.stringify(currentWorkspaces))
|
|
35594
35856
|
// Deep clone for night shift
|
|
35595
35857
|
};
|
|
35858
|
+
const newDbValues = { 0: {}, 1: {} };
|
|
35596
35859
|
for (const shiftId of [0, 1]) {
|
|
35597
35860
|
for (const lineId of lineIds) {
|
|
35598
35861
|
try {
|
|
35599
|
-
const
|
|
35600
|
-
if (
|
|
35601
|
-
console.
|
|
35862
|
+
const operatingHoursData = await loadOperatingHours(lineId, shiftId);
|
|
35863
|
+
if (!operatingHoursData) {
|
|
35864
|
+
console.warn(`No operating hours for line ${lineId}, shift ${shiftId} - using defaults`);
|
|
35602
35865
|
continue;
|
|
35603
35866
|
}
|
|
35604
|
-
|
|
35605
|
-
if (operatingHours?.breaks) {
|
|
35606
|
-
if (Array.isArray(operatingHours.breaks)) {
|
|
35607
|
-
breaks = operatingHours.breaks.map((breakItem) => ({
|
|
35608
|
-
startTime: breakItem.start || breakItem.startTime || "00:00",
|
|
35609
|
-
endTime: breakItem.end || breakItem.endTime || "00:00",
|
|
35610
|
-
duration: breakItem.duration || calculateShiftHours2(breakItem.start || breakItem.startTime || "00:00", breakItem.end || breakItem.endTime || "00:00", []) * 60
|
|
35611
|
-
}));
|
|
35612
|
-
}
|
|
35613
|
-
}
|
|
35614
|
-
const startTime = operatingHours?.start_time || "08:00";
|
|
35615
|
-
const endTime = operatingHours?.end_time || "19:00";
|
|
35867
|
+
const { startTime, endTime, breaks } = operatingHoursData;
|
|
35616
35868
|
const shiftHours = calculateShiftHours2(startTime, endTime, breaks);
|
|
35617
35869
|
const actionThresholds = await workspaceService.getActionThresholds(
|
|
35618
35870
|
lineId,
|
|
35619
35871
|
currentDate,
|
|
35620
35872
|
shiftId
|
|
35621
35873
|
);
|
|
35874
|
+
if (!newDbValues[shiftId][lineId]) {
|
|
35875
|
+
newDbValues[shiftId][lineId] = {};
|
|
35876
|
+
}
|
|
35622
35877
|
const existingLine = newAllShiftsData[shiftId][lineId];
|
|
35623
35878
|
if (existingLine) {
|
|
35624
35879
|
newAllShiftsData[shiftId][lineId] = {
|
|
@@ -35630,6 +35885,11 @@ var TargetsView = ({
|
|
|
35630
35885
|
workspaces: existingLine.workspaces.map((ws) => {
|
|
35631
35886
|
const threshold = actionThresholds.find((t) => t.workspace_id === ws.id);
|
|
35632
35887
|
if (threshold) {
|
|
35888
|
+
newDbValues[shiftId][lineId][ws.id] = {
|
|
35889
|
+
targetPPH: threshold.pph_threshold,
|
|
35890
|
+
targetCycleTime: threshold.ideal_cycle_time,
|
|
35891
|
+
targetDayOutput: threshold.total_day_output
|
|
35892
|
+
};
|
|
35633
35893
|
return {
|
|
35634
35894
|
...ws,
|
|
35635
35895
|
targetPPH: threshold.pph_threshold,
|
|
@@ -35647,114 +35907,17 @@ var TargetsView = ({
|
|
|
35647
35907
|
}
|
|
35648
35908
|
}
|
|
35649
35909
|
setAllShiftsData(newAllShiftsData);
|
|
35650
|
-
|
|
35651
|
-
|
|
35652
|
-
try {
|
|
35653
|
-
if (!supabase) return null;
|
|
35654
|
-
const { data, error } = await supabase.from("line_operating_hours").select("start_time, end_time, breaks").eq("line_id", lineId).eq("shift_id", shiftId).maybeSingle();
|
|
35655
|
-
if (error) {
|
|
35656
|
-
if (error.code === "PGRST116") {
|
|
35657
|
-
console.log(`No operating hours found for line ${lineId}, shift ${shiftId}`);
|
|
35658
|
-
return {
|
|
35659
|
-
startTime: "08:00",
|
|
35660
|
-
// Default values
|
|
35661
|
-
endTime: "19:00",
|
|
35662
|
-
breaks: []
|
|
35663
|
-
};
|
|
35664
|
-
} else {
|
|
35665
|
-
console.error("Error fetching operating hours:", error);
|
|
35666
|
-
return null;
|
|
35667
|
-
}
|
|
35668
|
-
}
|
|
35669
|
-
let breaks = [];
|
|
35670
|
-
if (data?.breaks) {
|
|
35671
|
-
if (Array.isArray(data.breaks)) {
|
|
35672
|
-
breaks = data.breaks.map((breakItem) => {
|
|
35673
|
-
const startTime = breakItem.start || breakItem.startTime || "00:00";
|
|
35674
|
-
const endTime = breakItem.end || breakItem.endTime || "00:00";
|
|
35675
|
-
const calculateDuration = (start, end) => {
|
|
35676
|
-
const [startHour, startMinute] = start.split(":").map(Number);
|
|
35677
|
-
const [endHour, endMinute] = end.split(":").map(Number);
|
|
35678
|
-
let startMinutes = startHour * 60 + startMinute;
|
|
35679
|
-
let endMinutes = endHour * 60 + endMinute;
|
|
35680
|
-
if (endMinutes < startMinutes) {
|
|
35681
|
-
endMinutes += 24 * 60;
|
|
35682
|
-
}
|
|
35683
|
-
return endMinutes - startMinutes;
|
|
35684
|
-
};
|
|
35685
|
-
return {
|
|
35686
|
-
startTime,
|
|
35687
|
-
endTime,
|
|
35688
|
-
duration: breakItem.duration || calculateDuration(startTime, endTime)
|
|
35689
|
-
};
|
|
35690
|
-
});
|
|
35691
|
-
} else if (typeof data.breaks === "object" && data.breaks.breaks) {
|
|
35692
|
-
breaks = data.breaks.breaks.map((breakItem) => {
|
|
35693
|
-
const startTime = breakItem.start || breakItem.startTime || "00:00";
|
|
35694
|
-
const endTime = breakItem.end || breakItem.endTime || "00:00";
|
|
35695
|
-
const calculateDuration = (start, end) => {
|
|
35696
|
-
const [startHour, startMinute] = start.split(":").map(Number);
|
|
35697
|
-
const [endHour, endMinute] = end.split(":").map(Number);
|
|
35698
|
-
let startMinutes = startHour * 60 + startMinute;
|
|
35699
|
-
let endMinutes = endHour * 60 + endMinute;
|
|
35700
|
-
if (endMinutes < startMinutes) {
|
|
35701
|
-
endMinutes += 24 * 60;
|
|
35702
|
-
}
|
|
35703
|
-
return endMinutes - startMinutes;
|
|
35704
|
-
};
|
|
35705
|
-
return {
|
|
35706
|
-
startTime,
|
|
35707
|
-
endTime,
|
|
35708
|
-
duration: breakItem.duration || calculateDuration(startTime, endTime)
|
|
35709
|
-
};
|
|
35710
|
-
});
|
|
35711
|
-
} else if (typeof data.breaks === "string") {
|
|
35712
|
-
try {
|
|
35713
|
-
const parsedBreaks = JSON.parse(data.breaks);
|
|
35714
|
-
if (Array.isArray(parsedBreaks)) {
|
|
35715
|
-
breaks = parsedBreaks.map((breakItem) => ({
|
|
35716
|
-
startTime: breakItem.start || breakItem.startTime || "00:00",
|
|
35717
|
-
endTime: breakItem.end || breakItem.endTime || "00:00",
|
|
35718
|
-
duration: breakItem.duration || 0
|
|
35719
|
-
}));
|
|
35720
|
-
} else if (parsedBreaks.breaks && Array.isArray(parsedBreaks.breaks)) {
|
|
35721
|
-
breaks = parsedBreaks.breaks.map((breakItem) => ({
|
|
35722
|
-
startTime: breakItem.start || breakItem.startTime || "00:00",
|
|
35723
|
-
endTime: breakItem.end || breakItem.endTime || "00:00",
|
|
35724
|
-
duration: breakItem.duration || 0
|
|
35725
|
-
}));
|
|
35726
|
-
}
|
|
35727
|
-
} catch (e) {
|
|
35728
|
-
console.error("Error parsing breaks data:", e);
|
|
35729
|
-
}
|
|
35730
|
-
}
|
|
35731
|
-
}
|
|
35732
|
-
return {
|
|
35733
|
-
startTime: data?.start_time || "08:00",
|
|
35734
|
-
endTime: data?.end_time || "19:00",
|
|
35735
|
-
breaks
|
|
35736
|
-
};
|
|
35737
|
-
} catch (e) {
|
|
35738
|
-
console.error("Exception when loading operating hours:", e);
|
|
35739
|
-
return {
|
|
35740
|
-
startTime: "08:00",
|
|
35741
|
-
endTime: "19:00",
|
|
35742
|
-
breaks: []
|
|
35743
|
-
};
|
|
35744
|
-
}
|
|
35745
|
-
}, [supabase]);
|
|
35910
|
+
setDbValues(newDbValues);
|
|
35911
|
+
}, [supabase, lineIds, loadOperatingHours]);
|
|
35746
35912
|
const toggleLineDropdown = useCallback((lineId) => {
|
|
35747
|
-
|
|
35748
|
-
const newIsOpen = !prev[lineId]
|
|
35913
|
+
setDropdownStates((prev) => {
|
|
35914
|
+
const newIsOpen = !prev[lineId];
|
|
35749
35915
|
if (typeof window !== "undefined") {
|
|
35750
35916
|
localStorage.setItem(`line_${lineId}_open`, JSON.stringify(newIsOpen));
|
|
35751
35917
|
}
|
|
35752
35918
|
return {
|
|
35753
35919
|
...prev,
|
|
35754
|
-
[lineId]:
|
|
35755
|
-
...prev[lineId],
|
|
35756
|
-
isOpen: newIsOpen
|
|
35757
|
-
}
|
|
35920
|
+
[lineId]: newIsOpen
|
|
35758
35921
|
};
|
|
35759
35922
|
});
|
|
35760
35923
|
}, []);
|
|
@@ -35803,6 +35966,8 @@ var TargetsView = ({
|
|
|
35803
35966
|
}
|
|
35804
35967
|
};
|
|
35805
35968
|
const updateWorkspaceTarget = (lineId, workspaceId, field, value) => {
|
|
35969
|
+
const fieldKey = `${lineId}-${workspaceId}-${field}`;
|
|
35970
|
+
setUserEditedFields((prev) => new Set(prev).add(fieldKey));
|
|
35806
35971
|
setLineWorkspaces((prev) => {
|
|
35807
35972
|
const shiftHours = prev[lineId].shiftHours;
|
|
35808
35973
|
return {
|
|
@@ -35827,11 +35992,7 @@ var TargetsView = ({
|
|
|
35827
35992
|
} else if (field === "targetDayOutput") {
|
|
35828
35993
|
updates.targetDayOutput = value;
|
|
35829
35994
|
if (value !== "") {
|
|
35830
|
-
const
|
|
35831
|
-
const totalBreakMinutes = breaks.reduce((total, b) => total + b.duration, 0);
|
|
35832
|
-
const totalBreakHours = totalBreakMinutes / 60;
|
|
35833
|
-
const realWorkHours = shiftHours - totalBreakHours;
|
|
35834
|
-
const calculatedPPH = Math.round(value / realWorkHours);
|
|
35995
|
+
const calculatedPPH = Math.round(value / shiftHours);
|
|
35835
35996
|
updates.targetPPH = calculatedPPH;
|
|
35836
35997
|
} else {
|
|
35837
35998
|
updates.targetPPH = "";
|
|
@@ -35846,62 +36007,35 @@ var TargetsView = ({
|
|
|
35846
36007
|
};
|
|
35847
36008
|
const handleShiftChange = (shiftId) => {
|
|
35848
36009
|
setSelectedShift(shiftId);
|
|
35849
|
-
|
|
35850
|
-
|
|
35851
|
-
|
|
35852
|
-
|
|
35853
|
-
|
|
35854
|
-
|
|
35855
|
-
|
|
35856
|
-
|
|
35857
|
-
|
|
35858
|
-
|
|
35859
|
-
|
|
35860
|
-
|
|
35861
|
-
|
|
35862
|
-
|
|
35863
|
-
|
|
35864
|
-
|
|
35865
|
-
|
|
35866
|
-
shiftHours: Number(shiftHours),
|
|
35867
|
-
workspaces: updatedLineWorkspaces[lineId].workspaces.map((ws) => {
|
|
35868
|
-
let updatedPPH = ws.targetPPH;
|
|
35869
|
-
if (ws.targetCycleTime !== "") {
|
|
35870
|
-
const idealPPH = calculatePPH(
|
|
35871
|
-
ws.targetCycleTime,
|
|
35872
|
-
operatingHours.breaks,
|
|
35873
|
-
Number(shiftHours)
|
|
35874
|
-
);
|
|
35875
|
-
const shouldUpdatePPH = typeof ws.targetPPH === "string" ? ws.targetPPH === "" : ws.targetPPH === 0 || !ws.targetPPH;
|
|
35876
|
-
if (shouldUpdatePPH) {
|
|
35877
|
-
updatedPPH = idealPPH;
|
|
36010
|
+
setUserEditedFields(/* @__PURE__ */ new Set());
|
|
36011
|
+
if (dbValues[shiftId] && Object.keys(dbValues[shiftId]).length > 0) {
|
|
36012
|
+
setAllShiftsData((prev) => {
|
|
36013
|
+
const updatedShiftData = { ...prev[shiftId] };
|
|
36014
|
+
for (const lineId of Object.keys(updatedShiftData)) {
|
|
36015
|
+
if (dbValues[shiftId][lineId]) {
|
|
36016
|
+
updatedShiftData[lineId] = {
|
|
36017
|
+
...updatedShiftData[lineId],
|
|
36018
|
+
workspaces: updatedShiftData[lineId].workspaces.map((ws) => {
|
|
36019
|
+
const dbValue = dbValues[shiftId][lineId][ws.id];
|
|
36020
|
+
if (dbValue) {
|
|
36021
|
+
return {
|
|
36022
|
+
...ws,
|
|
36023
|
+
targetPPH: dbValue.targetPPH,
|
|
36024
|
+
targetCycleTime: dbValue.targetCycleTime,
|
|
36025
|
+
targetDayOutput: dbValue.targetDayOutput
|
|
36026
|
+
};
|
|
35878
36027
|
}
|
|
35879
|
-
|
|
35880
|
-
|
|
35881
|
-
|
|
35882
|
-
|
|
35883
|
-
operatingHours.breaks
|
|
35884
|
-
);
|
|
35885
|
-
return {
|
|
35886
|
-
...ws,
|
|
35887
|
-
targetPPH: updatedPPH,
|
|
35888
|
-
targetDayOutput: updatedDayOutput
|
|
35889
|
-
};
|
|
35890
|
-
})
|
|
35891
|
-
};
|
|
35892
|
-
hasUpdates = true;
|
|
35893
|
-
} catch (e) {
|
|
35894
|
-
console.error(`Exception when loading shift hours for line ${lineId}:`, e);
|
|
36028
|
+
return ws;
|
|
36029
|
+
})
|
|
36030
|
+
};
|
|
36031
|
+
}
|
|
35895
36032
|
}
|
|
35896
|
-
|
|
35897
|
-
if (hasUpdates) {
|
|
35898
|
-
setAllShiftsData((prev) => ({
|
|
36033
|
+
return {
|
|
35899
36034
|
...prev,
|
|
35900
|
-
[shiftId]:
|
|
35901
|
-
}
|
|
35902
|
-
}
|
|
35903
|
-
}
|
|
35904
|
-
loadShiftHours();
|
|
36035
|
+
[shiftId]: updatedShiftData
|
|
36036
|
+
};
|
|
36037
|
+
});
|
|
36038
|
+
}
|
|
35905
36039
|
};
|
|
35906
36040
|
const handleActionTypeChange = useCallback((lineId, workspaceId, newActionType) => {
|
|
35907
36041
|
if (!actionIds) return;
|
|
@@ -35991,6 +36125,31 @@ var TargetsView = ({
|
|
|
35991
36125
|
throw lineUpsertError;
|
|
35992
36126
|
}
|
|
35993
36127
|
console.log(`[handleSaveLine] Successfully upserted line_thresholds for ${lineId}`);
|
|
36128
|
+
setDbValues((prev) => ({
|
|
36129
|
+
...prev,
|
|
36130
|
+
[selectedShift]: {
|
|
36131
|
+
...prev[selectedShift],
|
|
36132
|
+
[lineId]: lineDataToSave.workspaces.reduce((acc, ws) => ({
|
|
36133
|
+
...acc,
|
|
36134
|
+
[ws.id]: {
|
|
36135
|
+
targetPPH: ws.targetPPH,
|
|
36136
|
+
targetCycleTime: ws.targetCycleTime,
|
|
36137
|
+
targetDayOutput: ws.targetDayOutput
|
|
36138
|
+
}
|
|
36139
|
+
}), {})
|
|
36140
|
+
}
|
|
36141
|
+
}));
|
|
36142
|
+
console.log(`[handleSaveLine] Updated dbValues for line ${lineId}, shift ${selectedShift}`);
|
|
36143
|
+
setUserEditedFields((prev) => {
|
|
36144
|
+
const newSet = new Set(prev);
|
|
36145
|
+
lineDataToSave.workspaces.forEach((ws) => {
|
|
36146
|
+
newSet.delete(`${lineId}-${ws.id}-targetPPH`);
|
|
36147
|
+
newSet.delete(`${lineId}-${ws.id}-targetCycleTime`);
|
|
36148
|
+
newSet.delete(`${lineId}-${ws.id}-targetDayOutput`);
|
|
36149
|
+
});
|
|
36150
|
+
return newSet;
|
|
36151
|
+
});
|
|
36152
|
+
console.log(`[handleSaveLine] Cleared user edited fields for line ${lineId}`);
|
|
35994
36153
|
setSaveSuccess((prev) => ({ ...prev, [lineId]: true }));
|
|
35995
36154
|
toast.success(`${lineNames[lineId] || lineId} targets saved successfully`);
|
|
35996
36155
|
if (onSaveChanges) onSaveChanges(lineId);
|
|
@@ -36004,7 +36163,7 @@ var TargetsView = ({
|
|
|
36004
36163
|
setSavingLines((prev) => ({ ...prev, [lineId]: false }));
|
|
36005
36164
|
console.log(`[handleSaveLine] Set savingLines to false for ${lineId} in finally block`);
|
|
36006
36165
|
}
|
|
36007
|
-
}, [supabase, lineWorkspaces, selectedShift, lineNames, onSaveChanges]);
|
|
36166
|
+
}, [supabase, lineWorkspaces, selectedShift, lineNames, onSaveChanges, skuEnabled, dashboardConfig]);
|
|
36008
36167
|
const handleBulkConfigure = async (updates) => {
|
|
36009
36168
|
if (!actionIds) return;
|
|
36010
36169
|
if (updates.productId !== void 0) {
|
|
@@ -36052,6 +36211,7 @@ var TargetsView = ({
|
|
|
36052
36211
|
isLoading: isLoading || skusLoading,
|
|
36053
36212
|
lineWorkspaces,
|
|
36054
36213
|
lineNames,
|
|
36214
|
+
dropdownStates,
|
|
36055
36215
|
savingLines,
|
|
36056
36216
|
saveSuccess,
|
|
36057
36217
|
selectedShift,
|
|
@@ -36076,7 +36236,7 @@ var TargetsView = ({
|
|
|
36076
36236
|
};
|
|
36077
36237
|
var TargetsViewWithDisplayNames = withAllWorkspaceDisplayNames(TargetsView);
|
|
36078
36238
|
var TargetsView_default = TargetsViewWithDisplayNames;
|
|
36079
|
-
var AuthenticatedTargetsView = withAuth(TargetsViewWithDisplayNames);
|
|
36239
|
+
var AuthenticatedTargetsView = withAuth(React19__default.memo(TargetsViewWithDisplayNames));
|
|
36080
36240
|
|
|
36081
36241
|
// src/views/workspace-detail-view.utils.ts
|
|
36082
36242
|
var formatISTDate2 = (date = /* @__PURE__ */ new Date(), options) => {
|
|
@@ -37547,4 +37707,4 @@ var streamProxyConfig = {
|
|
|
37547
37707
|
}
|
|
37548
37708
|
};
|
|
37549
37709
|
|
|
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 };
|
|
37710
|
+
export { ACTION_NAMES, AIAgentView_default as AIAgentView, AudioService, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedShiftsView, 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 };
|