@optifye/dashboard-core 6.3.5 → 6.4.0
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 +629 -508
- package/dist/index.mjs +637 -517
- 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");
|
|
@@ -3926,20 +3931,36 @@ var S3ClipsService = class {
|
|
|
3926
3931
|
return null;
|
|
3927
3932
|
}
|
|
3928
3933
|
}
|
|
3934
|
+
/**
|
|
3935
|
+
* Control prefetch mode to prevent metadata fetching during background operations
|
|
3936
|
+
*/
|
|
3937
|
+
setPrefetchMode(enabled) {
|
|
3938
|
+
this.isPrefetching = enabled;
|
|
3939
|
+
console.log(`[S3ClipsService] Prefetch mode ${enabled ? "enabled" : "disabled"} - metadata fetching ${enabled ? "blocked" : "allowed"}`);
|
|
3940
|
+
}
|
|
3929
3941
|
/**
|
|
3930
3942
|
* Fetches full metadata including timestamps with deduplication
|
|
3931
3943
|
*/
|
|
3932
3944
|
async getFullMetadata(playlistUri) {
|
|
3933
|
-
if (this.isIndexBuilding) {
|
|
3934
|
-
console.warn(`[S3ClipsService] Skipping metadata fetch
|
|
3945
|
+
if (this.isIndexBuilding || this.isPrefetching) {
|
|
3946
|
+
console.warn(`[S3ClipsService] Skipping metadata fetch - building: ${this.isIndexBuilding}, prefetching: ${this.isPrefetching}`);
|
|
3935
3947
|
return null;
|
|
3936
3948
|
}
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3949
|
+
if (this.currentMetadataFetches >= this.MAX_CONCURRENT_METADATA) {
|
|
3950
|
+
console.warn(`[S3ClipsService] Skipping metadata - max concurrent fetches (${this.MAX_CONCURRENT_METADATA}) reached`);
|
|
3951
|
+
return null;
|
|
3952
|
+
}
|
|
3953
|
+
this.currentMetadataFetches++;
|
|
3954
|
+
try {
|
|
3955
|
+
const deduplicationKey = `full-metadata:${playlistUri}`;
|
|
3956
|
+
return await this.requestCache.deduplicate(
|
|
3957
|
+
deduplicationKey,
|
|
3958
|
+
() => this.executeGetFullMetadata(playlistUri),
|
|
3959
|
+
"FullMetadata"
|
|
3960
|
+
);
|
|
3961
|
+
} finally {
|
|
3962
|
+
this.currentMetadataFetches--;
|
|
3963
|
+
}
|
|
3943
3964
|
}
|
|
3944
3965
|
/**
|
|
3945
3966
|
* Internal implementation of full metadata fetching
|
|
@@ -4441,7 +4462,8 @@ var S3ClipsService = class {
|
|
|
4441
4462
|
date,
|
|
4442
4463
|
shiftId.toString(),
|
|
4443
4464
|
includeCycleTime || false,
|
|
4444
|
-
includeMetadata ||
|
|
4465
|
+
includeMetadata || false
|
|
4466
|
+
// Never fetch metadata for timestamp filtering to prevent flooding
|
|
4445
4467
|
);
|
|
4446
4468
|
});
|
|
4447
4469
|
const videoResults = await Promise.all(videoPromises);
|
|
@@ -4512,6 +4534,7 @@ var VideoPrefetchManager = class extends EventEmitter {
|
|
|
4512
4534
|
}
|
|
4513
4535
|
/**
|
|
4514
4536
|
* Get or create S3 service instance for dashboard config
|
|
4537
|
+
* Public method to allow sharing the same S3Service instance across components
|
|
4515
4538
|
*/
|
|
4516
4539
|
getS3Service(dashboardConfig) {
|
|
4517
4540
|
const configKey = JSON.stringify(dashboardConfig.s3Config);
|
|
@@ -4581,75 +4604,80 @@ var VideoPrefetchManager = class extends EventEmitter {
|
|
|
4581
4604
|
* Perform the actual prefetch work
|
|
4582
4605
|
*/
|
|
4583
4606
|
async performPrefetchWork(key, params, s3Service, buildIndex) {
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
|
|
4587
|
-
|
|
4588
|
-
|
|
4589
|
-
|
|
4590
|
-
|
|
4591
|
-
|
|
4592
|
-
|
|
4607
|
+
s3Service.setPrefetchMode(true);
|
|
4608
|
+
try {
|
|
4609
|
+
const cacheKey = `clip-counts:${params.workspaceId}:${params.date}:${params.shift}`;
|
|
4610
|
+
const cachedResult = await smartVideoCache.getClipCounts(cacheKey);
|
|
4611
|
+
if (cachedResult) {
|
|
4612
|
+
console.log(`[VideoPrefetchManager] Found cached data for ${key}`);
|
|
4613
|
+
this.updateRequestStatus(key, "fully_indexed" /* FULLY_INDEXED */, cachedResult);
|
|
4614
|
+
return cachedResult;
|
|
4615
|
+
}
|
|
4616
|
+
if (buildIndex) {
|
|
4617
|
+
const countsOnly = await s3Service.getClipCounts(
|
|
4618
|
+
params.workspaceId,
|
|
4619
|
+
params.date,
|
|
4620
|
+
params.shift
|
|
4621
|
+
);
|
|
4622
|
+
if (typeof countsOnly === "object" && countsOnly !== null) {
|
|
4623
|
+
const renderReadyData = {
|
|
4624
|
+
counts: countsOnly,
|
|
4625
|
+
videoIndex: {
|
|
4626
|
+
byCategory: /* @__PURE__ */ new Map(),
|
|
4627
|
+
allVideos: [],
|
|
4628
|
+
counts: countsOnly,
|
|
4629
|
+
workspaceId: params.workspaceId,
|
|
4630
|
+
date: params.date,
|
|
4631
|
+
shiftId: params.shift,
|
|
4632
|
+
lastUpdated: /* @__PURE__ */ new Date(),
|
|
4633
|
+
_debugId: `vid_RENDER_READY_${Date.now()}_${Math.random().toString(36).substring(7)}`
|
|
4634
|
+
}
|
|
4635
|
+
};
|
|
4636
|
+
this.updateRequestStatus(key, "render_ready" /* RENDER_READY */, renderReadyData);
|
|
4637
|
+
console.log(`[VideoPrefetchManager] Render ready, building full index for ${key}`);
|
|
4638
|
+
}
|
|
4639
|
+
}
|
|
4640
|
+
const fullResult = await s3Service.getClipCountsCacheFirst(
|
|
4593
4641
|
params.workspaceId,
|
|
4594
4642
|
params.date,
|
|
4595
|
-
params.shift
|
|
4643
|
+
params.shift,
|
|
4644
|
+
true
|
|
4596
4645
|
);
|
|
4597
|
-
if (typeof
|
|
4598
|
-
const
|
|
4599
|
-
|
|
4646
|
+
if (fullResult && typeof fullResult === "object" && "videoIndex" in fullResult) {
|
|
4647
|
+
const clipCountsWithIndex = fullResult;
|
|
4648
|
+
if (clipCountsWithIndex.videoIndex.allVideos.length > 0) {
|
|
4649
|
+
console.log(`[VideoPrefetchManager] Video index properly populated with ${clipCountsWithIndex.videoIndex.allVideos.length} videos`);
|
|
4650
|
+
} else {
|
|
4651
|
+
console.warn(`[VideoPrefetchManager] Video index is empty, but counts available:`, clipCountsWithIndex.counts);
|
|
4652
|
+
}
|
|
4653
|
+
await smartVideoCache.setClipCounts(cacheKey, clipCountsWithIndex, 5 * 60);
|
|
4654
|
+
this.updateRequestStatus(key, "fully_indexed" /* FULLY_INDEXED */, clipCountsWithIndex);
|
|
4655
|
+
console.log(`[VideoPrefetchManager] Fully indexed: ${key} (${clipCountsWithIndex.videoIndex.allVideos.length} videos)`);
|
|
4656
|
+
return clipCountsWithIndex;
|
|
4657
|
+
} else if (fullResult && typeof fullResult === "object") {
|
|
4658
|
+
console.log(`[VideoPrefetchManager] Received counts only, building fallback data structure`);
|
|
4659
|
+
const countsResult = fullResult;
|
|
4660
|
+
const fallbackData = {
|
|
4661
|
+
counts: countsResult,
|
|
4600
4662
|
videoIndex: {
|
|
4601
4663
|
byCategory: /* @__PURE__ */ new Map(),
|
|
4602
4664
|
allVideos: [],
|
|
4603
|
-
counts:
|
|
4665
|
+
counts: countsResult,
|
|
4604
4666
|
workspaceId: params.workspaceId,
|
|
4605
4667
|
date: params.date,
|
|
4606
4668
|
shiftId: params.shift,
|
|
4607
4669
|
lastUpdated: /* @__PURE__ */ new Date(),
|
|
4608
|
-
_debugId: `
|
|
4670
|
+
_debugId: `vid_FALLBACK_${Date.now()}_${Math.random().toString(36).substring(7)}`
|
|
4609
4671
|
}
|
|
4610
4672
|
};
|
|
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`);
|
|
4673
|
+
this.updateRequestStatus(key, "render_ready" /* RENDER_READY */, fallbackData);
|
|
4674
|
+
return fallbackData;
|
|
4625
4675
|
} 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");
|
|
4676
|
+
console.error(`[VideoPrefetchManager] Received null/undefined result from S3 service`);
|
|
4677
|
+
throw new Error("Failed to fetch clip counts from S3 service");
|
|
4678
|
+
}
|
|
4679
|
+
} finally {
|
|
4680
|
+
s3Service.setPrefetchMode(false);
|
|
4653
4681
|
}
|
|
4654
4682
|
}
|
|
4655
4683
|
/**
|
|
@@ -4912,9 +4940,13 @@ var AuthProvider = ({ children }) => {
|
|
|
4912
4940
|
const [loading, setLoading] = useState(true);
|
|
4913
4941
|
const [error, setError] = useState(null);
|
|
4914
4942
|
const router = useRouter();
|
|
4915
|
-
|
|
4916
|
-
|
|
4943
|
+
authConfig?.userProfileTable;
|
|
4944
|
+
authConfig?.roleColumn || "role";
|
|
4917
4945
|
const fetchUserDetails = useCallback(async (supabaseUser) => {
|
|
4946
|
+
console.log("[fetchUserDetails] Called for user:", supabaseUser.id, {
|
|
4947
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4948
|
+
stackTrace: new Error().stack?.split("\n").slice(1, 4).join(" -> ")
|
|
4949
|
+
});
|
|
4918
4950
|
if (!supabaseUser) return null;
|
|
4919
4951
|
const basicUser = {
|
|
4920
4952
|
id: supabaseUser.id,
|
|
@@ -4923,42 +4955,34 @@ var AuthProvider = ({ children }) => {
|
|
|
4923
4955
|
if (!supabase) return basicUser;
|
|
4924
4956
|
try {
|
|
4925
4957
|
const timeoutPromise = new Promise(
|
|
4926
|
-
(_, reject) => setTimeout(() =>
|
|
4958
|
+
(_, reject) => setTimeout(() => {
|
|
4959
|
+
console.log("[fetchUserDetails] Timeout triggered after 2 seconds");
|
|
4960
|
+
reject(new Error("Profile fetch timeout"));
|
|
4961
|
+
}, 2e3)
|
|
4927
4962
|
);
|
|
4928
4963
|
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
|
-
})
|
|
4964
|
+
const roleResult = await Promise.race([
|
|
4965
|
+
rolePromise,
|
|
4966
|
+
timeoutPromise
|
|
4967
|
+
// Fixed: removed .then() which was causing the bug
|
|
4941
4968
|
]);
|
|
4942
4969
|
let roleLevel = void 0;
|
|
4943
4970
|
if (roleResult && !roleResult.error && roleResult.data) {
|
|
4944
4971
|
roleLevel = roleResult.data.role_level;
|
|
4945
|
-
} else if (roleResult?.error) {
|
|
4972
|
+
} else if (roleResult?.error && roleResult.error.code !== "PGRST116") {
|
|
4946
4973
|
console.log("Error fetching role_level:", roleResult.error.message);
|
|
4947
4974
|
}
|
|
4948
|
-
let roleValue = void 0;
|
|
4949
|
-
if (profileResult && !profileResult.error && profileResult.data) {
|
|
4950
|
-
roleValue = profileResult.data[roleColumn];
|
|
4951
|
-
}
|
|
4952
4975
|
return {
|
|
4953
4976
|
...basicUser,
|
|
4954
|
-
role: roleValue,
|
|
4955
4977
|
role_level: roleLevel
|
|
4956
4978
|
};
|
|
4957
4979
|
} catch (err) {
|
|
4958
|
-
|
|
4980
|
+
if (err instanceof Error && err.message.includes("timeout")) {
|
|
4981
|
+
console.warn("Auth fetch timeout - using basic user info");
|
|
4982
|
+
}
|
|
4959
4983
|
return basicUser;
|
|
4960
4984
|
}
|
|
4961
|
-
}, [supabase
|
|
4985
|
+
}, [supabase]);
|
|
4962
4986
|
useEffect(() => {
|
|
4963
4987
|
if (!supabase) return;
|
|
4964
4988
|
let mounted = true;
|
|
@@ -4969,6 +4993,7 @@ var AuthProvider = ({ children }) => {
|
|
|
4969
4993
|
}
|
|
4970
4994
|
}, 1e4);
|
|
4971
4995
|
const initializeAuth = async () => {
|
|
4996
|
+
const startTime = performance.now();
|
|
4972
4997
|
try {
|
|
4973
4998
|
const { data: { session: initialSession }, error: sessionError } = await supabase.auth.getSession();
|
|
4974
4999
|
if (!mounted) return;
|
|
@@ -5011,12 +5036,38 @@ var AuthProvider = ({ children }) => {
|
|
|
5011
5036
|
if (mounted) {
|
|
5012
5037
|
setLoading(false);
|
|
5013
5038
|
clearTimeout(safetyTimeout);
|
|
5039
|
+
const duration = performance.now() - startTime;
|
|
5040
|
+
if (duration > 3e3) {
|
|
5041
|
+
console.warn(`[Auth] Initialization took ${duration.toFixed(0)}ms - consider optimization`);
|
|
5042
|
+
} else if (process.env.NODE_ENV === "development") {
|
|
5043
|
+
console.log(`[Auth] Initialized in ${duration.toFixed(0)}ms`);
|
|
5044
|
+
}
|
|
5014
5045
|
}
|
|
5015
5046
|
}
|
|
5016
5047
|
};
|
|
5017
5048
|
initializeAuth();
|
|
5018
|
-
const { data: { subscription } } = supabase.auth.onAuthStateChange(async (
|
|
5049
|
+
const { data: { subscription } } = supabase.auth.onAuthStateChange(async (event, currentSession) => {
|
|
5019
5050
|
if (!mounted) return;
|
|
5051
|
+
console.log("[AuthContext] Auth event fired:", {
|
|
5052
|
+
event,
|
|
5053
|
+
sessionId: currentSession?.user?.id,
|
|
5054
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5055
|
+
currentPath: typeof window !== "undefined" ? window.location.pathname : "unknown"
|
|
5056
|
+
});
|
|
5057
|
+
if (event === "TOKEN_REFRESHED") {
|
|
5058
|
+
if (session?.user?.id === currentSession?.user?.id && session?.user?.email === currentSession?.user?.email) {
|
|
5059
|
+
console.log("[AuthContext] Skipping TOKEN_REFRESHED - session unchanged");
|
|
5060
|
+
return;
|
|
5061
|
+
}
|
|
5062
|
+
}
|
|
5063
|
+
if (event !== "TOKEN_REFRESHED" && currentSession?.user) {
|
|
5064
|
+
console.log("[AuthContext] Non-TOKEN_REFRESHED event will trigger fetchUserDetails:", event);
|
|
5065
|
+
}
|
|
5066
|
+
const sessionChanged = session?.user?.id !== currentSession?.user?.id || session?.user?.email !== currentSession?.user?.email;
|
|
5067
|
+
if (!sessionChanged && user) {
|
|
5068
|
+
console.log("[AuthContext] Session and user unchanged, skipping update");
|
|
5069
|
+
return;
|
|
5070
|
+
}
|
|
5020
5071
|
setSession(currentSession);
|
|
5021
5072
|
setUser(null);
|
|
5022
5073
|
setLoading(false);
|
|
@@ -6937,16 +6988,12 @@ var useTargets = (options) => {
|
|
|
6937
6988
|
};
|
|
6938
6989
|
var DEFAULT_SHIFTS_TABLE_NAME = "shift_configurations";
|
|
6939
6990
|
var useShifts = () => {
|
|
6940
|
-
const { supabaseUrl, supabaseKey } = useDashboardConfig();
|
|
6941
6991
|
const { companyId } = useEntityConfig();
|
|
6942
6992
|
const { tables } = useDatabaseConfig();
|
|
6993
|
+
const supabase = useSupabase();
|
|
6943
6994
|
const [shifts, setShifts] = useState([]);
|
|
6944
6995
|
const [isLoading, setIsLoading] = useState(true);
|
|
6945
6996
|
const [error, setError] = useState(null);
|
|
6946
|
-
const supabase = useMemo(() => {
|
|
6947
|
-
if (!supabaseUrl || !supabaseKey) return null;
|
|
6948
|
-
return createClient(supabaseUrl, supabaseKey);
|
|
6949
|
-
}, [supabaseUrl, supabaseKey]);
|
|
6950
6997
|
const shiftsTable = tables?.shiftConfigurations || DEFAULT_SHIFTS_TABLE_NAME;
|
|
6951
6998
|
const fetchData = useCallback(async () => {
|
|
6952
6999
|
if (!supabase) {
|
|
@@ -7645,6 +7692,7 @@ var runtimeWorkspaceDisplayNames = {};
|
|
|
7645
7692
|
var isInitialized = false;
|
|
7646
7693
|
var isInitializing = false;
|
|
7647
7694
|
var initializedWithLineIds = [];
|
|
7695
|
+
var initializationPromise = null;
|
|
7648
7696
|
function getCurrentLineIds() {
|
|
7649
7697
|
try {
|
|
7650
7698
|
const config = _getDashboardConfigInstance();
|
|
@@ -7665,52 +7713,79 @@ function getCurrentLineIds() {
|
|
|
7665
7713
|
}
|
|
7666
7714
|
async function initializeWorkspaceDisplayNames(explicitLineId) {
|
|
7667
7715
|
console.log("\u{1F504} initializeWorkspaceDisplayNames called", { isInitialized, isInitializing, explicitLineId });
|
|
7668
|
-
if (isInitialized
|
|
7669
|
-
|
|
7670
|
-
|
|
7671
|
-
|
|
7672
|
-
|
|
7673
|
-
|
|
7674
|
-
|
|
7675
|
-
|
|
7676
|
-
|
|
7716
|
+
if (isInitialized) return;
|
|
7717
|
+
if (initializationPromise) {
|
|
7718
|
+
console.log("\u{1F504} Already initializing, waiting for existing initialization...");
|
|
7719
|
+
await initializationPromise;
|
|
7720
|
+
return;
|
|
7721
|
+
}
|
|
7722
|
+
initializationPromise = (async () => {
|
|
7723
|
+
isInitializing = true;
|
|
7724
|
+
try {
|
|
7725
|
+
console.log("\u{1F504} Starting Supabase workspace display names initialization...");
|
|
7726
|
+
let targetLineIds = [];
|
|
7727
|
+
if (explicitLineId) {
|
|
7728
|
+
targetLineIds = [explicitLineId];
|
|
7729
|
+
} else {
|
|
7730
|
+
targetLineIds = getCurrentLineIds();
|
|
7731
|
+
}
|
|
7732
|
+
console.log("\u{1F504} Target line IDs for workspace filtering:", targetLineIds);
|
|
7733
|
+
runtimeWorkspaceDisplayNames = {};
|
|
7734
|
+
if (targetLineIds.length > 0) {
|
|
7735
|
+
for (const lineId of targetLineIds) {
|
|
7736
|
+
console.log(`\u{1F504} Fetching workspaces for line: ${lineId}`);
|
|
7737
|
+
const lineDisplayNamesMap = await workspaceService.getWorkspaceDisplayNames(void 0, lineId);
|
|
7738
|
+
runtimeWorkspaceDisplayNames[lineId] = {};
|
|
7739
|
+
lineDisplayNamesMap.forEach((displayName, workspaceId) => {
|
|
7740
|
+
runtimeWorkspaceDisplayNames[lineId][workspaceId] = displayName;
|
|
7741
|
+
});
|
|
7742
|
+
console.log(`\u2705 Stored ${lineDisplayNamesMap.size} workspaces for line ${lineId}`);
|
|
7743
|
+
}
|
|
7744
|
+
} else {
|
|
7745
|
+
console.warn("\u26A0\uFE0F No line IDs found, fetching all workspaces (less efficient)");
|
|
7746
|
+
const allWorkspacesMap = await workspaceService.getWorkspaceDisplayNames();
|
|
7747
|
+
runtimeWorkspaceDisplayNames["global"] = {};
|
|
7748
|
+
allWorkspacesMap.forEach((displayName, workspaceId) => {
|
|
7749
|
+
runtimeWorkspaceDisplayNames["global"][workspaceId] = displayName;
|
|
7750
|
+
});
|
|
7751
|
+
}
|
|
7752
|
+
isInitialized = true;
|
|
7753
|
+
initializedWithLineIds = targetLineIds;
|
|
7754
|
+
console.log("\u2705 Workspace display names initialized from Supabase:", runtimeWorkspaceDisplayNames);
|
|
7755
|
+
console.log("\u2705 Initialized with line IDs:", initializedWithLineIds);
|
|
7756
|
+
} catch (error) {
|
|
7757
|
+
console.error("\u274C Failed to initialize workspace display names from Supabase:", error);
|
|
7758
|
+
} finally {
|
|
7759
|
+
isInitializing = false;
|
|
7760
|
+
initializationPromise = null;
|
|
7677
7761
|
}
|
|
7678
|
-
|
|
7679
|
-
|
|
7680
|
-
|
|
7681
|
-
|
|
7682
|
-
|
|
7762
|
+
})();
|
|
7763
|
+
await initializationPromise;
|
|
7764
|
+
}
|
|
7765
|
+
var preInitializeWorkspaceDisplayNames = async (lineId) => {
|
|
7766
|
+
console.log("\u{1F504} preInitializeWorkspaceDisplayNames called for lineId:", lineId);
|
|
7767
|
+
if (isInitialized) {
|
|
7768
|
+
console.log("\u{1F504} Already initialized");
|
|
7769
|
+
if (lineId && !runtimeWorkspaceDisplayNames[lineId]) {
|
|
7770
|
+
console.log(`\u{1F504} Line ${lineId} not in cache, fetching...`);
|
|
7771
|
+
try {
|
|
7683
7772
|
const lineDisplayNamesMap = await workspaceService.getWorkspaceDisplayNames(void 0, lineId);
|
|
7684
7773
|
runtimeWorkspaceDisplayNames[lineId] = {};
|
|
7685
7774
|
lineDisplayNamesMap.forEach((displayName, workspaceId) => {
|
|
7686
7775
|
runtimeWorkspaceDisplayNames[lineId][workspaceId] = displayName;
|
|
7687
7776
|
});
|
|
7688
|
-
console.log(`\u2705
|
|
7777
|
+
console.log(`\u2705 Added ${lineDisplayNamesMap.size} workspaces for line ${lineId}`);
|
|
7778
|
+
} catch (error) {
|
|
7779
|
+
console.error(`\u274C Failed to fetch workspaces for line ${lineId}:`, error);
|
|
7689
7780
|
}
|
|
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
7781
|
}
|
|
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;
|
|
7782
|
+
return;
|
|
7706
7783
|
}
|
|
7707
|
-
|
|
7708
|
-
|
|
7709
|
-
|
|
7710
|
-
if (isInitialized || isInitializing) {
|
|
7711
|
-
console.log("\u{1F504} Already initialized or initializing");
|
|
7784
|
+
if (initializationPromise) {
|
|
7785
|
+
console.log("\u{1F504} Already initializing, waiting for completion...");
|
|
7786
|
+
await initializationPromise;
|
|
7712
7787
|
if (lineId && !runtimeWorkspaceDisplayNames[lineId]) {
|
|
7713
|
-
console.log(`\u{1F504} Line ${lineId} not in cache, fetching...`);
|
|
7788
|
+
console.log(`\u{1F504} Line ${lineId} not in cache after init, fetching...`);
|
|
7714
7789
|
try {
|
|
7715
7790
|
const lineDisplayNamesMap = await workspaceService.getWorkspaceDisplayNames(void 0, lineId);
|
|
7716
7791
|
runtimeWorkspaceDisplayNames[lineId] = {};
|
|
@@ -7728,7 +7803,12 @@ var preInitializeWorkspaceDisplayNames = async (lineId) => {
|
|
|
7728
7803
|
};
|
|
7729
7804
|
var forceRefreshWorkspaceDisplayNames = async (lineId) => {
|
|
7730
7805
|
console.log("\u{1F504} forceRefreshWorkspaceDisplayNames called for lineId:", lineId);
|
|
7806
|
+
if (initializationPromise) {
|
|
7807
|
+
console.log("\u{1F504} Waiting for existing initialization to complete before refresh...");
|
|
7808
|
+
await initializationPromise;
|
|
7809
|
+
}
|
|
7731
7810
|
clearWorkspaceDisplayNamesCache();
|
|
7811
|
+
initializationPromise = null;
|
|
7732
7812
|
await initializeWorkspaceDisplayNames(lineId);
|
|
7733
7813
|
};
|
|
7734
7814
|
console.log("\u{1F504} Module loaded, will initialize lazily when first function is called");
|
|
@@ -7876,6 +7956,7 @@ var clearWorkspaceDisplayNamesCache = () => {
|
|
|
7876
7956
|
isInitialized = false;
|
|
7877
7957
|
isInitializing = false;
|
|
7878
7958
|
initializedWithLineIds = [];
|
|
7959
|
+
initializationPromise = null;
|
|
7879
7960
|
};
|
|
7880
7961
|
|
|
7881
7962
|
// src/lib/hooks/useWorkspaceDisplayNames.ts
|
|
@@ -19516,11 +19597,13 @@ var withAuth = (WrappedComponent2, options) => {
|
|
|
19516
19597
|
requireAuth: true,
|
|
19517
19598
|
...options
|
|
19518
19599
|
};
|
|
19519
|
-
|
|
19600
|
+
const WithAuthComponent = React19.memo(function WithAuthComponent2(props) {
|
|
19520
19601
|
const { session, loading } = useAuth();
|
|
19521
19602
|
const router = useRouter();
|
|
19522
19603
|
React19.useEffect(() => {
|
|
19523
|
-
|
|
19604
|
+
if (process.env.NODE_ENV === "development" && process.env.DEBUG_AUTH === "true") {
|
|
19605
|
+
console.log("withAuth state:", { loading, hasSession: !!session, requireAuth: defaultOptions.requireAuth });
|
|
19606
|
+
}
|
|
19524
19607
|
}, [session, loading]);
|
|
19525
19608
|
React19.useEffect(() => {
|
|
19526
19609
|
if (!loading && defaultOptions.requireAuth && !session) {
|
|
@@ -19535,7 +19618,9 @@ var withAuth = (WrappedComponent2, options) => {
|
|
|
19535
19618
|
return null;
|
|
19536
19619
|
}
|
|
19537
19620
|
return /* @__PURE__ */ jsx(WrappedComponent2, { ...props });
|
|
19538
|
-
};
|
|
19621
|
+
});
|
|
19622
|
+
WithAuthComponent.displayName = `withAuth(${WrappedComponent2.displayName || WrappedComponent2.name || "Component"})`;
|
|
19623
|
+
return WithAuthComponent;
|
|
19539
19624
|
};
|
|
19540
19625
|
var LoginPage = ({
|
|
19541
19626
|
onRateLimitCheck,
|
|
@@ -26123,7 +26208,7 @@ var BottlenecksContent = ({
|
|
|
26123
26208
|
const [duration, setDuration] = useState(0);
|
|
26124
26209
|
const [currentIndex, setCurrentIndex] = useState(0);
|
|
26125
26210
|
const [activeFilter, setActiveFilter] = useState(initialFilter);
|
|
26126
|
-
const previousFilterRef = useRef(
|
|
26211
|
+
const previousFilterRef = useRef("");
|
|
26127
26212
|
const [allVideos, setAllVideos] = useState([]);
|
|
26128
26213
|
const [isLoading, setIsLoading] = useState(true);
|
|
26129
26214
|
const [isCategoryLoading, setIsCategoryLoading] = useState(false);
|
|
@@ -26173,7 +26258,7 @@ var BottlenecksContent = ({
|
|
|
26173
26258
|
console.warn("S3 configuration not found in dashboard config");
|
|
26174
26259
|
return null;
|
|
26175
26260
|
}
|
|
26176
|
-
return
|
|
26261
|
+
return videoPrefetchManager.getS3Service(dashboardConfig);
|
|
26177
26262
|
}, [dashboardConfig]);
|
|
26178
26263
|
const {
|
|
26179
26264
|
data: prefetchData,
|
|
@@ -26280,8 +26365,8 @@ var BottlenecksContent = ({
|
|
|
26280
26365
|
index,
|
|
26281
26366
|
true,
|
|
26282
26367
|
// includeCycleTime - OK for preloading
|
|
26283
|
-
|
|
26284
|
-
// includeMetadata -
|
|
26368
|
+
false
|
|
26369
|
+
// includeMetadata - NO metadata during bulk preloading to prevent flooding
|
|
26285
26370
|
);
|
|
26286
26371
|
}
|
|
26287
26372
|
if (!video) {
|
|
@@ -26295,8 +26380,8 @@ var BottlenecksContent = ({
|
|
|
26295
26380
|
index,
|
|
26296
26381
|
true,
|
|
26297
26382
|
// includeCycleTime - OK for preloading
|
|
26298
|
-
|
|
26299
|
-
// includeMetadata -
|
|
26383
|
+
false
|
|
26384
|
+
// includeMetadata - NO metadata during bulk preloading to prevent flooding
|
|
26300
26385
|
);
|
|
26301
26386
|
}
|
|
26302
26387
|
if (video && isMountedRef.current) {
|
|
@@ -26356,8 +26441,16 @@ var BottlenecksContent = ({
|
|
|
26356
26441
|
);
|
|
26357
26442
|
if (firstVideo) {
|
|
26358
26443
|
console.log(`[BottlenecksContent] Successfully loaded first video via direct S3 method`);
|
|
26359
|
-
setAllVideos(
|
|
26444
|
+
setAllVideos((prev) => {
|
|
26445
|
+
const exists = prev.some((v) => v.id === firstVideo.id);
|
|
26446
|
+
if (!exists) {
|
|
26447
|
+
return [...prev, firstVideo];
|
|
26448
|
+
}
|
|
26449
|
+
return prev;
|
|
26450
|
+
});
|
|
26360
26451
|
preloadVideoUrl(firstVideo.src);
|
|
26452
|
+
setIsLoading(false);
|
|
26453
|
+
setHasInitialLoad(true);
|
|
26361
26454
|
loadingCategoryRef.current = null;
|
|
26362
26455
|
setIsCategoryLoading(false);
|
|
26363
26456
|
return;
|
|
@@ -26380,7 +26473,13 @@ var BottlenecksContent = ({
|
|
|
26380
26473
|
);
|
|
26381
26474
|
if (firstVideo && isMountedRef.current) {
|
|
26382
26475
|
console.log(`[BottlenecksContent] Successfully loaded first video via video index`);
|
|
26383
|
-
setAllVideos(
|
|
26476
|
+
setAllVideos((prev) => {
|
|
26477
|
+
const exists = prev.some((v) => v.id === firstVideo.id);
|
|
26478
|
+
if (!exists) {
|
|
26479
|
+
return [...prev, firstVideo];
|
|
26480
|
+
}
|
|
26481
|
+
return prev;
|
|
26482
|
+
});
|
|
26384
26483
|
preloadVideoUrl(firstVideo.src);
|
|
26385
26484
|
setIsCategoryLoading(false);
|
|
26386
26485
|
return;
|
|
@@ -26405,15 +26504,17 @@ var BottlenecksContent = ({
|
|
|
26405
26504
|
}
|
|
26406
26505
|
}, [workspaceId, date, s3ClipsService, clipCounts, videoIndex, shift, updateClipCounts, updateVideoIndex]);
|
|
26407
26506
|
useEffect(() => {
|
|
26408
|
-
if (s3ClipsService) {
|
|
26507
|
+
if (s3ClipsService && !prefetchData) {
|
|
26409
26508
|
fetchClipCounts();
|
|
26410
26509
|
}
|
|
26411
|
-
}, [workspaceId, date, shift, s3ClipsService, fetchClipCounts, updateClipCounts, updateVideoIndex]);
|
|
26510
|
+
}, [workspaceId, date, shift, s3ClipsService, fetchClipCounts, updateClipCounts, updateVideoIndex, prefetchData]);
|
|
26412
26511
|
useEffect(() => {
|
|
26413
26512
|
if (prefetchData) {
|
|
26414
26513
|
console.log(`[BottlenecksContent] Received prefetch update - status: ${prefetchStatus}, videos: ${prefetchData.videoIndex.allVideos.length}, ID: ${prefetchData.videoIndex._debugId || "NO_ID"}`);
|
|
26415
26514
|
updateClipCounts(prefetchData.counts);
|
|
26416
|
-
|
|
26515
|
+
if (prefetchData.videoIndex.allVideos.length > 0) {
|
|
26516
|
+
updateVideoIndex(prefetchData.videoIndex);
|
|
26517
|
+
}
|
|
26417
26518
|
if (!hasInitialLoad && prefetchData.videoIndex.allVideos.length > 0) {
|
|
26418
26519
|
setIsLoading(false);
|
|
26419
26520
|
setHasInitialLoad(true);
|
|
@@ -26421,12 +26522,45 @@ var BottlenecksContent = ({
|
|
|
26421
26522
|
}
|
|
26422
26523
|
}, [prefetchData, prefetchStatus, updateClipCounts, updateVideoIndex, hasInitialLoad]);
|
|
26423
26524
|
useEffect(() => {
|
|
26424
|
-
if (s3ClipsService &&
|
|
26425
|
-
|
|
26525
|
+
if (s3ClipsService && clipCounts[activeFilter] > 0) {
|
|
26526
|
+
const hasVideosForCurrentFilter = allVideos.some((video) => {
|
|
26527
|
+
if (sopCategories && sopCategories.length > 0) {
|
|
26528
|
+
const selectedCategory = sopCategories.find((cat) => cat.id === activeFilter);
|
|
26529
|
+
if (selectedCategory) {
|
|
26530
|
+
return video.type === selectedCategory.id;
|
|
26531
|
+
}
|
|
26532
|
+
}
|
|
26533
|
+
if (activeFilter === "all") return true;
|
|
26534
|
+
if (activeFilter === "low_value") {
|
|
26535
|
+
return video.type === "low_value";
|
|
26536
|
+
}
|
|
26537
|
+
if (activeFilter === "idle_time") {
|
|
26538
|
+
return video.type === "idle_time";
|
|
26539
|
+
}
|
|
26540
|
+
if (activeFilter === "sop_deviations") {
|
|
26541
|
+
return video.type === "missing_quality_check";
|
|
26542
|
+
}
|
|
26543
|
+
if (activeFilter === "best_cycle_time") {
|
|
26544
|
+
return video.type === "best_cycle_time";
|
|
26545
|
+
}
|
|
26546
|
+
if (activeFilter === "worst_cycle_time") {
|
|
26547
|
+
return video.type === "worst_cycle_time";
|
|
26548
|
+
}
|
|
26549
|
+
if (activeFilter === "cycle_completion") {
|
|
26550
|
+
return video.type === "cycle_completion";
|
|
26551
|
+
}
|
|
26552
|
+
if (activeFilter === "long_cycle_time") {
|
|
26553
|
+
return video.type === "long_cycle_time";
|
|
26554
|
+
}
|
|
26555
|
+
return video.type === "bottleneck" && video.severity === activeFilter;
|
|
26556
|
+
});
|
|
26557
|
+
if (!hasVideosForCurrentFilter) {
|
|
26426
26558
|
loadFirstVideoForCategory(activeFilter);
|
|
26559
|
+
} else {
|
|
26560
|
+
setIsCategoryLoading(false);
|
|
26427
26561
|
}
|
|
26428
26562
|
}
|
|
26429
|
-
}, [activeFilter, s3ClipsService, videoIndex, clipCounts, loadFirstVideoForCategory, allVideos
|
|
26563
|
+
}, [activeFilter, s3ClipsService, videoIndex, clipCounts, loadFirstVideoForCategory, allVideos, sopCategories]);
|
|
26430
26564
|
useEffect(() => {
|
|
26431
26565
|
if (previousFilterRef.current !== activeFilter) {
|
|
26432
26566
|
console.log(`Filter changed from ${previousFilterRef.current} to ${activeFilter} - resetting to first video`);
|
|
@@ -26609,14 +26743,39 @@ var BottlenecksContent = ({
|
|
|
26609
26743
|
}
|
|
26610
26744
|
}
|
|
26611
26745
|
}, [filteredVideos.length]);
|
|
26746
|
+
const currentVideo = useMemo(() => {
|
|
26747
|
+
if (!filteredVideos || filteredVideos.length === 0 || currentIndex >= filteredVideos.length) {
|
|
26748
|
+
return null;
|
|
26749
|
+
}
|
|
26750
|
+
return filteredVideos[currentIndex];
|
|
26751
|
+
}, [filteredVideos, currentIndex]);
|
|
26612
26752
|
const handleVideoReady = useCallback((player) => {
|
|
26613
26753
|
console.log("Video.js player ready");
|
|
26614
26754
|
}, []);
|
|
26615
|
-
const handleVideoPlay = useCallback((player) => {
|
|
26755
|
+
const handleVideoPlay = useCallback(async (player) => {
|
|
26616
26756
|
setIsPlaying(true);
|
|
26617
26757
|
const currentIdx = currentIndexRef.current;
|
|
26618
26758
|
ensureVideosLoaded(currentIdx);
|
|
26619
|
-
|
|
26759
|
+
if (currentVideo && !currentVideo.creation_timestamp && s3ClipsService) {
|
|
26760
|
+
try {
|
|
26761
|
+
const originalUri = currentVideo.originalUri || currentVideo.src;
|
|
26762
|
+
if (originalUri && originalUri.includes("s3://")) {
|
|
26763
|
+
const metadata = await s3ClipsService.getFullMetadata(originalUri);
|
|
26764
|
+
if (metadata && isMountedRef.current) {
|
|
26765
|
+
setAllVideos((prev) => prev.map(
|
|
26766
|
+
(v) => v.id === currentVideo.id ? {
|
|
26767
|
+
...v,
|
|
26768
|
+
creation_timestamp: metadata.upload_timestamp || metadata.original_task_metadata?.timestamp || metadata.creation_timestamp,
|
|
26769
|
+
cycle_time_seconds: metadata.original_task_metadata?.cycle_time || v.cycle_time_seconds
|
|
26770
|
+
} : v
|
|
26771
|
+
));
|
|
26772
|
+
}
|
|
26773
|
+
}
|
|
26774
|
+
} catch (error2) {
|
|
26775
|
+
console.warn("[BottlenecksContent] Failed to load metadata for current video:", error2);
|
|
26776
|
+
}
|
|
26777
|
+
}
|
|
26778
|
+
}, [currentVideo, s3ClipsService]);
|
|
26620
26779
|
const handleVideoPause = useCallback((player) => {
|
|
26621
26780
|
setIsPlaying(false);
|
|
26622
26781
|
}, []);
|
|
@@ -26643,13 +26802,6 @@ var BottlenecksContent = ({
|
|
|
26643
26802
|
fetchInProgressRef.current.clear();
|
|
26644
26803
|
setIsCategoryLoading(false);
|
|
26645
26804
|
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
26805
|
};
|
|
26654
26806
|
}, [s3ClipsService]);
|
|
26655
26807
|
useEffect(() => {
|
|
@@ -26690,12 +26842,6 @@ var BottlenecksContent = ({
|
|
|
26690
26842
|
counts.bottlenecks = counts.bottleneck || counts.bottlenecks || 0;
|
|
26691
26843
|
return counts;
|
|
26692
26844
|
}, [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
26845
|
const getClipTypeLabel = (video) => {
|
|
26700
26846
|
if (!video) return "";
|
|
26701
26847
|
switch (video.type) {
|
|
@@ -26930,8 +27076,8 @@ var BottlenecksContent = ({
|
|
|
26930
27076
|
] }),
|
|
26931
27077
|
/* Priority 1: Show loading if initial load hasn't completed yet */
|
|
26932
27078
|
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..." }) }) }) }) : (
|
|
27079
|
+
/* Priority 2: Show loading if category is loading BUT only if no video is available */
|
|
27080
|
+
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
27081
|
/* Priority 3: Show loading if navigating and current video not available */
|
|
26936
27082
|
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
27083
|
/* Priority 4: Show video if we have filtered videos and current video */
|
|
@@ -31288,7 +31434,7 @@ var HelpView = ({
|
|
|
31288
31434
|
onClick: handleBackClick,
|
|
31289
31435
|
className: "flex items-center text-gray-600 hover:text-gray-900",
|
|
31290
31436
|
children: [
|
|
31291
|
-
/* @__PURE__ */ jsx(ArrowLeftIcon, { className: "h-5 w-5" }),
|
|
31437
|
+
/* @__PURE__ */ jsx(ArrowLeftIcon$1, { className: "h-5 w-5" }),
|
|
31292
31438
|
/* @__PURE__ */ jsx("span", { className: "ml-2", children: "Back" })
|
|
31293
31439
|
]
|
|
31294
31440
|
}
|
|
@@ -31729,9 +31875,25 @@ function withWorkspaceDisplayNames(Component3, options = {}) {
|
|
|
31729
31875
|
return function WithWorkspaceDisplayNamesWrapper(props) {
|
|
31730
31876
|
const [isInitialized2, setIsInitialized] = useState(false);
|
|
31731
31877
|
const [error, setError] = useState(null);
|
|
31878
|
+
const [lastInitKey, setLastInitKey] = useState("");
|
|
31879
|
+
const lineIdsKey = useMemo(() => {
|
|
31880
|
+
if (!props.lineIds) return "";
|
|
31881
|
+
if (Array.isArray(props.lineIds)) {
|
|
31882
|
+
return props.lineIds.sort().join(",");
|
|
31883
|
+
}
|
|
31884
|
+
const values = Object.values(props.lineIds).filter(Boolean);
|
|
31885
|
+
return values.sort().join(",");
|
|
31886
|
+
}, [props.lineIds]);
|
|
31887
|
+
const initKey = useMemo(() => {
|
|
31888
|
+
return `${lineIdsKey}-${props.selectedLineId || ""}-${props.factoryViewId || ""}-${initializeFor}`;
|
|
31889
|
+
}, [lineIdsKey, props.selectedLineId, props.factoryViewId]);
|
|
31732
31890
|
useEffect(() => {
|
|
31733
|
-
|
|
31734
|
-
|
|
31891
|
+
if (initKey === lastInitKey && isInitialized2) {
|
|
31892
|
+
return;
|
|
31893
|
+
}
|
|
31894
|
+
if (initKey !== lastInitKey) {
|
|
31895
|
+
setError(null);
|
|
31896
|
+
}
|
|
31735
31897
|
const initializeDisplayNames = async () => {
|
|
31736
31898
|
try {
|
|
31737
31899
|
const { lineIds, selectedLineId, factoryViewId } = props;
|
|
@@ -31757,20 +31919,17 @@ function withWorkspaceDisplayNames(Component3, options = {}) {
|
|
|
31757
31919
|
await preInitializeWorkspaceDisplayNames();
|
|
31758
31920
|
}
|
|
31759
31921
|
setIsInitialized(true);
|
|
31922
|
+
setLastInitKey(initKey);
|
|
31760
31923
|
} catch (err) {
|
|
31761
31924
|
console.error("Failed to initialize workspace display names:", err);
|
|
31762
31925
|
setError(err);
|
|
31763
31926
|
setIsInitialized(true);
|
|
31927
|
+
setLastInitKey(initKey);
|
|
31764
31928
|
}
|
|
31765
31929
|
};
|
|
31766
31930
|
initializeDisplayNames();
|
|
31767
|
-
}, [
|
|
31768
|
-
|
|
31769
|
-
props.selectedLineId,
|
|
31770
|
-
props.factoryViewId,
|
|
31771
|
-
initializeFor
|
|
31772
|
-
]);
|
|
31773
|
-
if (!isInitialized2 && showLoading) {
|
|
31931
|
+
}, [initKey]);
|
|
31932
|
+
if (!isInitialized2 && showLoading && lastInitKey === "") {
|
|
31774
31933
|
return /* @__PURE__ */ jsx(LoadingPage, { message: loadingMessage });
|
|
31775
31934
|
}
|
|
31776
31935
|
if (error && showLoading) {
|
|
@@ -32410,7 +32569,7 @@ var KPIDetailView = ({
|
|
|
32410
32569
|
onClick: handleBackClick,
|
|
32411
32570
|
className: "absolute left-0 flex items-center text-gray-600 hover:text-gray-900 cursor-pointer",
|
|
32412
32571
|
children: [
|
|
32413
|
-
/* @__PURE__ */ jsx(ArrowLeftIcon, { className: "h-5 w-5" }),
|
|
32572
|
+
/* @__PURE__ */ jsx(ArrowLeftIcon$1, { className: "h-5 w-5" }),
|
|
32414
32573
|
/* @__PURE__ */ jsx("span", { className: "ml-2", children: "Back" })
|
|
32415
32574
|
]
|
|
32416
32575
|
}
|
|
@@ -32782,7 +32941,7 @@ var KPIsOverviewView = ({
|
|
|
32782
32941
|
onClick: handleBackClick,
|
|
32783
32942
|
className: "absolute left-0 flex items-center text-gray-600 hover:text-gray-900 cursor-pointer",
|
|
32784
32943
|
children: [
|
|
32785
|
-
/* @__PURE__ */ jsx(ArrowLeftIcon, { className: "h-5 w-5" }),
|
|
32944
|
+
/* @__PURE__ */ jsx(ArrowLeftIcon$1, { className: "h-5 w-5" }),
|
|
32786
32945
|
/* @__PURE__ */ jsx("span", { className: "ml-2", children: "Back" })
|
|
32787
32946
|
]
|
|
32788
32947
|
}
|
|
@@ -32804,7 +32963,7 @@ var KPIsOverviewView = ({
|
|
|
32804
32963
|
onClick: handleBackClick,
|
|
32805
32964
|
className: "absolute left-0 flex items-center text-gray-600 hover:text-gray-900 cursor-pointer",
|
|
32806
32965
|
children: [
|
|
32807
|
-
/* @__PURE__ */ jsx(ArrowLeftIcon, { className: "h-5 w-5" }),
|
|
32966
|
+
/* @__PURE__ */ jsx(ArrowLeftIcon$1, { className: "h-5 w-5" }),
|
|
32808
32967
|
/* @__PURE__ */ jsx("span", { className: "ml-2", children: "Back" })
|
|
32809
32968
|
]
|
|
32810
32969
|
}
|
|
@@ -32829,7 +32988,7 @@ var KPIsOverviewView = ({
|
|
|
32829
32988
|
onClick: handleBackClick,
|
|
32830
32989
|
className: "absolute left-0 flex items-center text-gray-600 hover:text-gray-900 cursor-pointer",
|
|
32831
32990
|
children: [
|
|
32832
|
-
/* @__PURE__ */ jsx(ArrowLeftIcon, { className: "h-5 w-5" }),
|
|
32991
|
+
/* @__PURE__ */ jsx(ArrowLeftIcon$1, { className: "h-5 w-5" }),
|
|
32833
32992
|
/* @__PURE__ */ jsx("span", { className: "ml-2", children: "Back" })
|
|
32834
32993
|
]
|
|
32835
32994
|
}
|
|
@@ -33841,7 +34000,15 @@ var ShiftsView = ({
|
|
|
33841
34000
|
className = ""
|
|
33842
34001
|
}) => {
|
|
33843
34002
|
const supabase = useSupabase();
|
|
33844
|
-
|
|
34003
|
+
useEffect(() => {
|
|
34004
|
+
console.log("[ShiftsView] Component mounted/re-rendered", {
|
|
34005
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
34006
|
+
lineIds: lineIds.length
|
|
34007
|
+
});
|
|
34008
|
+
return () => {
|
|
34009
|
+
console.log("[ShiftsView] Component unmounting");
|
|
34010
|
+
};
|
|
34011
|
+
}, []);
|
|
33845
34012
|
const [lineConfigs, setLineConfigs] = useState(
|
|
33846
34013
|
() => lineIds.map((id3) => ({
|
|
33847
34014
|
id: id3,
|
|
@@ -33939,7 +34106,7 @@ var ShiftsView = ({
|
|
|
33939
34106
|
}
|
|
33940
34107
|
};
|
|
33941
34108
|
fetchShiftConfigs();
|
|
33942
|
-
}, [
|
|
34109
|
+
}, [lineIds, showToast]);
|
|
33943
34110
|
useCallback((lineId) => {
|
|
33944
34111
|
setLineConfigs((prev) => {
|
|
33945
34112
|
const typedPrev = prev;
|
|
@@ -34132,7 +34299,6 @@ var ShiftsView = ({
|
|
|
34132
34299
|
}));
|
|
34133
34300
|
}, []);
|
|
34134
34301
|
const handleSaveShifts = useCallback(async (lineId) => {
|
|
34135
|
-
if (!auth.user?.id && false) ;
|
|
34136
34302
|
setLineConfigs((prev) => prev.map(
|
|
34137
34303
|
(config) => config.id === lineId ? { ...config, isSaving: true, saveSuccess: false } : config
|
|
34138
34304
|
));
|
|
@@ -34179,7 +34345,7 @@ var ShiftsView = ({
|
|
|
34179
34345
|
(config) => config.id === lineId ? { ...config, isSaving: false, saveSuccess: false } : config
|
|
34180
34346
|
));
|
|
34181
34347
|
}
|
|
34182
|
-
}, [
|
|
34348
|
+
}, [lineConfigs, supabase, showToast]);
|
|
34183
34349
|
return /* @__PURE__ */ jsxs("div", { className: `min-h-screen bg-slate-50 ${className}`, children: [
|
|
34184
34350
|
/* @__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
34351
|
/* @__PURE__ */ jsxs(
|
|
@@ -34287,6 +34453,7 @@ var ShiftsView = ({
|
|
|
34287
34453
|
] })
|
|
34288
34454
|
] });
|
|
34289
34455
|
};
|
|
34456
|
+
var AuthenticatedShiftsView = withAuth(React19__default.memo(ShiftsView));
|
|
34290
34457
|
var ShiftsView_default = ShiftsView;
|
|
34291
34458
|
|
|
34292
34459
|
// src/lib/constants/actions.ts
|
|
@@ -35074,6 +35241,7 @@ var TargetsViewUI = ({
|
|
|
35074
35241
|
isLoading,
|
|
35075
35242
|
lineWorkspaces,
|
|
35076
35243
|
lineNames,
|
|
35244
|
+
dropdownStates,
|
|
35077
35245
|
savingLines,
|
|
35078
35246
|
saveSuccess,
|
|
35079
35247
|
selectedShift,
|
|
@@ -35106,7 +35274,7 @@ var TargetsViewUI = ({
|
|
|
35106
35274
|
onClick: onBack,
|
|
35107
35275
|
className: "flex items-center text-gray-600 hover:text-gray-900",
|
|
35108
35276
|
children: [
|
|
35109
|
-
/* @__PURE__ */ jsx(ArrowLeftIcon
|
|
35277
|
+
/* @__PURE__ */ jsx(ArrowLeftIcon, { className: "h-5 w-5" }),
|
|
35110
35278
|
/* @__PURE__ */ jsx("span", { className: "ml-2", children: "Back" })
|
|
35111
35279
|
]
|
|
35112
35280
|
}
|
|
@@ -35159,13 +35327,13 @@ var TargetsViewUI = ({
|
|
|
35159
35327
|
{
|
|
35160
35328
|
onClick: () => onToggleLineDropdown(lineId),
|
|
35161
35329
|
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":
|
|
35330
|
+
"aria-expanded": dropdownStates[lineId],
|
|
35163
35331
|
"aria-controls": `line-${lineId}-content`,
|
|
35164
35332
|
children: [
|
|
35165
35333
|
/* @__PURE__ */ jsx(
|
|
35166
35334
|
ChevronDown,
|
|
35167
35335
|
{
|
|
35168
|
-
className: `w-5 h-5 text-blue-500 transform transition-transform duration-200 ${
|
|
35336
|
+
className: `w-5 h-5 text-blue-500 transform transition-transform duration-200 ${dropdownStates[lineId] ? "rotate-180" : ""}`
|
|
35169
35337
|
}
|
|
35170
35338
|
),
|
|
35171
35339
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5", children: [
|
|
@@ -35212,7 +35380,7 @@ var TargetsViewUI = ({
|
|
|
35212
35380
|
)
|
|
35213
35381
|
] })
|
|
35214
35382
|
] }) }),
|
|
35215
|
-
|
|
35383
|
+
dropdownStates[lineId] && /* @__PURE__ */ jsxs("div", { id: `line-${lineId}-content`, className: "border-t border-gray-200", children: [
|
|
35216
35384
|
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
35385
|
/* @__PURE__ */ jsx("label", { htmlFor: `sku-${lineId}`, className: "text-sm font-medium text-gray-700", children: "Select SKU:" }),
|
|
35218
35386
|
/* @__PURE__ */ jsx("div", { className: "flex-1 max-w-md", children: /* @__PURE__ */ jsx(
|
|
@@ -35249,68 +35417,71 @@ var TargetsViewUI = ({
|
|
|
35249
35417
|
/* @__PURE__ */ jsx("span", { className: "text-xs text-gray-400", children: "pieces per day" })
|
|
35250
35418
|
] })
|
|
35251
35419
|
] }) }),
|
|
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
|
-
|
|
35420
|
+
/* @__PURE__ */ jsx("div", { className: "divide-y divide-gray-100", children: line.workspaces.map((workspace) => {
|
|
35421
|
+
const formattedName = formatWorkspaceName(workspace.name, lineId);
|
|
35422
|
+
return /* @__PURE__ */ jsx(
|
|
35423
|
+
"div",
|
|
35424
|
+
{
|
|
35425
|
+
className: "px-6 py-4 hover:bg-gray-50 transition-all duration-200",
|
|
35426
|
+
children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-12 gap-6 items-center", children: [
|
|
35427
|
+
/* @__PURE__ */ jsx("div", { className: "col-span-2", children: /* @__PURE__ */ jsx("span", { className: "font-medium text-gray-900", children: formattedName }) }),
|
|
35428
|
+
/* @__PURE__ */ jsx("div", { className: "col-span-2", children: /* @__PURE__ */ jsxs(
|
|
35429
|
+
"select",
|
|
35430
|
+
{
|
|
35431
|
+
value: workspace.actionType,
|
|
35432
|
+
onChange: (e) => {
|
|
35433
|
+
const newActionType = e.target.value;
|
|
35434
|
+
onActionTypeChange(lineId, workspace.id, newActionType);
|
|
35435
|
+
},
|
|
35436
|
+
className: "w-full p-2 border border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm",
|
|
35437
|
+
"aria-label": `Action type for ${formattedName}`,
|
|
35438
|
+
children: [
|
|
35439
|
+
/* @__PURE__ */ jsx("option", { value: "assembly", className: "py-2", children: "Assembly" }),
|
|
35440
|
+
/* @__PURE__ */ jsx("option", { value: "packaging", className: "py-2", children: "Packaging" })
|
|
35441
|
+
]
|
|
35442
|
+
}
|
|
35443
|
+
) }),
|
|
35444
|
+
/* @__PURE__ */ jsx("div", { className: "col-span-3", children: /* @__PURE__ */ jsx(
|
|
35445
|
+
"input",
|
|
35446
|
+
{
|
|
35447
|
+
type: "number",
|
|
35448
|
+
value: workspace.targetCycleTime === 0 ? "" : workspace.targetCycleTime,
|
|
35449
|
+
onChange: (e) => onUpdateWorkspaceTarget(lineId, workspace.id, "targetCycleTime", Number(e.target.value) || ""),
|
|
35450
|
+
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",
|
|
35451
|
+
min: "0",
|
|
35452
|
+
step: "0.01",
|
|
35453
|
+
placeholder: "Enter cycle time"
|
|
35454
|
+
}
|
|
35455
|
+
) }),
|
|
35456
|
+
/* @__PURE__ */ jsx("div", { className: "col-span-3", children: /* @__PURE__ */ jsx(
|
|
35457
|
+
"input",
|
|
35458
|
+
{
|
|
35459
|
+
type: "number",
|
|
35460
|
+
value: workspace.targetPPH === 0 ? "" : workspace.targetPPH,
|
|
35461
|
+
onChange: (e) => onUpdateWorkspaceTarget(lineId, workspace.id, "targetPPH", Number(e.target.value) || ""),
|
|
35462
|
+
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",
|
|
35463
|
+
min: "0",
|
|
35464
|
+
step: "0.1",
|
|
35465
|
+
placeholder: "Enter PPH"
|
|
35466
|
+
}
|
|
35467
|
+
) }),
|
|
35468
|
+
/* @__PURE__ */ jsx("div", { className: "col-span-2", children: /* @__PURE__ */ jsx(
|
|
35469
|
+
"input",
|
|
35470
|
+
{
|
|
35471
|
+
type: "number",
|
|
35472
|
+
value: workspace.targetDayOutput === 0 ? "" : workspace.targetDayOutput,
|
|
35473
|
+
onChange: (e) => onUpdateWorkspaceTarget(lineId, workspace.id, "targetDayOutput", Number(e.target.value) || ""),
|
|
35474
|
+
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",
|
|
35475
|
+
min: "0",
|
|
35476
|
+
step: "1",
|
|
35477
|
+
placeholder: "Enter day output"
|
|
35478
|
+
}
|
|
35479
|
+
) })
|
|
35480
|
+
] })
|
|
35481
|
+
},
|
|
35482
|
+
workspace.id
|
|
35483
|
+
);
|
|
35484
|
+
}) })
|
|
35314
35485
|
] })
|
|
35315
35486
|
]
|
|
35316
35487
|
},
|
|
@@ -35343,7 +35514,6 @@ var TargetsView = ({
|
|
|
35343
35514
|
return lineIds.reduce((acc, lineId) => ({
|
|
35344
35515
|
...acc,
|
|
35345
35516
|
[lineId]: {
|
|
35346
|
-
isOpen: getStoredLineState2(lineId),
|
|
35347
35517
|
productId: "",
|
|
35348
35518
|
shiftStartTime: "08:00",
|
|
35349
35519
|
shiftEndTime: "19:00",
|
|
@@ -35356,6 +35526,12 @@ var TargetsView = ({
|
|
|
35356
35526
|
}
|
|
35357
35527
|
}), {});
|
|
35358
35528
|
}, [lineIds]);
|
|
35529
|
+
const [dropdownStates, setDropdownStates] = useState(() => {
|
|
35530
|
+
return lineIds.reduce((acc, lineId) => ({
|
|
35531
|
+
...acc,
|
|
35532
|
+
[lineId]: getStoredLineState2(lineId)
|
|
35533
|
+
}), {});
|
|
35534
|
+
});
|
|
35359
35535
|
const [allShiftsData, setAllShiftsData] = useState({
|
|
35360
35536
|
0: initialLineWorkspaces,
|
|
35361
35537
|
// Day shift
|
|
@@ -35373,6 +35549,8 @@ var TargetsView = ({
|
|
|
35373
35549
|
const [isBulkConfigureOpen, setIsBulkConfigureOpen] = useState(false);
|
|
35374
35550
|
const [selectedWorkspaces, setSelectedWorkspaces] = useState([]);
|
|
35375
35551
|
const [selectedShift, setSelectedShift] = useState(0);
|
|
35552
|
+
const [dbValues, setDbValues] = useState({ 0: {}, 1: {} });
|
|
35553
|
+
const [userEditedFields, setUserEditedFields] = useState(/* @__PURE__ */ new Set());
|
|
35376
35554
|
const lineWorkspaces = allShiftsData[selectedShift] || initialLineWorkspaces;
|
|
35377
35555
|
const setLineWorkspaces = useCallback((updater) => {
|
|
35378
35556
|
setAllShiftsData((prev) => ({
|
|
@@ -35381,18 +35559,123 @@ var TargetsView = ({
|
|
|
35381
35559
|
}));
|
|
35382
35560
|
}, [selectedShift]);
|
|
35383
35561
|
const supabase = useSupabase();
|
|
35384
|
-
const
|
|
35385
|
-
userId || auth?.user?.id;
|
|
35562
|
+
const effectiveUserId = userId || "6bf6f271-1e55-4a95-9b89-1c3820b58739";
|
|
35386
35563
|
const dashboardConfig = useDashboardConfig();
|
|
35387
35564
|
const { skus, isLoading: skusLoading } = useSKUs(companyId);
|
|
35388
35565
|
const skuEnabled = dashboardConfig?.skuConfig?.enabled || false;
|
|
35566
|
+
const loadOperatingHours = useCallback(async (lineId, shiftId) => {
|
|
35567
|
+
try {
|
|
35568
|
+
if (!supabase) return null;
|
|
35569
|
+
const { data, error } = await supabase.from("line_operating_hours").select("start_time, end_time, breaks").eq("line_id", lineId).eq("shift_id", shiftId).maybeSingle();
|
|
35570
|
+
if (error) {
|
|
35571
|
+
if (error.code === "PGRST116") {
|
|
35572
|
+
console.log(`No operating hours found for line ${lineId}, shift ${shiftId}`);
|
|
35573
|
+
return {
|
|
35574
|
+
startTime: "08:00",
|
|
35575
|
+
// Default values
|
|
35576
|
+
endTime: "19:00",
|
|
35577
|
+
breaks: []
|
|
35578
|
+
};
|
|
35579
|
+
} else {
|
|
35580
|
+
console.error("Error fetching operating hours:", error);
|
|
35581
|
+
return null;
|
|
35582
|
+
}
|
|
35583
|
+
}
|
|
35584
|
+
let breaks = [];
|
|
35585
|
+
if (data?.breaks) {
|
|
35586
|
+
if (Array.isArray(data.breaks)) {
|
|
35587
|
+
breaks = data.breaks.map((breakItem) => {
|
|
35588
|
+
const startTime = breakItem.start || breakItem.startTime || "00:00";
|
|
35589
|
+
const endTime = breakItem.end || breakItem.endTime || "00:00";
|
|
35590
|
+
const calculateDuration = (start, end) => {
|
|
35591
|
+
const [startHour, startMinute] = start.split(":").map(Number);
|
|
35592
|
+
const [endHour, endMinute] = end.split(":").map(Number);
|
|
35593
|
+
let startMinutes = startHour * 60 + startMinute;
|
|
35594
|
+
let endMinutes = endHour * 60 + endMinute;
|
|
35595
|
+
if (endMinutes < startMinutes) {
|
|
35596
|
+
endMinutes += 24 * 60;
|
|
35597
|
+
}
|
|
35598
|
+
return endMinutes - startMinutes;
|
|
35599
|
+
};
|
|
35600
|
+
return {
|
|
35601
|
+
startTime,
|
|
35602
|
+
endTime,
|
|
35603
|
+
duration: breakItem.duration || calculateDuration(startTime, endTime)
|
|
35604
|
+
};
|
|
35605
|
+
});
|
|
35606
|
+
} else if (typeof data.breaks === "object" && data.breaks.breaks) {
|
|
35607
|
+
breaks = data.breaks.breaks.map((breakItem) => {
|
|
35608
|
+
const startTime = breakItem.start || breakItem.startTime || "00:00";
|
|
35609
|
+
const endTime = breakItem.end || breakItem.endTime || "00:00";
|
|
35610
|
+
const calculateDuration = (start, end) => {
|
|
35611
|
+
const [startHour, startMinute] = start.split(":").map(Number);
|
|
35612
|
+
const [endHour, endMinute] = end.split(":").map(Number);
|
|
35613
|
+
let startMinutes = startHour * 60 + startMinute;
|
|
35614
|
+
let endMinutes = endHour * 60 + endMinute;
|
|
35615
|
+
if (endMinutes < startMinutes) {
|
|
35616
|
+
endMinutes += 24 * 60;
|
|
35617
|
+
}
|
|
35618
|
+
return endMinutes - startMinutes;
|
|
35619
|
+
};
|
|
35620
|
+
return {
|
|
35621
|
+
startTime,
|
|
35622
|
+
endTime,
|
|
35623
|
+
duration: breakItem.duration || calculateDuration(startTime, endTime)
|
|
35624
|
+
};
|
|
35625
|
+
});
|
|
35626
|
+
} else if (typeof data.breaks === "string") {
|
|
35627
|
+
try {
|
|
35628
|
+
const parsedBreaks = JSON.parse(data.breaks);
|
|
35629
|
+
if (Array.isArray(parsedBreaks)) {
|
|
35630
|
+
breaks = parsedBreaks.map((breakItem) => ({
|
|
35631
|
+
startTime: breakItem.start || breakItem.startTime || "00:00",
|
|
35632
|
+
endTime: breakItem.end || breakItem.endTime || "00:00",
|
|
35633
|
+
duration: breakItem.duration || 0
|
|
35634
|
+
}));
|
|
35635
|
+
} else if (parsedBreaks.breaks && Array.isArray(parsedBreaks.breaks)) {
|
|
35636
|
+
breaks = parsedBreaks.breaks.map((breakItem) => ({
|
|
35637
|
+
startTime: breakItem.start || breakItem.startTime || "00:00",
|
|
35638
|
+
endTime: breakItem.end || breakItem.endTime || "00:00",
|
|
35639
|
+
duration: breakItem.duration || 0
|
|
35640
|
+
}));
|
|
35641
|
+
}
|
|
35642
|
+
} catch (e) {
|
|
35643
|
+
console.error("Error parsing breaks data:", e);
|
|
35644
|
+
}
|
|
35645
|
+
}
|
|
35646
|
+
}
|
|
35647
|
+
return {
|
|
35648
|
+
startTime: data?.start_time || "08:00",
|
|
35649
|
+
endTime: data?.end_time || "19:00",
|
|
35650
|
+
breaks
|
|
35651
|
+
};
|
|
35652
|
+
} catch (e) {
|
|
35653
|
+
console.error("Exception when loading operating hours:", e);
|
|
35654
|
+
return {
|
|
35655
|
+
startTime: "08:00",
|
|
35656
|
+
endTime: "19:00",
|
|
35657
|
+
breaks: []
|
|
35658
|
+
};
|
|
35659
|
+
}
|
|
35660
|
+
}, [supabase]);
|
|
35661
|
+
useEffect(() => {
|
|
35662
|
+
console.log("[TargetsView] Component mounted/re-rendered", {
|
|
35663
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
35664
|
+
lineIds: lineIds.length,
|
|
35665
|
+
effectiveUserId
|
|
35666
|
+
});
|
|
35667
|
+
return () => {
|
|
35668
|
+
console.log("[TargetsView] Component unmounting");
|
|
35669
|
+
};
|
|
35670
|
+
}, []);
|
|
35389
35671
|
useEffect(() => {
|
|
35390
35672
|
let timeoutId;
|
|
35391
35673
|
let retryCount = 0;
|
|
35392
35674
|
const MAX_RETRIES2 = 2;
|
|
35393
35675
|
const LOADING_TIMEOUT = 15e3;
|
|
35394
35676
|
const fetchInitialData = async () => {
|
|
35395
|
-
if (
|
|
35677
|
+
if (lineIds.length === 0) return;
|
|
35678
|
+
console.log("[TargetsView] Starting fetchInitialData");
|
|
35396
35679
|
setIsLoading(true);
|
|
35397
35680
|
timeoutId = setTimeout(() => {
|
|
35398
35681
|
console.error("Loading timeout reached");
|
|
@@ -35456,10 +35739,32 @@ var TargetsView = ({
|
|
|
35456
35739
|
const actionThresholds = await workspaceService.getActionThresholds(
|
|
35457
35740
|
lineId,
|
|
35458
35741
|
currentDate,
|
|
35459
|
-
|
|
35742
|
+
0
|
|
35743
|
+
// Always use day shift for initial load
|
|
35460
35744
|
);
|
|
35745
|
+
const operatingHoursData = await loadOperatingHours(lineId, 0);
|
|
35746
|
+
if (operatingHoursData) {
|
|
35747
|
+
updatedLineWorkspaces[lineId].shiftStartTime = operatingHoursData.startTime;
|
|
35748
|
+
updatedLineWorkspaces[lineId].shiftEndTime = operatingHoursData.endTime;
|
|
35749
|
+
updatedLineWorkspaces[lineId].breaks = operatingHoursData.breaks;
|
|
35750
|
+
updatedLineWorkspaces[lineId].shiftHours = calculateShiftHours2(
|
|
35751
|
+
operatingHoursData.startTime,
|
|
35752
|
+
operatingHoursData.endTime,
|
|
35753
|
+
operatingHoursData.breaks
|
|
35754
|
+
);
|
|
35755
|
+
}
|
|
35461
35756
|
const mappedWorkspaces = enabledWorkspaces.map((ws) => {
|
|
35462
35757
|
const threshold = actionThresholds.find((t) => t.workspace_id === ws.id);
|
|
35758
|
+
if (!dbValues[0][lineId]) {
|
|
35759
|
+
dbValues[0][lineId] = {};
|
|
35760
|
+
}
|
|
35761
|
+
if (threshold) {
|
|
35762
|
+
dbValues[0][lineId][ws.id] = {
|
|
35763
|
+
targetPPH: threshold.pph_threshold,
|
|
35764
|
+
targetCycleTime: threshold.ideal_cycle_time,
|
|
35765
|
+
targetDayOutput: threshold.total_day_output
|
|
35766
|
+
};
|
|
35767
|
+
}
|
|
35463
35768
|
return {
|
|
35464
35769
|
id: ws.id,
|
|
35465
35770
|
name: ws.workspace_id,
|
|
@@ -35500,90 +35805,7 @@ var TargetsView = ({
|
|
|
35500
35805
|
return () => {
|
|
35501
35806
|
clearTimeout(timeoutId);
|
|
35502
35807
|
};
|
|
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]);
|
|
35808
|
+
}, [lineIds, companyId, loadOperatingHours]);
|
|
35587
35809
|
const fetchAllShiftsData = useCallback(async (currentWorkspaces) => {
|
|
35588
35810
|
if (!supabase) return;
|
|
35589
35811
|
const currentDate = getOperationalDate();
|
|
@@ -35593,32 +35815,25 @@ var TargetsView = ({
|
|
|
35593
35815
|
1: JSON.parse(JSON.stringify(currentWorkspaces))
|
|
35594
35816
|
// Deep clone for night shift
|
|
35595
35817
|
};
|
|
35818
|
+
const newDbValues = { 0: {}, 1: {} };
|
|
35596
35819
|
for (const shiftId of [0, 1]) {
|
|
35597
35820
|
for (const lineId of lineIds) {
|
|
35598
35821
|
try {
|
|
35599
|
-
const
|
|
35600
|
-
if (
|
|
35601
|
-
console.
|
|
35822
|
+
const operatingHoursData = await loadOperatingHours(lineId, shiftId);
|
|
35823
|
+
if (!operatingHoursData) {
|
|
35824
|
+
console.warn(`No operating hours for line ${lineId}, shift ${shiftId} - using defaults`);
|
|
35602
35825
|
continue;
|
|
35603
35826
|
}
|
|
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";
|
|
35827
|
+
const { startTime, endTime, breaks } = operatingHoursData;
|
|
35616
35828
|
const shiftHours = calculateShiftHours2(startTime, endTime, breaks);
|
|
35617
35829
|
const actionThresholds = await workspaceService.getActionThresholds(
|
|
35618
35830
|
lineId,
|
|
35619
35831
|
currentDate,
|
|
35620
35832
|
shiftId
|
|
35621
35833
|
);
|
|
35834
|
+
if (!newDbValues[shiftId][lineId]) {
|
|
35835
|
+
newDbValues[shiftId][lineId] = {};
|
|
35836
|
+
}
|
|
35622
35837
|
const existingLine = newAllShiftsData[shiftId][lineId];
|
|
35623
35838
|
if (existingLine) {
|
|
35624
35839
|
newAllShiftsData[shiftId][lineId] = {
|
|
@@ -35630,6 +35845,11 @@ var TargetsView = ({
|
|
|
35630
35845
|
workspaces: existingLine.workspaces.map((ws) => {
|
|
35631
35846
|
const threshold = actionThresholds.find((t) => t.workspace_id === ws.id);
|
|
35632
35847
|
if (threshold) {
|
|
35848
|
+
newDbValues[shiftId][lineId][ws.id] = {
|
|
35849
|
+
targetPPH: threshold.pph_threshold,
|
|
35850
|
+
targetCycleTime: threshold.ideal_cycle_time,
|
|
35851
|
+
targetDayOutput: threshold.total_day_output
|
|
35852
|
+
};
|
|
35633
35853
|
return {
|
|
35634
35854
|
...ws,
|
|
35635
35855
|
targetPPH: threshold.pph_threshold,
|
|
@@ -35647,114 +35867,17 @@ var TargetsView = ({
|
|
|
35647
35867
|
}
|
|
35648
35868
|
}
|
|
35649
35869
|
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]);
|
|
35870
|
+
setDbValues(newDbValues);
|
|
35871
|
+
}, [supabase, lineIds, loadOperatingHours]);
|
|
35746
35872
|
const toggleLineDropdown = useCallback((lineId) => {
|
|
35747
|
-
|
|
35748
|
-
const newIsOpen = !prev[lineId]
|
|
35873
|
+
setDropdownStates((prev) => {
|
|
35874
|
+
const newIsOpen = !prev[lineId];
|
|
35749
35875
|
if (typeof window !== "undefined") {
|
|
35750
35876
|
localStorage.setItem(`line_${lineId}_open`, JSON.stringify(newIsOpen));
|
|
35751
35877
|
}
|
|
35752
35878
|
return {
|
|
35753
35879
|
...prev,
|
|
35754
|
-
[lineId]:
|
|
35755
|
-
...prev[lineId],
|
|
35756
|
-
isOpen: newIsOpen
|
|
35757
|
-
}
|
|
35880
|
+
[lineId]: newIsOpen
|
|
35758
35881
|
};
|
|
35759
35882
|
});
|
|
35760
35883
|
}, []);
|
|
@@ -35803,6 +35926,8 @@ var TargetsView = ({
|
|
|
35803
35926
|
}
|
|
35804
35927
|
};
|
|
35805
35928
|
const updateWorkspaceTarget = (lineId, workspaceId, field, value) => {
|
|
35929
|
+
const fieldKey = `${lineId}-${workspaceId}-${field}`;
|
|
35930
|
+
setUserEditedFields((prev) => new Set(prev).add(fieldKey));
|
|
35806
35931
|
setLineWorkspaces((prev) => {
|
|
35807
35932
|
const shiftHours = prev[lineId].shiftHours;
|
|
35808
35933
|
return {
|
|
@@ -35827,11 +35952,7 @@ var TargetsView = ({
|
|
|
35827
35952
|
} else if (field === "targetDayOutput") {
|
|
35828
35953
|
updates.targetDayOutput = value;
|
|
35829
35954
|
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);
|
|
35955
|
+
const calculatedPPH = Math.round(value / shiftHours);
|
|
35835
35956
|
updates.targetPPH = calculatedPPH;
|
|
35836
35957
|
} else {
|
|
35837
35958
|
updates.targetPPH = "";
|
|
@@ -35846,62 +35967,35 @@ var TargetsView = ({
|
|
|
35846
35967
|
};
|
|
35847
35968
|
const handleShiftChange = (shiftId) => {
|
|
35848
35969
|
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;
|
|
35970
|
+
setUserEditedFields(/* @__PURE__ */ new Set());
|
|
35971
|
+
if (dbValues[shiftId] && Object.keys(dbValues[shiftId]).length > 0) {
|
|
35972
|
+
setAllShiftsData((prev) => {
|
|
35973
|
+
const updatedShiftData = { ...prev[shiftId] };
|
|
35974
|
+
for (const lineId of Object.keys(updatedShiftData)) {
|
|
35975
|
+
if (dbValues[shiftId][lineId]) {
|
|
35976
|
+
updatedShiftData[lineId] = {
|
|
35977
|
+
...updatedShiftData[lineId],
|
|
35978
|
+
workspaces: updatedShiftData[lineId].workspaces.map((ws) => {
|
|
35979
|
+
const dbValue = dbValues[shiftId][lineId][ws.id];
|
|
35980
|
+
if (dbValue) {
|
|
35981
|
+
return {
|
|
35982
|
+
...ws,
|
|
35983
|
+
targetPPH: dbValue.targetPPH,
|
|
35984
|
+
targetCycleTime: dbValue.targetCycleTime,
|
|
35985
|
+
targetDayOutput: dbValue.targetDayOutput
|
|
35986
|
+
};
|
|
35878
35987
|
}
|
|
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);
|
|
35988
|
+
return ws;
|
|
35989
|
+
})
|
|
35990
|
+
};
|
|
35991
|
+
}
|
|
35895
35992
|
}
|
|
35896
|
-
|
|
35897
|
-
if (hasUpdates) {
|
|
35898
|
-
setAllShiftsData((prev) => ({
|
|
35993
|
+
return {
|
|
35899
35994
|
...prev,
|
|
35900
|
-
[shiftId]:
|
|
35901
|
-
}
|
|
35902
|
-
}
|
|
35903
|
-
}
|
|
35904
|
-
loadShiftHours();
|
|
35995
|
+
[shiftId]: updatedShiftData
|
|
35996
|
+
};
|
|
35997
|
+
});
|
|
35998
|
+
}
|
|
35905
35999
|
};
|
|
35906
36000
|
const handleActionTypeChange = useCallback((lineId, workspaceId, newActionType) => {
|
|
35907
36001
|
if (!actionIds) return;
|
|
@@ -35991,6 +36085,31 @@ var TargetsView = ({
|
|
|
35991
36085
|
throw lineUpsertError;
|
|
35992
36086
|
}
|
|
35993
36087
|
console.log(`[handleSaveLine] Successfully upserted line_thresholds for ${lineId}`);
|
|
36088
|
+
setDbValues((prev) => ({
|
|
36089
|
+
...prev,
|
|
36090
|
+
[selectedShift]: {
|
|
36091
|
+
...prev[selectedShift],
|
|
36092
|
+
[lineId]: lineDataToSave.workspaces.reduce((acc, ws) => ({
|
|
36093
|
+
...acc,
|
|
36094
|
+
[ws.id]: {
|
|
36095
|
+
targetPPH: ws.targetPPH,
|
|
36096
|
+
targetCycleTime: ws.targetCycleTime,
|
|
36097
|
+
targetDayOutput: ws.targetDayOutput
|
|
36098
|
+
}
|
|
36099
|
+
}), {})
|
|
36100
|
+
}
|
|
36101
|
+
}));
|
|
36102
|
+
console.log(`[handleSaveLine] Updated dbValues for line ${lineId}, shift ${selectedShift}`);
|
|
36103
|
+
setUserEditedFields((prev) => {
|
|
36104
|
+
const newSet = new Set(prev);
|
|
36105
|
+
lineDataToSave.workspaces.forEach((ws) => {
|
|
36106
|
+
newSet.delete(`${lineId}-${ws.id}-targetPPH`);
|
|
36107
|
+
newSet.delete(`${lineId}-${ws.id}-targetCycleTime`);
|
|
36108
|
+
newSet.delete(`${lineId}-${ws.id}-targetDayOutput`);
|
|
36109
|
+
});
|
|
36110
|
+
return newSet;
|
|
36111
|
+
});
|
|
36112
|
+
console.log(`[handleSaveLine] Cleared user edited fields for line ${lineId}`);
|
|
35994
36113
|
setSaveSuccess((prev) => ({ ...prev, [lineId]: true }));
|
|
35995
36114
|
toast.success(`${lineNames[lineId] || lineId} targets saved successfully`);
|
|
35996
36115
|
if (onSaveChanges) onSaveChanges(lineId);
|
|
@@ -36004,7 +36123,7 @@ var TargetsView = ({
|
|
|
36004
36123
|
setSavingLines((prev) => ({ ...prev, [lineId]: false }));
|
|
36005
36124
|
console.log(`[handleSaveLine] Set savingLines to false for ${lineId} in finally block`);
|
|
36006
36125
|
}
|
|
36007
|
-
}, [supabase, lineWorkspaces, selectedShift, lineNames, onSaveChanges]);
|
|
36126
|
+
}, [supabase, lineWorkspaces, selectedShift, lineNames, onSaveChanges, skuEnabled, dashboardConfig]);
|
|
36008
36127
|
const handleBulkConfigure = async (updates) => {
|
|
36009
36128
|
if (!actionIds) return;
|
|
36010
36129
|
if (updates.productId !== void 0) {
|
|
@@ -36052,6 +36171,7 @@ var TargetsView = ({
|
|
|
36052
36171
|
isLoading: isLoading || skusLoading,
|
|
36053
36172
|
lineWorkspaces,
|
|
36054
36173
|
lineNames,
|
|
36174
|
+
dropdownStates,
|
|
36055
36175
|
savingLines,
|
|
36056
36176
|
saveSuccess,
|
|
36057
36177
|
selectedShift,
|
|
@@ -36076,7 +36196,7 @@ var TargetsView = ({
|
|
|
36076
36196
|
};
|
|
36077
36197
|
var TargetsViewWithDisplayNames = withAllWorkspaceDisplayNames(TargetsView);
|
|
36078
36198
|
var TargetsView_default = TargetsViewWithDisplayNames;
|
|
36079
|
-
var AuthenticatedTargetsView = withAuth(TargetsViewWithDisplayNames);
|
|
36199
|
+
var AuthenticatedTargetsView = withAuth(React19__default.memo(TargetsViewWithDisplayNames));
|
|
36080
36200
|
|
|
36081
36201
|
// src/views/workspace-detail-view.utils.ts
|
|
36082
36202
|
var formatISTDate2 = (date = /* @__PURE__ */ new Date(), options) => {
|
|
@@ -37547,4 +37667,4 @@ var streamProxyConfig = {
|
|
|
37547
37667
|
}
|
|
37548
37668
|
};
|
|
37549
37669
|
|
|
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 };
|
|
37670
|
+
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 };
|