@optifye/dashboard-core 6.0.9 → 6.1.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 +29 -43
- package/dist/index.d.ts +29 -43
- package/dist/index.js +421 -105
- package/dist/index.mjs +421 -107
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -12,7 +12,7 @@ import { noop, warning, invariant, progress, secondsToMilliseconds, milliseconds
|
|
|
12
12
|
import { getValueTransition, hover, press, isPrimaryPointer, GroupPlaybackControls, setDragLock, supportsLinearEasing, attachTimeline, isGenerator, calcGeneratorDuration, isWaapiSupportedEasing, mapEasingToNativeEasing, maxGeneratorDuration, generateLinearEasing, isBezierDefinition } from 'motion-dom';
|
|
13
13
|
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';
|
|
14
14
|
import { Slot } from '@radix-ui/react-slot';
|
|
15
|
-
import { Camera, ChevronDown, ChevronUp, Check, ShieldCheck, Star, Award, X, Coffee, Plus, Clock, Minus, ArrowDown, ArrowUp, Search, CheckCircle, AlertTriangle, Info, Share2, Download, User, XCircle, ChevronLeft, ChevronRight, AlertCircle, Sun, Moon, MessageSquare, Trash2, ArrowLeft, RefreshCw, Menu, Send, Copy, Edit2, UserCheck, Save, LogOut, Calendar, Package, Settings, LifeBuoy, ArrowLeftIcon as ArrowLeftIcon$1, Settings2, CheckCircle2
|
|
15
|
+
import { Camera, ChevronDown, ChevronUp, Check, ShieldCheck, Star, Award, X, Coffee, Plus, Clock, Minus, ArrowDown, ArrowUp, Search, CheckCircle, AlertTriangle, Info, Share2, Download, User, XCircle, ChevronLeft, ChevronRight, AlertCircle, Sun, Moon, MessageSquare, Trash2, ArrowLeft, RefreshCw, Menu, Send, Copy, Edit2, UserCheck, Save, LogOut, Calendar, Package, Settings, LifeBuoy, EyeOff, Eye, Zap, UserCircle, ArrowLeftIcon as ArrowLeftIcon$1, Settings2, CheckCircle2 } from 'lucide-react';
|
|
16
16
|
import { DayPicker, useNavigation as useNavigation$1 } from 'react-day-picker';
|
|
17
17
|
import html2canvas from 'html2canvas';
|
|
18
18
|
import jsPDF, { jsPDF as jsPDF$1 } from 'jspdf';
|
|
@@ -4987,34 +4987,6 @@ var useWorkspaceOperators = (workspaceId, options) => {
|
|
|
4987
4987
|
refetch: fetchData
|
|
4988
4988
|
};
|
|
4989
4989
|
};
|
|
4990
|
-
|
|
4991
|
-
// src/lib/utils/dashboardReload.ts
|
|
4992
|
-
var createThrottledReload = (interval = 5e3) => {
|
|
4993
|
-
let last = 0;
|
|
4994
|
-
let queued = false;
|
|
4995
|
-
const doReload = () => {
|
|
4996
|
-
if (typeof window !== "undefined") {
|
|
4997
|
-
window.location.reload();
|
|
4998
|
-
}
|
|
4999
|
-
};
|
|
5000
|
-
return () => {
|
|
5001
|
-
const now2 = Date.now();
|
|
5002
|
-
if (now2 - last >= interval) {
|
|
5003
|
-
last = now2;
|
|
5004
|
-
doReload();
|
|
5005
|
-
} else if (!queued) {
|
|
5006
|
-
queued = true;
|
|
5007
|
-
setTimeout(() => {
|
|
5008
|
-
queued = false;
|
|
5009
|
-
last = Date.now();
|
|
5010
|
-
doReload();
|
|
5011
|
-
}, interval - (now2 - last));
|
|
5012
|
-
}
|
|
5013
|
-
};
|
|
5014
|
-
};
|
|
5015
|
-
var throttledReloadDashboard = createThrottledReload(5e3);
|
|
5016
|
-
|
|
5017
|
-
// src/lib/hooks/useHlsStream.ts
|
|
5018
4990
|
var HLS_CONFIG = {
|
|
5019
4991
|
maxBufferLength: 8,
|
|
5020
4992
|
maxMaxBufferLength: 15,
|
|
@@ -5033,7 +5005,35 @@ var HLS_CONFIG = {
|
|
|
5033
5005
|
liveSyncDurationCount: 2
|
|
5034
5006
|
// Follow live edge aggressively
|
|
5035
5007
|
};
|
|
5008
|
+
var failedUrls = /* @__PURE__ */ new Map();
|
|
5009
|
+
var MAX_FAILURES_PER_URL = 3;
|
|
5010
|
+
var FAILURE_EXPIRY_MS = 5 * 60 * 1e3;
|
|
5011
|
+
function resetFailedUrl(url) {
|
|
5012
|
+
if (failedUrls.has(url)) {
|
|
5013
|
+
console.log(`[HLS] Manually resetting failed URL: ${url}`);
|
|
5014
|
+
failedUrls.delete(url);
|
|
5015
|
+
}
|
|
5016
|
+
}
|
|
5017
|
+
function isUrlPermanentlyFailed(url) {
|
|
5018
|
+
const failure = failedUrls.get(url);
|
|
5019
|
+
return failure?.permanentlyFailed || false;
|
|
5020
|
+
}
|
|
5036
5021
|
function useHlsStream(videoRef, { src, shouldPlay, onFatalError }) {
|
|
5022
|
+
const urlFailure = failedUrls.get(src);
|
|
5023
|
+
const isPermanentlyFailed = urlFailure?.permanentlyFailed || false;
|
|
5024
|
+
const cleanupFailedUrls = () => {
|
|
5025
|
+
const now2 = Date.now();
|
|
5026
|
+
const expiredUrls = [];
|
|
5027
|
+
failedUrls.forEach((failure, url) => {
|
|
5028
|
+
if (now2 - failure.timestamp > FAILURE_EXPIRY_MS) {
|
|
5029
|
+
expiredUrls.push(url);
|
|
5030
|
+
}
|
|
5031
|
+
});
|
|
5032
|
+
expiredUrls.forEach((url) => {
|
|
5033
|
+
console.log(`[HLS] Removing expired failure entry for: ${url}`);
|
|
5034
|
+
failedUrls.delete(url);
|
|
5035
|
+
});
|
|
5036
|
+
};
|
|
5037
5037
|
const [restartKey, setRestartKey] = useState(0);
|
|
5038
5038
|
const hlsRef = useRef(null);
|
|
5039
5039
|
const stallCheckIntervalRef = useRef(null);
|
|
@@ -5103,14 +5103,33 @@ function useHlsStream(videoRef, { src, shouldPlay, onFatalError }) {
|
|
|
5103
5103
|
};
|
|
5104
5104
|
const hardRestart = (reason) => {
|
|
5105
5105
|
console.warn(`[HLS] Hard restart: ${reason}`);
|
|
5106
|
+
cleanupFailedUrls();
|
|
5107
|
+
const failure = failedUrls.get(src);
|
|
5108
|
+
const failureCount = failure ? failure.count : 0;
|
|
5109
|
+
if (failureCount >= MAX_FAILURES_PER_URL) {
|
|
5110
|
+
console.error(`[HLS] URL has failed ${failureCount} times. Marking as permanently failed: ${src}`);
|
|
5111
|
+
failedUrls.set(src, {
|
|
5112
|
+
count: failureCount,
|
|
5113
|
+
timestamp: Date.now(),
|
|
5114
|
+
permanentlyFailed: true
|
|
5115
|
+
});
|
|
5116
|
+
cleanup();
|
|
5117
|
+
if (onFatalError) {
|
|
5118
|
+
onFatalError();
|
|
5119
|
+
}
|
|
5120
|
+
return;
|
|
5121
|
+
}
|
|
5122
|
+
failedUrls.set(src, {
|
|
5123
|
+
count: failureCount + 1,
|
|
5124
|
+
timestamp: Date.now(),
|
|
5125
|
+
permanentlyFailed: false
|
|
5126
|
+
});
|
|
5106
5127
|
cleanup();
|
|
5107
5128
|
setRestartKey((k) => k + 1);
|
|
5108
5129
|
softRestartCountRef.current = 0;
|
|
5109
|
-
if (reason.includes("hard restart")
|
|
5130
|
+
if (reason.includes("404 hard restart")) {
|
|
5110
5131
|
if (onFatalError) {
|
|
5111
5132
|
onFatalError();
|
|
5112
|
-
} else {
|
|
5113
|
-
throttledReloadDashboard();
|
|
5114
5133
|
}
|
|
5115
5134
|
}
|
|
5116
5135
|
};
|
|
@@ -5164,6 +5183,13 @@ function useHlsStream(videoRef, { src, shouldPlay, onFatalError }) {
|
|
|
5164
5183
|
}, 7e3);
|
|
5165
5184
|
};
|
|
5166
5185
|
useEffect(() => {
|
|
5186
|
+
if (isPermanentlyFailed) {
|
|
5187
|
+
console.warn(`[HLS] URL is permanently failed, not attempting to load: ${src}`);
|
|
5188
|
+
if (onFatalError) {
|
|
5189
|
+
onFatalError();
|
|
5190
|
+
}
|
|
5191
|
+
return;
|
|
5192
|
+
}
|
|
5167
5193
|
if (!src || !shouldPlay) {
|
|
5168
5194
|
cleanup();
|
|
5169
5195
|
return;
|
|
@@ -5194,6 +5220,10 @@ function useHlsStream(videoRef, { src, shouldPlay, onFatalError }) {
|
|
|
5194
5220
|
}
|
|
5195
5221
|
});
|
|
5196
5222
|
hls.on(Hls2.Events.MANIFEST_PARSED, () => {
|
|
5223
|
+
if (failedUrls.has(src)) {
|
|
5224
|
+
console.log(`[HLS] Stream loaded successfully, resetting failure count for: ${src}`);
|
|
5225
|
+
failedUrls.delete(src);
|
|
5226
|
+
}
|
|
5197
5227
|
video.play().catch((err) => {
|
|
5198
5228
|
console.error("[HLS] Play failed:", err);
|
|
5199
5229
|
});
|
|
@@ -5212,7 +5242,7 @@ function useHlsStream(videoRef, { src, shouldPlay, onFatalError }) {
|
|
|
5212
5242
|
console.error("[HLS] HLS not supported");
|
|
5213
5243
|
}
|
|
5214
5244
|
return cleanup;
|
|
5215
|
-
}, [src, shouldPlay, restartKey, onFatalError]);
|
|
5245
|
+
}, [src, shouldPlay, restartKey, onFatalError, isPermanentlyFailed]);
|
|
5216
5246
|
return {
|
|
5217
5247
|
restartKey,
|
|
5218
5248
|
isNativeHls: isNativeHlsRef.current
|
|
@@ -6317,7 +6347,7 @@ function useNavigation(customNavigate) {
|
|
|
6317
6347
|
}
|
|
6318
6348
|
function useWorkspaceNavigation() {
|
|
6319
6349
|
const { defaultTimezone } = useDateTimeConfig();
|
|
6320
|
-
const
|
|
6350
|
+
const getWorkspaceNavigationParams2 = useCallback(
|
|
6321
6351
|
(workspaceId, options) => {
|
|
6322
6352
|
let dateToUse = options?.date;
|
|
6323
6353
|
if (!dateToUse && options?.useCurrentDate) {
|
|
@@ -6333,7 +6363,7 @@ function useWorkspaceNavigation() {
|
|
|
6333
6363
|
[defaultTimezone]
|
|
6334
6364
|
);
|
|
6335
6365
|
return {
|
|
6336
|
-
getWorkspaceNavigationParams:
|
|
6366
|
+
getWorkspaceNavigationParams: getWorkspaceNavigationParams2
|
|
6337
6367
|
};
|
|
6338
6368
|
}
|
|
6339
6369
|
function useDateFormatter() {
|
|
@@ -9031,9 +9061,15 @@ var getStoredWorkspaceMappings = () => {
|
|
|
9031
9061
|
var getDefaultTabForWorkspace = (workspaceId, displayName) => {
|
|
9032
9062
|
return "overview";
|
|
9033
9063
|
};
|
|
9034
|
-
var getWorkspaceNavigationParams = (workspaceId, displayName) => {
|
|
9064
|
+
var getWorkspaceNavigationParams = (workspaceId, displayName, lineId) => {
|
|
9035
9065
|
const defaultTab = getDefaultTabForWorkspace();
|
|
9036
|
-
|
|
9066
|
+
const params = new URLSearchParams();
|
|
9067
|
+
params.set("displayName", displayName);
|
|
9068
|
+
params.set("defaultTab", defaultTab);
|
|
9069
|
+
if (lineId) {
|
|
9070
|
+
params.set("lineId", lineId);
|
|
9071
|
+
}
|
|
9072
|
+
return `?${params.toString()}`;
|
|
9037
9073
|
};
|
|
9038
9074
|
|
|
9039
9075
|
// src/lib/utils/videoPreloader.ts
|
|
@@ -9354,6 +9390,115 @@ var clearS3VideoCache = () => {
|
|
|
9354
9390
|
var preloadS3VideoUrl = s3VideoPreloader.preloadVideo;
|
|
9355
9391
|
var preloadS3VideosUrl = s3VideoPreloader.preloadVideos;
|
|
9356
9392
|
|
|
9393
|
+
// src/lib/utils/dashboardReload.ts
|
|
9394
|
+
var reloadAttempts = [];
|
|
9395
|
+
var createThrottledReload = (interval = 5e3, maxReloads = 3) => {
|
|
9396
|
+
const circuitBreakerWindow = 1e4;
|
|
9397
|
+
const circuitBreakerThreshold = 5;
|
|
9398
|
+
let last = 0;
|
|
9399
|
+
let queued = false;
|
|
9400
|
+
let reloadCount = 0;
|
|
9401
|
+
let firstReloadTime = 0;
|
|
9402
|
+
const resetWindow = 6e4;
|
|
9403
|
+
const doReload = () => {
|
|
9404
|
+
if (typeof window !== "undefined") {
|
|
9405
|
+
const now2 = Date.now();
|
|
9406
|
+
reloadAttempts.push(now2);
|
|
9407
|
+
const cutoff = now2 - circuitBreakerWindow;
|
|
9408
|
+
const recentAttempts = reloadAttempts.filter((t) => t > cutoff);
|
|
9409
|
+
reloadAttempts.length = 0;
|
|
9410
|
+
reloadAttempts.push(...recentAttempts);
|
|
9411
|
+
if (recentAttempts.length >= circuitBreakerThreshold) {
|
|
9412
|
+
console.error(`[Dashboard Reload] Circuit breaker triggered! ${recentAttempts.length} reload attempts in ${circuitBreakerWindow}ms`);
|
|
9413
|
+
const errorDiv = document.createElement("div");
|
|
9414
|
+
errorDiv.id = "reload-circuit-breaker";
|
|
9415
|
+
errorDiv.style.cssText = `
|
|
9416
|
+
position: fixed;
|
|
9417
|
+
top: 20px;
|
|
9418
|
+
left: 50%;
|
|
9419
|
+
transform: translateX(-50%);
|
|
9420
|
+
background: #dc2626;
|
|
9421
|
+
color: white;
|
|
9422
|
+
padding: 20px 32px;
|
|
9423
|
+
border-radius: 12px;
|
|
9424
|
+
z-index: 99999;
|
|
9425
|
+
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.3);
|
|
9426
|
+
font-family: system-ui, -apple-system, sans-serif;
|
|
9427
|
+
`;
|
|
9428
|
+
errorDiv.innerHTML = `
|
|
9429
|
+
<div style="display: flex; align-items: center; gap: 16px;">
|
|
9430
|
+
<svg width="24" height="24" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
9431
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path>
|
|
9432
|
+
</svg>
|
|
9433
|
+
<div>
|
|
9434
|
+
<div style="font-weight: 600; font-size: 16px; margin-bottom: 4px;">Too many reload attempts detected</div>
|
|
9435
|
+
<div style="font-size: 14px; opacity: 0.9;">Please check your network connection and refresh manually.</div>
|
|
9436
|
+
</div>
|
|
9437
|
+
</div>
|
|
9438
|
+
`;
|
|
9439
|
+
const existing = document.getElementById("reload-circuit-breaker");
|
|
9440
|
+
if (existing) existing.remove();
|
|
9441
|
+
document.body.appendChild(errorDiv);
|
|
9442
|
+
return;
|
|
9443
|
+
}
|
|
9444
|
+
if (now2 - firstReloadTime > resetWindow) {
|
|
9445
|
+
reloadCount = 0;
|
|
9446
|
+
firstReloadTime = now2;
|
|
9447
|
+
}
|
|
9448
|
+
if (reloadCount === 0) {
|
|
9449
|
+
firstReloadTime = now2;
|
|
9450
|
+
}
|
|
9451
|
+
reloadCount++;
|
|
9452
|
+
if (reloadCount > maxReloads) {
|
|
9453
|
+
console.error(`[Dashboard Reload] Maximum reload attempts (${maxReloads}) reached. Stopping to prevent infinite loop.`);
|
|
9454
|
+
const errorDiv = document.createElement("div");
|
|
9455
|
+
errorDiv.style.cssText = `
|
|
9456
|
+
position: fixed;
|
|
9457
|
+
top: 20px;
|
|
9458
|
+
left: 50%;
|
|
9459
|
+
transform: translateX(-50%);
|
|
9460
|
+
background: #ef4444;
|
|
9461
|
+
color: white;
|
|
9462
|
+
padding: 16px 24px;
|
|
9463
|
+
border-radius: 8px;
|
|
9464
|
+
z-index: 9999;
|
|
9465
|
+
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
|
9466
|
+
`;
|
|
9467
|
+
errorDiv.innerHTML = `
|
|
9468
|
+
<div style="display: flex; align-items: center; gap: 12px;">
|
|
9469
|
+
<svg width="20" height="20" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
9470
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
|
|
9471
|
+
</svg>
|
|
9472
|
+
<span>Stream connection failed. Please refresh the page manually.</span>
|
|
9473
|
+
</div>
|
|
9474
|
+
`;
|
|
9475
|
+
document.body.appendChild(errorDiv);
|
|
9476
|
+
setTimeout(() => {
|
|
9477
|
+
document.body.removeChild(errorDiv);
|
|
9478
|
+
}, 1e4);
|
|
9479
|
+
return;
|
|
9480
|
+
}
|
|
9481
|
+
console.warn(`[Dashboard Reload] Reloading dashboard (attempt ${reloadCount}/${maxReloads})`);
|
|
9482
|
+
window.location.reload();
|
|
9483
|
+
}
|
|
9484
|
+
};
|
|
9485
|
+
return () => {
|
|
9486
|
+
const now2 = Date.now();
|
|
9487
|
+
if (now2 - last >= interval) {
|
|
9488
|
+
last = now2;
|
|
9489
|
+
doReload();
|
|
9490
|
+
} else if (!queued) {
|
|
9491
|
+
queued = true;
|
|
9492
|
+
setTimeout(() => {
|
|
9493
|
+
queued = false;
|
|
9494
|
+
last = Date.now();
|
|
9495
|
+
doReload();
|
|
9496
|
+
}, interval - (now2 - last));
|
|
9497
|
+
}
|
|
9498
|
+
};
|
|
9499
|
+
};
|
|
9500
|
+
var throttledReloadDashboard = createThrottledReload(5e3, 3);
|
|
9501
|
+
|
|
9357
9502
|
// src/lib/utils/index.ts
|
|
9358
9503
|
var formatIdleTime = (idleTimeInSeconds) => {
|
|
9359
9504
|
if (!idleTimeInSeconds || idleTimeInSeconds <= 0) {
|
|
@@ -18640,6 +18785,7 @@ var VideoGridView = React19__default.memo(({
|
|
|
18640
18785
|
const [gridRows, setGridRows] = useState(1);
|
|
18641
18786
|
const [visibleWorkspaces, setVisibleWorkspaces] = useState(/* @__PURE__ */ new Set());
|
|
18642
18787
|
const [cardDimensions, setCardDimensions] = useState({ width: 0, height: 0 });
|
|
18788
|
+
const [failedStreams, setFailedStreams] = useState(/* @__PURE__ */ new Set());
|
|
18643
18789
|
const videoConfig = useVideoConfig();
|
|
18644
18790
|
const { cropping, canvasConfig, hlsUrls } = videoConfig;
|
|
18645
18791
|
const mergedVideoSources = {
|
|
@@ -18791,9 +18937,17 @@ var VideoGridView = React19__default.memo(({
|
|
|
18791
18937
|
action_count: workspace.action_count
|
|
18792
18938
|
});
|
|
18793
18939
|
const displayName = getWorkspaceDisplayName(workspace.workspace_name, workspace.line_id);
|
|
18794
|
-
const navParams = getWorkspaceNavigationParams(workspaceId, displayName);
|
|
18940
|
+
const navParams = getWorkspaceNavigationParams(workspaceId, displayName, workspace.line_id);
|
|
18795
18941
|
router.push(`/workspace/${workspaceId}${navParams}`);
|
|
18796
18942
|
}, [router]);
|
|
18943
|
+
const handleStreamError = useCallback((workspaceId) => {
|
|
18944
|
+
console.error(`[VideoGridView] Stream failed for workspace: ${workspaceId}`);
|
|
18945
|
+
setFailedStreams((prev) => new Set(prev).add(workspaceId));
|
|
18946
|
+
trackCoreEvent("Video Stream Error", {
|
|
18947
|
+
workspace_id: workspaceId,
|
|
18948
|
+
view_type: "video_grid"
|
|
18949
|
+
});
|
|
18950
|
+
}, []);
|
|
18797
18951
|
return /* @__PURE__ */ jsx("div", { className: `relative overflow-hidden h-full w-full ${className}`, children: /* @__PURE__ */ jsx("div", { ref: containerRef, className: "h-full w-full p-2", children: /* @__PURE__ */ jsx(
|
|
18798
18952
|
"div",
|
|
18799
18953
|
{
|
|
@@ -18830,9 +18984,9 @@ var VideoGridView = React19__default.memo(({
|
|
|
18830
18984
|
{
|
|
18831
18985
|
workspace,
|
|
18832
18986
|
hlsUrl: getWorkspaceHlsUrl(workspace.workspace_name, workspace.line_id),
|
|
18833
|
-
shouldPlay: isVisible,
|
|
18987
|
+
shouldPlay: isVisible && !failedStreams.has(workspaceId),
|
|
18834
18988
|
onClick: () => handleWorkspaceClick(workspace),
|
|
18835
|
-
onFatalError:
|
|
18989
|
+
onFatalError: () => handleStreamError(workspaceId),
|
|
18836
18990
|
isVeryLowEfficiency,
|
|
18837
18991
|
cropping: workspaceCropping,
|
|
18838
18992
|
canvasFps: canvasConfig?.fps,
|
|
@@ -23999,7 +24153,7 @@ var WorkspaceGridItem = React19__default.memo(({
|
|
|
23999
24153
|
e.preventDefault();
|
|
24000
24154
|
if (isInactive) return;
|
|
24001
24155
|
const displayName = getWorkspaceDisplayName(data.workspace_name, data.line_id);
|
|
24002
|
-
const navParams = getWorkspaceNavigationParams(data.workspace_id, displayName);
|
|
24156
|
+
const navParams = getWorkspaceNavigationParams(data.workspace_id, displayName, data.line_id);
|
|
24003
24157
|
navigate(`/workspace/${data.workspace_id}${navParams}`, {
|
|
24004
24158
|
trackingEvent: {
|
|
24005
24159
|
name: "Workspace Detail Clicked",
|
|
@@ -28740,6 +28894,73 @@ function HomeView({
|
|
|
28740
28894
|
}
|
|
28741
28895
|
var AuthenticatedHomeView = withAuth(React19__default.memo(HomeView));
|
|
28742
28896
|
var HomeView_default = HomeView;
|
|
28897
|
+
function withWorkspaceDisplayNames(Component3, options = {}) {
|
|
28898
|
+
const {
|
|
28899
|
+
showLoading = true,
|
|
28900
|
+
loadingMessage = "Initializing workspace data...",
|
|
28901
|
+
initializeFor = "all"
|
|
28902
|
+
} = options;
|
|
28903
|
+
return function WithWorkspaceDisplayNamesWrapper(props) {
|
|
28904
|
+
const [isInitialized2, setIsInitialized] = useState(false);
|
|
28905
|
+
const [error, setError] = useState(null);
|
|
28906
|
+
useEffect(() => {
|
|
28907
|
+
setIsInitialized(false);
|
|
28908
|
+
setError(null);
|
|
28909
|
+
const initializeDisplayNames = async () => {
|
|
28910
|
+
try {
|
|
28911
|
+
const { lineIds, selectedLineId, factoryViewId } = props;
|
|
28912
|
+
let lineIdArray = [];
|
|
28913
|
+
if (Array.isArray(lineIds)) {
|
|
28914
|
+
lineIdArray = lineIds;
|
|
28915
|
+
} else if (lineIds && typeof lineIds === "object") {
|
|
28916
|
+
lineIdArray = Object.values(lineIds).filter((id3) => !!id3);
|
|
28917
|
+
}
|
|
28918
|
+
if (initializeFor === "specific" && selectedLineId) {
|
|
28919
|
+
if (selectedLineId === factoryViewId && lineIdArray.length > 0) {
|
|
28920
|
+
await Promise.all(
|
|
28921
|
+
lineIdArray.map((lineId) => preInitializeWorkspaceDisplayNames(lineId))
|
|
28922
|
+
);
|
|
28923
|
+
} else {
|
|
28924
|
+
await preInitializeWorkspaceDisplayNames(selectedLineId);
|
|
28925
|
+
}
|
|
28926
|
+
} else if (lineIdArray.length > 0) {
|
|
28927
|
+
await Promise.all(
|
|
28928
|
+
lineIdArray.map((lineId) => preInitializeWorkspaceDisplayNames(lineId))
|
|
28929
|
+
);
|
|
28930
|
+
} else {
|
|
28931
|
+
await preInitializeWorkspaceDisplayNames();
|
|
28932
|
+
}
|
|
28933
|
+
setIsInitialized(true);
|
|
28934
|
+
} catch (err) {
|
|
28935
|
+
console.error("Failed to initialize workspace display names:", err);
|
|
28936
|
+
setError(err);
|
|
28937
|
+
setIsInitialized(true);
|
|
28938
|
+
}
|
|
28939
|
+
};
|
|
28940
|
+
initializeDisplayNames();
|
|
28941
|
+
}, [
|
|
28942
|
+
Array.isArray(props.lineIds) ? props.lineIds.join(",") : JSON.stringify(props.lineIds),
|
|
28943
|
+
props.selectedLineId,
|
|
28944
|
+
props.factoryViewId,
|
|
28945
|
+
initializeFor
|
|
28946
|
+
]);
|
|
28947
|
+
if (!isInitialized2 && showLoading) {
|
|
28948
|
+
return /* @__PURE__ */ jsx(LoadingPage, { message: loadingMessage });
|
|
28949
|
+
}
|
|
28950
|
+
if (error && showLoading) {
|
|
28951
|
+
console.warn("Workspace display names initialization failed, proceeding anyway:", error);
|
|
28952
|
+
}
|
|
28953
|
+
return /* @__PURE__ */ jsx(Component3, { ...props });
|
|
28954
|
+
};
|
|
28955
|
+
}
|
|
28956
|
+
var withAllWorkspaceDisplayNames = (Component3) => withWorkspaceDisplayNames(Component3, {
|
|
28957
|
+
initializeFor: "all",
|
|
28958
|
+
showLoading: true
|
|
28959
|
+
});
|
|
28960
|
+
var withSelectedLineDisplayNames = (Component3) => withWorkspaceDisplayNames(Component3, {
|
|
28961
|
+
initializeFor: "specific",
|
|
28962
|
+
showLoading: true
|
|
28963
|
+
});
|
|
28743
28964
|
|
|
28744
28965
|
// src/views/kpi-detail-view.types.ts
|
|
28745
28966
|
var pageVariants = {
|
|
@@ -28800,11 +29021,6 @@ var itemVariants = {
|
|
|
28800
29021
|
}
|
|
28801
29022
|
}
|
|
28802
29023
|
};
|
|
28803
|
-
|
|
28804
|
-
// src/lib/utils/navigation.ts
|
|
28805
|
-
function getWorkspaceNavigationParams2(workspaceUuid, displayName) {
|
|
28806
|
-
return `?name=${encodeURIComponent(displayName || "")}`;
|
|
28807
|
-
}
|
|
28808
29024
|
var formatLocalDate = (date) => {
|
|
28809
29025
|
const options = {
|
|
28810
29026
|
year: "numeric",
|
|
@@ -28920,7 +29136,7 @@ var BottomSection = memo(({
|
|
|
28920
29136
|
}
|
|
28921
29137
|
const clickHandler = () => handleWorkspaceClick(ws, index);
|
|
28922
29138
|
const displayName = getWorkspaceDisplayName(ws.workspace_name, lineId);
|
|
28923
|
-
const navParams = wsUuid ?
|
|
29139
|
+
const navParams = wsUuid ? getWorkspaceNavigationParams(wsUuid, displayName, lineId) : "";
|
|
28924
29140
|
const dateShiftParams = urlDate ? `&date=${urlDate}&shift=${urlShift || "0"}` : "";
|
|
28925
29141
|
const returnToParam = `&returnTo=${encodeURIComponent(`/kpis/${lineInfo?.line_id}`)}`;
|
|
28926
29142
|
const fullUrl = `/workspace/${wsUuid}${navParams}${dateShiftParams}${returnToParam}`;
|
|
@@ -28954,7 +29170,7 @@ var BottomSection = memo(({
|
|
|
28954
29170
|
sortedByEfficiency.map((ws, index) => {
|
|
28955
29171
|
const clickHandler = () => handleWorkspaceClick(ws, index);
|
|
28956
29172
|
const displayName = getWorkspaceDisplayName(ws.workspace_name, lineId);
|
|
28957
|
-
const navParams = ws.workspace_uuid ?
|
|
29173
|
+
const navParams = ws.workspace_uuid ? getWorkspaceNavigationParams(ws.workspace_uuid, displayName, lineId) : "";
|
|
28958
29174
|
const dateShiftParams = urlDate ? `&date=${urlDate}&shift=${urlShift || "0"}` : "";
|
|
28959
29175
|
const returnToParam = `&returnTo=${encodeURIComponent(`/kpis/${lineInfo?.line_id}`)}`;
|
|
28960
29176
|
const fullUrl = `/workspace/${ws.workspace_uuid}${navParams}${dateShiftParams}${returnToParam}`;
|
|
@@ -29569,7 +29785,8 @@ var KPIDetailView = ({
|
|
|
29569
29785
|
) }) })
|
|
29570
29786
|
] });
|
|
29571
29787
|
};
|
|
29572
|
-
var
|
|
29788
|
+
var KPIDetailViewWithDisplayNames = withSelectedLineDisplayNames(KPIDetailView);
|
|
29789
|
+
var KPIDetailView_default = KPIDetailViewWithDisplayNames;
|
|
29573
29790
|
var LineCard = ({ line, onClick }) => {
|
|
29574
29791
|
const { kpis, isLoading, error } = useLineKPIs({ lineId: line.id });
|
|
29575
29792
|
const isOnTrack = React19__default.useMemo(() => {
|
|
@@ -30059,7 +30276,7 @@ var LeaderboardDetailView = memo(({
|
|
|
30059
30276
|
action_threshold: workspace.action_threshold
|
|
30060
30277
|
});
|
|
30061
30278
|
const displayName = getWorkspaceDisplayName(workspace.workspace_name, workspace.line_id);
|
|
30062
|
-
const navParams = workspace.workspace_uuid ? getWorkspaceNavigationParams(workspace.workspace_uuid, displayName) : "";
|
|
30279
|
+
const navParams = workspace.workspace_uuid ? getWorkspaceNavigationParams(workspace.workspace_uuid, displayName, workspace.line_id) : "";
|
|
30063
30280
|
const returnToParam = `&returnTo=${encodeURIComponent(`/leaderboard`)}`;
|
|
30064
30281
|
if (onWorkspaceClick) {
|
|
30065
30282
|
onWorkspaceClick(workspace, rank);
|
|
@@ -30193,7 +30410,8 @@ var LeaderboardDetailView = memo(({
|
|
|
30193
30410
|
return prevProps.lineId === nextProps.lineId && prevProps.date === nextProps.date && prevProps.shift === nextProps.shift && prevProps.line1Id === nextProps.line1Id && prevProps.line2Id === nextProps.line2Id && JSON.stringify(prevProps.lineNames) === JSON.stringify(nextProps.lineNames) && prevProps.className === nextProps.className && prevProps.onBackClick === nextProps.onBackClick && prevProps.onWorkspaceClick === nextProps.onWorkspaceClick;
|
|
30194
30411
|
});
|
|
30195
30412
|
LeaderboardDetailView.displayName = "LeaderboardDetailView";
|
|
30196
|
-
var
|
|
30413
|
+
var LeaderboardDetailViewWithDisplayNames = withAllWorkspaceDisplayNames(LeaderboardDetailView);
|
|
30414
|
+
var LeaderboardDetailView_default = LeaderboardDetailViewWithDisplayNames;
|
|
30197
30415
|
function LoginView({
|
|
30198
30416
|
logoSrc = "/optifye-logo.png",
|
|
30199
30417
|
logoAlt = "Optifye",
|
|
@@ -32313,7 +32531,12 @@ var TargetsView = ({
|
|
|
32313
32531
|
}
|
|
32314
32532
|
}), {});
|
|
32315
32533
|
}, [lineIds]);
|
|
32316
|
-
const [
|
|
32534
|
+
const [allShiftsData, setAllShiftsData] = useState({
|
|
32535
|
+
0: initialLineWorkspaces,
|
|
32536
|
+
// Day shift
|
|
32537
|
+
1: initialLineWorkspaces
|
|
32538
|
+
// Night shift (will be populated on first load)
|
|
32539
|
+
});
|
|
32317
32540
|
const [actionIds, setActionIds] = useState(null);
|
|
32318
32541
|
const [savingLines, setSavingLines] = useState(
|
|
32319
32542
|
() => lineIds.reduce((acc, id3) => ({ ...acc, [id3]: false }), {})
|
|
@@ -32325,6 +32548,13 @@ var TargetsView = ({
|
|
|
32325
32548
|
const [isBulkConfigureOpen, setIsBulkConfigureOpen] = useState(false);
|
|
32326
32549
|
const [selectedWorkspaces, setSelectedWorkspaces] = useState([]);
|
|
32327
32550
|
const [selectedShift, setSelectedShift] = useState(0);
|
|
32551
|
+
const lineWorkspaces = allShiftsData[selectedShift] || initialLineWorkspaces;
|
|
32552
|
+
const setLineWorkspaces = useCallback((updater) => {
|
|
32553
|
+
setAllShiftsData((prev) => ({
|
|
32554
|
+
...prev,
|
|
32555
|
+
[selectedShift]: typeof updater === "function" ? updater(prev[selectedShift]) : updater
|
|
32556
|
+
}));
|
|
32557
|
+
}, [selectedShift]);
|
|
32328
32558
|
const supabase = useSupabase();
|
|
32329
32559
|
const auth = useAuth();
|
|
32330
32560
|
userId || auth?.user?.id;
|
|
@@ -32395,7 +32625,7 @@ var TargetsView = ({
|
|
|
32395
32625
|
};
|
|
32396
32626
|
fetchActions();
|
|
32397
32627
|
}, [supabase, companyId]);
|
|
32398
|
-
|
|
32628
|
+
useCallback(async (shiftId) => {
|
|
32399
32629
|
try {
|
|
32400
32630
|
if (!supabase) return;
|
|
32401
32631
|
const currentDate = getOperationalDate();
|
|
@@ -32463,15 +32693,7 @@ var TargetsView = ({
|
|
|
32463
32693
|
shiftEndTime: endTime,
|
|
32464
32694
|
breaks,
|
|
32465
32695
|
shiftHours: Number(shiftHours),
|
|
32466
|
-
workspaces:
|
|
32467
|
-
...ws,
|
|
32468
|
-
targetPPH: ws.targetCycleTime !== "" ? calculatePPH(ws.targetCycleTime, breaks, Number(shiftHours)) : ws.targetPPH,
|
|
32469
|
-
targetDayOutput: calculateDayOutput(
|
|
32470
|
-
ws.targetCycleTime !== "" ? calculatePPH(ws.targetCycleTime, breaks, Number(shiftHours)) : ws.targetPPH,
|
|
32471
|
-
Number(shiftHours),
|
|
32472
|
-
breaks
|
|
32473
|
-
)
|
|
32474
|
-
}))
|
|
32696
|
+
workspaces: currentLineStateFromLoop?.workspaces || []
|
|
32475
32697
|
};
|
|
32476
32698
|
hasUpdates = true;
|
|
32477
32699
|
}
|
|
@@ -32485,7 +32707,71 @@ var TargetsView = ({
|
|
|
32485
32707
|
} catch (error) {
|
|
32486
32708
|
console.error("Error in fetchLineThresholds outer try-catch:", error);
|
|
32487
32709
|
}
|
|
32488
|
-
}, [selectedShift, supabase, lineIds, lineWorkspaces]);
|
|
32710
|
+
}, [selectedShift, supabase, lineIds, lineWorkspaces, allShiftsData]);
|
|
32711
|
+
const fetchAllShiftsData = useCallback(async (currentWorkspaces) => {
|
|
32712
|
+
if (!supabase) return;
|
|
32713
|
+
const currentDate = getOperationalDate();
|
|
32714
|
+
const newAllShiftsData = {
|
|
32715
|
+
0: JSON.parse(JSON.stringify(currentWorkspaces)),
|
|
32716
|
+
// Deep clone for day shift
|
|
32717
|
+
1: JSON.parse(JSON.stringify(currentWorkspaces))
|
|
32718
|
+
// Deep clone for night shift
|
|
32719
|
+
};
|
|
32720
|
+
for (const shiftId of [0, 1]) {
|
|
32721
|
+
for (const lineId of lineIds) {
|
|
32722
|
+
try {
|
|
32723
|
+
const { data: operatingHours, error: hoursError } = await supabase.from("line_operating_hours").select("start_time, end_time, breaks").eq("line_id", lineId).eq("shift_id", shiftId).maybeSingle();
|
|
32724
|
+
if (hoursError) {
|
|
32725
|
+
console.error(`Error fetching operating hours for line ${lineId}, shift ${shiftId}:`, hoursError);
|
|
32726
|
+
continue;
|
|
32727
|
+
}
|
|
32728
|
+
let breaks = [];
|
|
32729
|
+
if (operatingHours?.breaks) {
|
|
32730
|
+
if (Array.isArray(operatingHours.breaks)) {
|
|
32731
|
+
breaks = operatingHours.breaks.map((breakItem) => ({
|
|
32732
|
+
startTime: breakItem.start || breakItem.startTime || "00:00",
|
|
32733
|
+
endTime: breakItem.end || breakItem.endTime || "00:00",
|
|
32734
|
+
duration: breakItem.duration || calculateShiftHours2(breakItem.start || breakItem.startTime || "00:00", breakItem.end || breakItem.endTime || "00:00", []) * 60
|
|
32735
|
+
}));
|
|
32736
|
+
}
|
|
32737
|
+
}
|
|
32738
|
+
const startTime = operatingHours?.start_time || "08:00";
|
|
32739
|
+
const endTime = operatingHours?.end_time || "19:00";
|
|
32740
|
+
const shiftHours = calculateShiftHours2(startTime, endTime, breaks);
|
|
32741
|
+
const actionThresholds = await workspaceService.getActionThresholds(
|
|
32742
|
+
lineId,
|
|
32743
|
+
currentDate,
|
|
32744
|
+
shiftId
|
|
32745
|
+
);
|
|
32746
|
+
const existingLine = newAllShiftsData[shiftId][lineId];
|
|
32747
|
+
if (existingLine) {
|
|
32748
|
+
newAllShiftsData[shiftId][lineId] = {
|
|
32749
|
+
...existingLine,
|
|
32750
|
+
shiftStartTime: startTime,
|
|
32751
|
+
shiftEndTime: endTime,
|
|
32752
|
+
breaks,
|
|
32753
|
+
shiftHours: Number(shiftHours),
|
|
32754
|
+
workspaces: existingLine.workspaces.map((ws) => {
|
|
32755
|
+
const threshold = actionThresholds.find((t) => t.workspace_id === ws.id);
|
|
32756
|
+
if (threshold) {
|
|
32757
|
+
return {
|
|
32758
|
+
...ws,
|
|
32759
|
+
targetPPH: threshold.pph_threshold,
|
|
32760
|
+
targetCycleTime: threshold.ideal_cycle_time,
|
|
32761
|
+
targetDayOutput: threshold.total_day_output
|
|
32762
|
+
};
|
|
32763
|
+
}
|
|
32764
|
+
return ws;
|
|
32765
|
+
})
|
|
32766
|
+
};
|
|
32767
|
+
}
|
|
32768
|
+
} catch (error) {
|
|
32769
|
+
console.error(`Error fetching data for line ${lineId}, shift ${shiftId}:`, error);
|
|
32770
|
+
}
|
|
32771
|
+
}
|
|
32772
|
+
}
|
|
32773
|
+
setAllShiftsData(newAllShiftsData);
|
|
32774
|
+
}, [supabase, lineIds]);
|
|
32489
32775
|
const loadOperatingHours = useCallback(async (lineId, shiftId) => {
|
|
32490
32776
|
try {
|
|
32491
32777
|
if (!supabase) return null;
|
|
@@ -32590,7 +32876,7 @@ var TargetsView = ({
|
|
|
32590
32876
|
(line) => line.workspaces && line.workspaces.length > 0
|
|
32591
32877
|
);
|
|
32592
32878
|
if (workspacesAlreadyLoadedForAnyLine) {
|
|
32593
|
-
|
|
32879
|
+
setIsLoading(false);
|
|
32594
32880
|
return;
|
|
32595
32881
|
}
|
|
32596
32882
|
const fetchWorkspacesAndThenThresholds = async () => {
|
|
@@ -32611,7 +32897,7 @@ var TargetsView = ({
|
|
|
32611
32897
|
}
|
|
32612
32898
|
try {
|
|
32613
32899
|
const fetchedLineWorkspacesData = await workspaceService.getWorkspaces(lineId);
|
|
32614
|
-
|
|
32900
|
+
let mappedWorkspaces = fetchedLineWorkspacesData.map((ws) => ({
|
|
32615
32901
|
id: ws.id,
|
|
32616
32902
|
name: ws.workspace_id,
|
|
32617
32903
|
targetPPH: ws.action_pph_threshold === null ? "" : ws.action_pph_threshold,
|
|
@@ -32620,6 +32906,29 @@ var TargetsView = ({
|
|
|
32620
32906
|
actionType: ws.action_id === actionIds.assembly ? "assembly" : ws.action_id === actionIds.packaging ? "packaging" : "assembly",
|
|
32621
32907
|
actionId: ws.action_id === actionIds.assembly ? actionIds.assembly : ws.action_id === actionIds.packaging ? actionIds.packaging : actionIds.assembly
|
|
32622
32908
|
})).sort((a, b) => a.name.localeCompare(b.name, void 0, { numeric: true }));
|
|
32909
|
+
const currentDate = getOperationalDate();
|
|
32910
|
+
try {
|
|
32911
|
+
const actionThresholds = await workspaceService.getActionThresholds(
|
|
32912
|
+
lineId,
|
|
32913
|
+
currentDate,
|
|
32914
|
+
selectedShift
|
|
32915
|
+
);
|
|
32916
|
+
mappedWorkspaces = mappedWorkspaces.map((ws) => {
|
|
32917
|
+
const threshold = actionThresholds.find((t) => t.workspace_id === ws.id);
|
|
32918
|
+
if (threshold) {
|
|
32919
|
+
return {
|
|
32920
|
+
...ws,
|
|
32921
|
+
targetPPH: threshold.pph_threshold,
|
|
32922
|
+
targetCycleTime: threshold.ideal_cycle_time,
|
|
32923
|
+
targetDayOutput: threshold.total_day_output
|
|
32924
|
+
};
|
|
32925
|
+
}
|
|
32926
|
+
return ws;
|
|
32927
|
+
});
|
|
32928
|
+
console.log(`Merged action thresholds for line ${lineId}, found ${actionThresholds.length} saved thresholds`);
|
|
32929
|
+
} catch (error) {
|
|
32930
|
+
console.error(`Error fetching action thresholds for line ${lineId}:`, error);
|
|
32931
|
+
}
|
|
32623
32932
|
if (JSON.stringify(mappedWorkspaces) !== JSON.stringify(newUpdatedLineWorkspaces[lineId].workspaces)) {
|
|
32624
32933
|
newUpdatedLineWorkspaces[lineId] = {
|
|
32625
32934
|
...newUpdatedLineWorkspaces[lineId],
|
|
@@ -32634,7 +32943,7 @@ var TargetsView = ({
|
|
|
32634
32943
|
if (workspacesHaveBeenUpdated) {
|
|
32635
32944
|
setLineWorkspaces(newUpdatedLineWorkspaces);
|
|
32636
32945
|
}
|
|
32637
|
-
await
|
|
32946
|
+
await fetchAllShiftsData(newUpdatedLineWorkspaces);
|
|
32638
32947
|
} catch (error) {
|
|
32639
32948
|
console.error("Error in fetchWorkspacesAndThenThresholds:", error);
|
|
32640
32949
|
toast.error("Failed to load workspace data");
|
|
@@ -32643,37 +32952,7 @@ var TargetsView = ({
|
|
|
32643
32952
|
}
|
|
32644
32953
|
};
|
|
32645
32954
|
fetchWorkspacesAndThenThresholds();
|
|
32646
|
-
}, [actionIds, supabase, lineIds
|
|
32647
|
-
useEffect(() => {
|
|
32648
|
-
if (Object.keys(lineWorkspaces).length > 0) {
|
|
32649
|
-
const updatedLineWorkspaces = { ...lineWorkspaces };
|
|
32650
|
-
let hasChanges = false;
|
|
32651
|
-
Object.keys(updatedLineWorkspaces).forEach((lineId) => {
|
|
32652
|
-
const line = updatedLineWorkspaces[lineId];
|
|
32653
|
-
const shiftHours = calculateShiftHours2(line.shiftStartTime, line.shiftEndTime, line.breaks);
|
|
32654
|
-
if (shiftHours !== line.shiftHours) {
|
|
32655
|
-
hasChanges = true;
|
|
32656
|
-
updatedLineWorkspaces[lineId] = {
|
|
32657
|
-
...line,
|
|
32658
|
-
shiftHours,
|
|
32659
|
-
workspaces: line.workspaces.map((ws) => {
|
|
32660
|
-
const targetDayOutput = calculateDayOutput(ws.targetPPH, shiftHours, line.breaks);
|
|
32661
|
-
if (targetDayOutput !== ws.targetDayOutput) {
|
|
32662
|
-
return {
|
|
32663
|
-
...ws,
|
|
32664
|
-
targetDayOutput
|
|
32665
|
-
};
|
|
32666
|
-
}
|
|
32667
|
-
return ws;
|
|
32668
|
-
})
|
|
32669
|
-
};
|
|
32670
|
-
}
|
|
32671
|
-
});
|
|
32672
|
-
if (hasChanges) {
|
|
32673
|
-
setLineWorkspaces(updatedLineWorkspaces);
|
|
32674
|
-
}
|
|
32675
|
-
}
|
|
32676
|
-
}, [selectedShift]);
|
|
32955
|
+
}, [actionIds, supabase, lineIds]);
|
|
32677
32956
|
const toggleLineDropdown = useCallback((lineId) => {
|
|
32678
32957
|
setLineWorkspaces((prev) => {
|
|
32679
32958
|
const newIsOpen = !prev[lineId].isOpen;
|
|
@@ -32757,6 +33036,16 @@ var TargetsView = ({
|
|
|
32757
33036
|
updates.targetDayOutput = calculateDayOutput(value, shiftHours, prev[lineId].breaks);
|
|
32758
33037
|
} else if (field === "targetDayOutput") {
|
|
32759
33038
|
updates.targetDayOutput = value;
|
|
33039
|
+
if (value !== "") {
|
|
33040
|
+
const breaks = prev[lineId].breaks;
|
|
33041
|
+
const totalBreakMinutes = breaks.reduce((total, b) => total + b.duration, 0);
|
|
33042
|
+
const totalBreakHours = totalBreakMinutes / 60;
|
|
33043
|
+
const realWorkHours = shiftHours - totalBreakHours;
|
|
33044
|
+
const calculatedPPH = Math.round(value / realWorkHours);
|
|
33045
|
+
updates.targetPPH = calculatedPPH;
|
|
33046
|
+
} else {
|
|
33047
|
+
updates.targetPPH = "";
|
|
33048
|
+
}
|
|
32760
33049
|
}
|
|
32761
33050
|
updates[field] = value;
|
|
32762
33051
|
return updates;
|
|
@@ -33018,8 +33307,9 @@ var TargetsView = ({
|
|
|
33018
33307
|
}
|
|
33019
33308
|
);
|
|
33020
33309
|
};
|
|
33021
|
-
var
|
|
33022
|
-
var
|
|
33310
|
+
var TargetsViewWithDisplayNames = withAllWorkspaceDisplayNames(TargetsView);
|
|
33311
|
+
var TargetsView_default = TargetsViewWithDisplayNames;
|
|
33312
|
+
var AuthenticatedTargetsView = withAuth(TargetsViewWithDisplayNames);
|
|
33023
33313
|
|
|
33024
33314
|
// src/views/workspace-detail-view.utils.ts
|
|
33025
33315
|
var formatISTDate2 = (date = /* @__PURE__ */ new Date(), options) => {
|
|
@@ -33035,8 +33325,8 @@ var formatISTDate2 = (date = /* @__PURE__ */ new Date(), options) => {
|
|
|
33035
33325
|
});
|
|
33036
33326
|
return formatter.format(date);
|
|
33037
33327
|
};
|
|
33038
|
-
var formatWorkspaceName3 = (name) => {
|
|
33039
|
-
return getWorkspaceDisplayName(name);
|
|
33328
|
+
var formatWorkspaceName3 = (name, lineId) => {
|
|
33329
|
+
return getWorkspaceDisplayName(name, lineId);
|
|
33040
33330
|
};
|
|
33041
33331
|
var getDaysDifference = (date) => {
|
|
33042
33332
|
const today = /* @__PURE__ */ new Date();
|
|
@@ -33073,9 +33363,11 @@ var WorkspaceDetailView = ({
|
|
|
33073
33363
|
fromMonthly = false,
|
|
33074
33364
|
sourceType,
|
|
33075
33365
|
displayName,
|
|
33366
|
+
lineId,
|
|
33076
33367
|
defaultTab,
|
|
33077
33368
|
returnUrl,
|
|
33078
33369
|
lineIds = { line1: "", line2: "" },
|
|
33370
|
+
selectedLineId,
|
|
33079
33371
|
onNavigate,
|
|
33080
33372
|
onTabChange,
|
|
33081
33373
|
onDateSelect,
|
|
@@ -33238,7 +33530,8 @@ var WorkspaceDetailView = ({
|
|
|
33238
33530
|
setSelectedMonth(newMonth);
|
|
33239
33531
|
setSelectedYear(newYear);
|
|
33240
33532
|
};
|
|
33241
|
-
const
|
|
33533
|
+
const effectiveLineId = lineId || selectedLineId;
|
|
33534
|
+
const formattedWorkspaceName = displayName || formatWorkspaceName3(workspace?.workspace_name || "", effectiveLineId);
|
|
33242
33535
|
const shouldShowCycleTimeChart = showCycleTimeChart ?? formattedWorkspaceName.startsWith("FINAL ASSY");
|
|
33243
33536
|
const handleBackNavigation = () => {
|
|
33244
33537
|
if (returnUrl) {
|
|
@@ -33250,13 +33543,23 @@ var WorkspaceDetailView = ({
|
|
|
33250
33543
|
if (date || shift) {
|
|
33251
33544
|
setActiveTab("monthly_history");
|
|
33252
33545
|
if (onNavigate) {
|
|
33253
|
-
|
|
33546
|
+
const params = new URLSearchParams();
|
|
33547
|
+
params.set("fromMonthly", "true");
|
|
33548
|
+
if (effectiveLineId) {
|
|
33549
|
+
params.set("lineId", effectiveLineId);
|
|
33550
|
+
}
|
|
33551
|
+
onNavigate(`/workspace/${workspaceId}?${params.toString()}`);
|
|
33254
33552
|
}
|
|
33255
33553
|
} else {
|
|
33256
33554
|
if (previousView === "line_monthly_history") {
|
|
33257
33555
|
setActiveTab("monthly_history");
|
|
33258
33556
|
if (onNavigate) {
|
|
33259
|
-
|
|
33557
|
+
const params = new URLSearchParams();
|
|
33558
|
+
params.set("fromMonthly", "true");
|
|
33559
|
+
if (effectiveLineId) {
|
|
33560
|
+
params.set("lineId", effectiveLineId);
|
|
33561
|
+
}
|
|
33562
|
+
onNavigate(`/workspace/${workspaceId}?${params.toString()}`);
|
|
33260
33563
|
}
|
|
33261
33564
|
} else {
|
|
33262
33565
|
if (onNavigate) {
|
|
@@ -33714,7 +34017,13 @@ var WorkspaceDetailView = ({
|
|
|
33714
34017
|
if (onDateSelect) {
|
|
33715
34018
|
onDateSelect(selectedDate, selectedShift);
|
|
33716
34019
|
} else if (onNavigate) {
|
|
33717
|
-
|
|
34020
|
+
const params = new URLSearchParams();
|
|
34021
|
+
params.set("date", selectedDate);
|
|
34022
|
+
params.set("shift", selectedShift === "day" ? "0" : "1");
|
|
34023
|
+
if (effectiveLineId) {
|
|
34024
|
+
params.set("lineId", effectiveLineId);
|
|
34025
|
+
}
|
|
34026
|
+
onNavigate(`/workspace/${workspaceId}?${params.toString()}`);
|
|
33718
34027
|
}
|
|
33719
34028
|
},
|
|
33720
34029
|
onMonthNavigate: (newMonth, newYear) => {
|
|
@@ -33741,7 +34050,12 @@ var WorkspaceDetailView = ({
|
|
|
33741
34050
|
}
|
|
33742
34051
|
);
|
|
33743
34052
|
};
|
|
33744
|
-
var
|
|
34053
|
+
var WorkspaceDetailViewWithDisplayNames = withSelectedLineDisplayNames(WorkspaceDetailView);
|
|
34054
|
+
var WorkspaceDetailViewFinal = (props) => {
|
|
34055
|
+
const componentKey = `${props.date || "live"}_${props.shift || "current"}`;
|
|
34056
|
+
return /* @__PURE__ */ jsx(WorkspaceDetailViewWithDisplayNames, { ...props }, componentKey);
|
|
34057
|
+
};
|
|
34058
|
+
var WrappedComponent = withAuth(WorkspaceDetailViewFinal);
|
|
33745
34059
|
var WorkspaceDetailView_default = WrappedComponent;
|
|
33746
34060
|
var SKUManagementView = () => {
|
|
33747
34061
|
const config = useDashboardConfig();
|
|
@@ -34119,4 +34433,4 @@ var S3Service = class {
|
|
|
34119
34433
|
}
|
|
34120
34434
|
};
|
|
34121
34435
|
|
|
34122
|
-
export { ACTION_NAMES, AIAgentView_default as AIAgentView, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedTargetsView, BarChart, BaseHistoryCalendar, BottlenecksContent, BreakNotificationPopup, Card2 as Card, CardContent2 as CardContent, CardDescription2 as CardDescription, CardFooter2 as CardFooter, CardHeader2 as CardHeader, CardTitle2 as CardTitle, 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, FactoryView_default as FactoryView, GaugeChart, GridComponentsPlaceholder, 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, 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, SlackAPI, SubscriptionManager, SubscriptionManagerProvider, SupabaseProvider, TargetWorkspaceGrid, TargetsView_default as TargetsView, ThreadSidebar, TimeDisplay_default as TimeDisplay, TimePickerDropdown, VideoCard, VideoGridView, VideoPreloader, WORKSPACE_POSITIONS, WhatsAppShareButton, WorkspaceCard, WorkspaceDetailView_default as WorkspaceDetailView, WorkspaceDisplayNameExample, WorkspaceGrid, WorkspaceGridItem, WorkspaceHistoryCalendar, WorkspaceMetricCards, WorkspaceMonthlyDataFetcher, WorkspaceMonthlyPdfGenerator, WorkspacePdfExportButton, WorkspacePdfGenerator, WorkspaceWhatsAppShareButton, actionService, apiUtils, authCoreService, authOTPService, authRateLimitService, cacheService, checkRateLimit2 as checkRateLimit, clearAllRateLimits2 as clearAllRateLimits, clearRateLimit2 as clearRateLimit, clearS3VideoCache, clearS3VideoFromCache, clearWorkspaceDisplayNamesCache, cn, createStreamProxyHandler, createSupabaseClient, createThrottledReload, dashboardService, deleteThread, forceRefreshWorkspaceDisplayNames, formatDateInZone, formatDateTimeInZone, formatISTDate, formatIdleTime, formatTimeInZone, fromUrlFriendlyName, getAllLineDisplayNames, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAnonClient, getCameraNumber, getCompanyMetricsTableName, getConfigurableShortWorkspaceDisplayName, getConfigurableWorkspaceDisplayName, getConfiguredLineIds, getCoreSessionRecordingProperties, getCoreSessionReplayUrl, getCurrentShift, getCurrentTimeInZone, getDashboardHeaderTimeInZone, getDaysDifferenceInZone, getDefaultCameraStreamUrl, getDefaultLineId, getDefaultTabForWorkspace, getLineDisplayName, getManufacturingInsights, getMetricsTablePrefix, getOperationalDate, getS3SignedUrl, getS3VideoSrc, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getSubscriptionManager, getThreadMessages, getUserThreads, getUserThreadsPaginated, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, identifyCoreUser, initializeCoreMixpanel, isLegacyConfiguration, isTransitionPeriod, isValidFactoryViewConfiguration, isValidLineInfoPayload, isValidWorkspaceDetailedMetricsPayload, isValidWorkspaceMetricsPayload, isWorkspaceDisplayNamesLoaded, isWorkspaceDisplayNamesLoading, mergeWithDefaultConfig, migrateLegacyConfiguration, optifyeAgentClient, preInitializeWorkspaceDisplayNames, preloadS3Video, preloadS3VideoUrl, preloadS3VideosUrl, preloadVideoUrl, preloadVideosUrl, qualityService, realtimeService, refreshWorkspaceDisplayNames, resetCoreMixpanel, resetSubscriptionManager, s3VideoPreloader, skuService, startCoreSessionRecording, stopCoreSessionRecording, storeWorkspaceMapping, streamProxyConfig, throttledReloadDashboard, toUrlFriendlyName, trackCoreEvent, trackCorePageView, updateThreadTitle, useActiveBreaks, useAllWorkspaceMetrics, useAnalyticsConfig, useAuth, useAuthConfig, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHistoricWorkspaceMetrics, useHlsStream, useHlsStreamWithCropping, useHookOverride, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineWorkspaceMetrics, useMessages, useMetrics, useNavigation, useOverrides, usePageOverride, useRealtimeLineMetrics, useRegistry, useSKUs, useShiftConfig, useShifts, useSubscriptionManager, useSubscriptionManagerSafe, useSupabase, useSupabaseClient, useTargets, useTheme, useThemeConfig, useThreads, useVideoConfig, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, videoPreloader, whatsappService, withAuth, withRegistry, workspaceService };
|
|
34436
|
+
export { ACTION_NAMES, AIAgentView_default as AIAgentView, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedTargetsView, BarChart, BaseHistoryCalendar, BottlenecksContent, BreakNotificationPopup, Card2 as Card, CardContent2 as CardContent, CardDescription2 as CardDescription, CardFooter2 as CardFooter, CardHeader2 as CardHeader, CardTitle2 as CardTitle, 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, FactoryView_default as FactoryView, GaugeChart, GridComponentsPlaceholder, 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, 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, SlackAPI, SubscriptionManager, SubscriptionManagerProvider, SupabaseProvider, TargetWorkspaceGrid, TargetsView_default as TargetsView, ThreadSidebar, TimeDisplay_default as TimeDisplay, TimePickerDropdown, VideoCard, VideoGridView, VideoPreloader, WORKSPACE_POSITIONS, WhatsAppShareButton, WorkspaceCard, WorkspaceDetailView_default as WorkspaceDetailView, WorkspaceDisplayNameExample, WorkspaceGrid, WorkspaceGridItem, WorkspaceHistoryCalendar, WorkspaceMetricCards, WorkspaceMonthlyDataFetcher, WorkspaceMonthlyPdfGenerator, WorkspacePdfExportButton, WorkspacePdfGenerator, WorkspaceWhatsAppShareButton, actionService, apiUtils, authCoreService, authOTPService, authRateLimitService, cacheService, checkRateLimit2 as checkRateLimit, clearAllRateLimits2 as clearAllRateLimits, clearRateLimit2 as clearRateLimit, clearS3VideoCache, clearS3VideoFromCache, clearWorkspaceDisplayNamesCache, cn, createStreamProxyHandler, createSupabaseClient, createThrottledReload, dashboardService, deleteThread, forceRefreshWorkspaceDisplayNames, formatDateInZone, formatDateTimeInZone, formatISTDate, formatIdleTime, formatTimeInZone, fromUrlFriendlyName, getAllLineDisplayNames, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAnonClient, getCameraNumber, getCompanyMetricsTableName, getConfigurableShortWorkspaceDisplayName, getConfigurableWorkspaceDisplayName, getConfiguredLineIds, getCoreSessionRecordingProperties, getCoreSessionReplayUrl, getCurrentShift, getCurrentTimeInZone, getDashboardHeaderTimeInZone, getDaysDifferenceInZone, getDefaultCameraStreamUrl, getDefaultLineId, getDefaultTabForWorkspace, getLineDisplayName, getManufacturingInsights, getMetricsTablePrefix, getOperationalDate, getS3SignedUrl, getS3VideoSrc, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getSubscriptionManager, getThreadMessages, getUserThreads, getUserThreadsPaginated, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, identifyCoreUser, initializeCoreMixpanel, isLegacyConfiguration, isTransitionPeriod, isUrlPermanentlyFailed, isValidFactoryViewConfiguration, isValidLineInfoPayload, 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, useAuth, useAuthConfig, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHistoricWorkspaceMetrics, useHlsStream, useHlsStreamWithCropping, useHookOverride, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineWorkspaceMetrics, useMessages, useMetrics, useNavigation, useOverrides, usePageOverride, useRealtimeLineMetrics, useRegistry, useSKUs, useShiftConfig, useShifts, useSubscriptionManager, useSubscriptionManagerSafe, useSupabase, useSupabaseClient, useTargets, useTheme, useThemeConfig, useThreads, useVideoConfig, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, videoPreloader, whatsappService, withAuth, withRegistry, workspaceService };
|