@optifye/dashboard-core 6.11.32 → 6.11.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.css +7 -0
- package/dist/index.d.mts +16 -3
- package/dist/index.d.ts +16 -3
- package/dist/index.js +3091 -2720
- package/dist/index.mjs +1026 -657
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import
|
|
1
|
+
import * as React143 from 'react';
|
|
2
|
+
import React143__default, { createContext, useRef, useCallback, useState, useMemo, useEffect, forwardRef, useImperativeHandle, useLayoutEffect, memo as memo$1, useContext, useSyncExternalStore, useId, Children, isValidElement, useInsertionEffect, startTransition, Fragment as Fragment$1, createElement, Component } from 'react';
|
|
3
3
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
4
4
|
import { useRouter } from 'next/router';
|
|
5
5
|
import { toast } from 'sonner';
|
|
@@ -1938,14 +1938,14 @@ var useIdleTimeVlmConfig = () => {
|
|
|
1938
1938
|
}
|
|
1939
1939
|
return context;
|
|
1940
1940
|
};
|
|
1941
|
-
var DashboardConfigContext =
|
|
1941
|
+
var DashboardConfigContext = React143.createContext(void 0);
|
|
1942
1942
|
var DashboardProvider = ({ config: userProvidedConfig, children }) => {
|
|
1943
|
-
const fullConfig =
|
|
1943
|
+
const fullConfig = React143.useMemo(() => mergeWithDefaultConfig(userProvidedConfig), [userProvidedConfig]);
|
|
1944
1944
|
_setDashboardConfigInstance(fullConfig);
|
|
1945
|
-
|
|
1945
|
+
React143.useEffect(() => {
|
|
1946
1946
|
_setDashboardConfigInstance(fullConfig);
|
|
1947
1947
|
}, [fullConfig]);
|
|
1948
|
-
|
|
1948
|
+
React143.useEffect(() => {
|
|
1949
1949
|
if (!fullConfig.theme) return;
|
|
1950
1950
|
const styleId = "dashboard-core-theme-vars";
|
|
1951
1951
|
let styleEl = document.getElementById(styleId);
|
|
@@ -1971,7 +1971,7 @@ var DashboardProvider = ({ config: userProvidedConfig, children }) => {
|
|
|
1971
1971
|
return /* @__PURE__ */ jsx(DashboardConfigContext.Provider, { value: fullConfig, children: /* @__PURE__ */ jsx(IdleTimeVlmConfigProvider, { children }) });
|
|
1972
1972
|
};
|
|
1973
1973
|
var useDashboardConfig = () => {
|
|
1974
|
-
const ctx =
|
|
1974
|
+
const ctx = React143.useContext(DashboardConfigContext);
|
|
1975
1975
|
if (!ctx) throw new Error("useDashboardConfig must be used within a DashboardProvider");
|
|
1976
1976
|
return ctx;
|
|
1977
1977
|
};
|
|
@@ -2444,6 +2444,107 @@ var _getSupabaseInstanceOptional = () => {
|
|
|
2444
2444
|
return supabaseInstance;
|
|
2445
2445
|
};
|
|
2446
2446
|
|
|
2447
|
+
// src/lib/utils/sentryContext.ts
|
|
2448
|
+
function getSentry() {
|
|
2449
|
+
try {
|
|
2450
|
+
return __require("@sentry/nextjs");
|
|
2451
|
+
} catch {
|
|
2452
|
+
return null;
|
|
2453
|
+
}
|
|
2454
|
+
}
|
|
2455
|
+
function isIgnorableFrontendError(error) {
|
|
2456
|
+
const name = error && typeof error === "object" ? error.name || "" : "";
|
|
2457
|
+
const message = error instanceof Error ? error.message : String(error ?? "");
|
|
2458
|
+
const lowerMessage = message.toLowerCase();
|
|
2459
|
+
return name === "AbortError" || lowerMessage.includes("the operation was aborted") || lowerMessage.includes("signal is aborted") || lowerMessage.includes("resizeobserver loop");
|
|
2460
|
+
}
|
|
2461
|
+
function setSentryUserContext(user) {
|
|
2462
|
+
const sentry = getSentry();
|
|
2463
|
+
if (!sentry) return;
|
|
2464
|
+
if (user) {
|
|
2465
|
+
sentry.setUser({
|
|
2466
|
+
id: user.id,
|
|
2467
|
+
email: user.email
|
|
2468
|
+
});
|
|
2469
|
+
sentry.setTags({
|
|
2470
|
+
company_id: user.company_id || "unknown",
|
|
2471
|
+
role: user.role || "unknown",
|
|
2472
|
+
role_level: user.role_level || "unknown"
|
|
2473
|
+
});
|
|
2474
|
+
} else {
|
|
2475
|
+
sentry.setUser(null);
|
|
2476
|
+
sentry.setTags({
|
|
2477
|
+
company_id: void 0,
|
|
2478
|
+
role: void 0,
|
|
2479
|
+
role_level: void 0
|
|
2480
|
+
});
|
|
2481
|
+
}
|
|
2482
|
+
}
|
|
2483
|
+
function setSentryWorkspaceContext(config) {
|
|
2484
|
+
const sentry = getSentry();
|
|
2485
|
+
if (!sentry) return;
|
|
2486
|
+
sentry.setTags({
|
|
2487
|
+
workspace_company: config.companyId || "unknown",
|
|
2488
|
+
workspace_factory: config.factoryId || "unknown",
|
|
2489
|
+
factory_name: config.factoryName || "unknown"
|
|
2490
|
+
});
|
|
2491
|
+
}
|
|
2492
|
+
function clearSentryContext() {
|
|
2493
|
+
const sentry = getSentry();
|
|
2494
|
+
if (!sentry) return;
|
|
2495
|
+
sentry.setUser(null);
|
|
2496
|
+
sentry.setTags({
|
|
2497
|
+
company_id: void 0,
|
|
2498
|
+
role: void 0,
|
|
2499
|
+
role_level: void 0,
|
|
2500
|
+
workspace_company: void 0,
|
|
2501
|
+
workspace_factory: void 0,
|
|
2502
|
+
factory_name: void 0
|
|
2503
|
+
});
|
|
2504
|
+
}
|
|
2505
|
+
function applyScopeExtras(scope, extras) {
|
|
2506
|
+
if (!extras) return;
|
|
2507
|
+
if (scope.setExtras) {
|
|
2508
|
+
scope.setExtras(extras);
|
|
2509
|
+
return;
|
|
2510
|
+
}
|
|
2511
|
+
if (scope.setExtra) {
|
|
2512
|
+
Object.entries(extras).forEach(([key, value]) => scope.setExtra?.(key, value));
|
|
2513
|
+
}
|
|
2514
|
+
}
|
|
2515
|
+
function captureSentryMessage(message, level = "warning", extras) {
|
|
2516
|
+
const sentry = getSentry();
|
|
2517
|
+
if (!sentry || !sentry.captureMessage) return;
|
|
2518
|
+
if (sentry.withScope) {
|
|
2519
|
+
sentry.withScope((scope) => {
|
|
2520
|
+
scope.setLevel?.(level);
|
|
2521
|
+
applyScopeExtras(scope, extras);
|
|
2522
|
+
sentry.captureMessage?.(message);
|
|
2523
|
+
});
|
|
2524
|
+
return;
|
|
2525
|
+
}
|
|
2526
|
+
sentry.captureMessage(message, level);
|
|
2527
|
+
}
|
|
2528
|
+
function captureSentryException(error, extras) {
|
|
2529
|
+
const sentry = getSentry();
|
|
2530
|
+
if (!sentry || !sentry.captureException) return;
|
|
2531
|
+
if (sentry.withScope) {
|
|
2532
|
+
sentry.withScope((scope) => {
|
|
2533
|
+
scope.setLevel?.("error");
|
|
2534
|
+
applyScopeExtras(scope, extras);
|
|
2535
|
+
sentry.captureException?.(error);
|
|
2536
|
+
});
|
|
2537
|
+
return;
|
|
2538
|
+
}
|
|
2539
|
+
sentry.captureException(error);
|
|
2540
|
+
}
|
|
2541
|
+
function captureHandledFrontendException(error, extras) {
|
|
2542
|
+
if (isIgnorableFrontendError(error)) {
|
|
2543
|
+
return;
|
|
2544
|
+
}
|
|
2545
|
+
captureSentryException(error, extras);
|
|
2546
|
+
}
|
|
2547
|
+
|
|
2447
2548
|
// src/lib/services/backendClient.ts
|
|
2448
2549
|
var ACCESS_TOKEN_REFRESH_BUFFER_MS = 6e4;
|
|
2449
2550
|
var cachedAccessToken = null;
|
|
@@ -2499,6 +2600,40 @@ var defaultDedupeKey = (method, url, body) => {
|
|
|
2499
2600
|
const bodyKey = body === void 0 ? "" : typeof body === "string" ? body : JSON.stringify(body);
|
|
2500
2601
|
return `${cachedUserId || "anon"}::${method.toUpperCase()}::${url}::${bodyKey}`;
|
|
2501
2602
|
};
|
|
2603
|
+
var DEFAULT_TIMEOUT_MS = 1e4;
|
|
2604
|
+
var DEFAULT_RETRY_DELAY_MS = 750;
|
|
2605
|
+
var createAbortError = () => {
|
|
2606
|
+
try {
|
|
2607
|
+
return new DOMException("The operation was aborted.", "AbortError");
|
|
2608
|
+
} catch {
|
|
2609
|
+
const error = new Error("The operation was aborted.");
|
|
2610
|
+
error.name = "AbortError";
|
|
2611
|
+
return error;
|
|
2612
|
+
}
|
|
2613
|
+
};
|
|
2614
|
+
var getStatusFromError = (error) => {
|
|
2615
|
+
const message = error instanceof Error ? error.message : String(error ?? "");
|
|
2616
|
+
const statusMatch = message.match(/\((\d{3})\)/) || message.match(/http\s+(\d{3})/i);
|
|
2617
|
+
if (!statusMatch) {
|
|
2618
|
+
return null;
|
|
2619
|
+
}
|
|
2620
|
+
const status = Number.parseInt(statusMatch[1], 10);
|
|
2621
|
+
return Number.isFinite(status) ? status : null;
|
|
2622
|
+
};
|
|
2623
|
+
var isAbortError = (error) => {
|
|
2624
|
+
return error instanceof Error && error.name === "AbortError";
|
|
2625
|
+
};
|
|
2626
|
+
var isRetryableError = (error) => {
|
|
2627
|
+
if (isAbortError(error)) {
|
|
2628
|
+
return false;
|
|
2629
|
+
}
|
|
2630
|
+
const status = getStatusFromError(error);
|
|
2631
|
+
if (status !== null) {
|
|
2632
|
+
return status >= 500 || status === 408 || status === 425 || status === 429;
|
|
2633
|
+
}
|
|
2634
|
+
const message = error instanceof Error ? error.message.toLowerCase() : String(error ?? "").toLowerCase();
|
|
2635
|
+
return message.includes("failed to fetch") || message.includes("networkerror") || message.includes("network request failed") || message.includes("load failed") || message.includes("timed out") || message.includes("fetch failed");
|
|
2636
|
+
};
|
|
2502
2637
|
var fetchBackendJson = async (supabase, endpoint, options = {}) => {
|
|
2503
2638
|
const baseUrl = getBackendUrl();
|
|
2504
2639
|
const url = endpoint.startsWith("http") ? endpoint : `${baseUrl}${endpoint.startsWith("/") ? "" : "/"}${endpoint}`;
|
|
@@ -2510,25 +2645,66 @@ var fetchBackendJson = async (supabase, endpoint, options = {}) => {
|
|
|
2510
2645
|
return existing;
|
|
2511
2646
|
}
|
|
2512
2647
|
const requestPromise = (async () => {
|
|
2513
|
-
const
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
const
|
|
2527
|
-
|
|
2648
|
+
const {
|
|
2649
|
+
dedupeKey: _dedupeKey,
|
|
2650
|
+
skipAuth,
|
|
2651
|
+
timeoutMs = DEFAULT_TIMEOUT_MS,
|
|
2652
|
+
retries = 0,
|
|
2653
|
+
retryDelayMs = DEFAULT_RETRY_DELAY_MS,
|
|
2654
|
+
signal: externalSignal,
|
|
2655
|
+
...fetchOptions
|
|
2656
|
+
} = options;
|
|
2657
|
+
for (let attempt = 0; attempt <= retries; attempt += 1) {
|
|
2658
|
+
if (externalSignal?.aborted) {
|
|
2659
|
+
throw createAbortError();
|
|
2660
|
+
}
|
|
2661
|
+
const headers = new Headers(fetchOptions.headers || {});
|
|
2662
|
+
if (!skipAuth) {
|
|
2663
|
+
const token = await getAuthToken(supabase);
|
|
2664
|
+
headers.set("Authorization", `Bearer ${token}`);
|
|
2665
|
+
}
|
|
2666
|
+
if (!headers.has("Content-Type") && fetchOptions.body !== void 0) {
|
|
2667
|
+
headers.set("Content-Type", "application/json");
|
|
2668
|
+
}
|
|
2669
|
+
const controller = new AbortController();
|
|
2670
|
+
const timeoutId = globalThis.setTimeout(() => controller.abort(), timeoutMs);
|
|
2671
|
+
const abortListener = () => controller.abort();
|
|
2672
|
+
externalSignal?.addEventListener("abort", abortListener, { once: true });
|
|
2673
|
+
try {
|
|
2674
|
+
const response = await fetch(url, {
|
|
2675
|
+
...fetchOptions,
|
|
2676
|
+
headers,
|
|
2677
|
+
signal: controller.signal
|
|
2678
|
+
});
|
|
2679
|
+
if (!response.ok) {
|
|
2680
|
+
const errorText = await response.text();
|
|
2681
|
+
throw new Error(`Backend API error (${response.status}): ${errorText}`);
|
|
2682
|
+
}
|
|
2683
|
+
if (response.status === 204) {
|
|
2684
|
+
return void 0;
|
|
2685
|
+
}
|
|
2686
|
+
const text = await response.text();
|
|
2687
|
+
return text ? JSON.parse(text) : void 0;
|
|
2688
|
+
} catch (error) {
|
|
2689
|
+
const wrappedError = externalSignal?.aborted || controller.signal.aborted && !isAbortError(error) ? createAbortError() : error;
|
|
2690
|
+
if (attempt >= retries || !isRetryableError(wrappedError)) {
|
|
2691
|
+
captureHandledFrontendException(wrappedError, {
|
|
2692
|
+
surface: "backend_client",
|
|
2693
|
+
url,
|
|
2694
|
+
method,
|
|
2695
|
+
retry_attempt: attempt,
|
|
2696
|
+
retries,
|
|
2697
|
+
pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
|
|
2698
|
+
});
|
|
2699
|
+
throw wrappedError;
|
|
2700
|
+
}
|
|
2701
|
+
await new Promise((resolve) => globalThis.setTimeout(resolve, retryDelayMs));
|
|
2702
|
+
} finally {
|
|
2703
|
+
globalThis.clearTimeout(timeoutId);
|
|
2704
|
+
externalSignal?.removeEventListener("abort", abortListener);
|
|
2705
|
+
}
|
|
2528
2706
|
}
|
|
2529
|
-
|
|
2530
|
-
const text = await response.text();
|
|
2531
|
-
return text ? JSON.parse(text) : void 0;
|
|
2707
|
+
return void 0;
|
|
2532
2708
|
})();
|
|
2533
2709
|
inFlightRequests.set(dedupeKey, requestPromise);
|
|
2534
2710
|
try {
|
|
@@ -2639,9 +2815,23 @@ var ApiClient = class {
|
|
|
2639
2815
|
continue;
|
|
2640
2816
|
}
|
|
2641
2817
|
if (silentErrors) {
|
|
2818
|
+
captureHandledFrontendException(lastError, {
|
|
2819
|
+
surface: "api_client",
|
|
2820
|
+
url,
|
|
2821
|
+
retries,
|
|
2822
|
+
silent_errors: true,
|
|
2823
|
+
pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
|
|
2824
|
+
});
|
|
2642
2825
|
console.warn("[ApiClient] All retries exhausted, returning fallback data");
|
|
2643
2826
|
return fallbackData;
|
|
2644
2827
|
} else {
|
|
2828
|
+
captureHandledFrontendException(lastError, {
|
|
2829
|
+
surface: "api_client",
|
|
2830
|
+
url,
|
|
2831
|
+
retries,
|
|
2832
|
+
silent_errors: false,
|
|
2833
|
+
pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
|
|
2834
|
+
});
|
|
2645
2835
|
throw lastError;
|
|
2646
2836
|
}
|
|
2647
2837
|
}
|
|
@@ -4919,6 +5109,13 @@ var workspaceService = {
|
|
|
4919
5109
|
return displayNamesMap;
|
|
4920
5110
|
} catch (error) {
|
|
4921
5111
|
console.error("Error fetching workspace display names:", error);
|
|
5112
|
+
captureSentryException(error, {
|
|
5113
|
+
surface: "workspace_display_names",
|
|
5114
|
+
route: "/api/workspaces/display-names",
|
|
5115
|
+
company_id: companyId || null,
|
|
5116
|
+
line_id: lineId || null,
|
|
5117
|
+
pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
|
|
5118
|
+
});
|
|
4922
5119
|
throw error;
|
|
4923
5120
|
}
|
|
4924
5121
|
},
|
|
@@ -6573,95 +6770,6 @@ function clearAllRateLimits2() {
|
|
|
6573
6770
|
rateLimitMap2.clear();
|
|
6574
6771
|
}
|
|
6575
6772
|
|
|
6576
|
-
// src/lib/utils/sentryContext.ts
|
|
6577
|
-
function getSentry() {
|
|
6578
|
-
try {
|
|
6579
|
-
return __require("@sentry/nextjs");
|
|
6580
|
-
} catch {
|
|
6581
|
-
return null;
|
|
6582
|
-
}
|
|
6583
|
-
}
|
|
6584
|
-
function setSentryUserContext(user) {
|
|
6585
|
-
const sentry = getSentry();
|
|
6586
|
-
if (!sentry) return;
|
|
6587
|
-
if (user) {
|
|
6588
|
-
sentry.setUser({
|
|
6589
|
-
id: user.id,
|
|
6590
|
-
email: user.email
|
|
6591
|
-
});
|
|
6592
|
-
sentry.setTags({
|
|
6593
|
-
company_id: user.company_id || "unknown",
|
|
6594
|
-
role: user.role || "unknown",
|
|
6595
|
-
role_level: user.role_level || "unknown"
|
|
6596
|
-
});
|
|
6597
|
-
} else {
|
|
6598
|
-
sentry.setUser(null);
|
|
6599
|
-
sentry.setTags({
|
|
6600
|
-
company_id: void 0,
|
|
6601
|
-
role: void 0,
|
|
6602
|
-
role_level: void 0
|
|
6603
|
-
});
|
|
6604
|
-
}
|
|
6605
|
-
}
|
|
6606
|
-
function setSentryWorkspaceContext(config) {
|
|
6607
|
-
const sentry = getSentry();
|
|
6608
|
-
if (!sentry) return;
|
|
6609
|
-
sentry.setTags({
|
|
6610
|
-
workspace_company: config.companyId || "unknown",
|
|
6611
|
-
workspace_factory: config.factoryId || "unknown",
|
|
6612
|
-
factory_name: config.factoryName || "unknown"
|
|
6613
|
-
});
|
|
6614
|
-
}
|
|
6615
|
-
function clearSentryContext() {
|
|
6616
|
-
const sentry = getSentry();
|
|
6617
|
-
if (!sentry) return;
|
|
6618
|
-
sentry.setUser(null);
|
|
6619
|
-
sentry.setTags({
|
|
6620
|
-
company_id: void 0,
|
|
6621
|
-
role: void 0,
|
|
6622
|
-
role_level: void 0,
|
|
6623
|
-
workspace_company: void 0,
|
|
6624
|
-
workspace_factory: void 0,
|
|
6625
|
-
factory_name: void 0
|
|
6626
|
-
});
|
|
6627
|
-
}
|
|
6628
|
-
function applyScopeExtras(scope, extras) {
|
|
6629
|
-
if (!extras) return;
|
|
6630
|
-
if (scope.setExtras) {
|
|
6631
|
-
scope.setExtras(extras);
|
|
6632
|
-
return;
|
|
6633
|
-
}
|
|
6634
|
-
if (scope.setExtra) {
|
|
6635
|
-
Object.entries(extras).forEach(([key, value]) => scope.setExtra?.(key, value));
|
|
6636
|
-
}
|
|
6637
|
-
}
|
|
6638
|
-
function captureSentryMessage(message, level = "warning", extras) {
|
|
6639
|
-
const sentry = getSentry();
|
|
6640
|
-
if (!sentry || !sentry.captureMessage) return;
|
|
6641
|
-
if (sentry.withScope) {
|
|
6642
|
-
sentry.withScope((scope) => {
|
|
6643
|
-
scope.setLevel?.(level);
|
|
6644
|
-
applyScopeExtras(scope, extras);
|
|
6645
|
-
sentry.captureMessage?.(message);
|
|
6646
|
-
});
|
|
6647
|
-
return;
|
|
6648
|
-
}
|
|
6649
|
-
sentry.captureMessage(message, level);
|
|
6650
|
-
}
|
|
6651
|
-
function captureSentryException(error, extras) {
|
|
6652
|
-
const sentry = getSentry();
|
|
6653
|
-
if (!sentry || !sentry.captureException) return;
|
|
6654
|
-
if (sentry.withScope) {
|
|
6655
|
-
sentry.withScope((scope) => {
|
|
6656
|
-
scope.setLevel?.("error");
|
|
6657
|
-
applyScopeExtras(scope, extras);
|
|
6658
|
-
sentry.captureException?.(error);
|
|
6659
|
-
});
|
|
6660
|
-
return;
|
|
6661
|
-
}
|
|
6662
|
-
sentry.captureException(error);
|
|
6663
|
-
}
|
|
6664
|
-
|
|
6665
6773
|
// src/lib/services/mixpanelService.ts
|
|
6666
6774
|
var ROOT_DASHBOARD_EVENT_NAMES = {
|
|
6667
6775
|
operations_overview: "Operations Overview Page Clicked",
|
|
@@ -8716,6 +8824,12 @@ var LinesService = class {
|
|
|
8716
8824
|
}));
|
|
8717
8825
|
} catch (error) {
|
|
8718
8826
|
console.error("Error fetching lines:", error);
|
|
8827
|
+
captureHandledFrontendException(error, {
|
|
8828
|
+
surface: "lines_service",
|
|
8829
|
+
operation: "getLinesByCompanyId",
|
|
8830
|
+
company_id: companyId,
|
|
8831
|
+
pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
|
|
8832
|
+
});
|
|
8719
8833
|
throw new Error(`Failed to fetch lines: ${error.message}`);
|
|
8720
8834
|
}
|
|
8721
8835
|
}
|
|
@@ -8765,6 +8879,11 @@ var LinesService = class {
|
|
|
8765
8879
|
}));
|
|
8766
8880
|
} catch (error) {
|
|
8767
8881
|
console.error("Error fetching all lines:", error);
|
|
8882
|
+
captureHandledFrontendException(error, {
|
|
8883
|
+
surface: "lines_service",
|
|
8884
|
+
operation: "getAllLines",
|
|
8885
|
+
pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
|
|
8886
|
+
});
|
|
8768
8887
|
throw new Error(`Failed to fetch lines: ${error.message}`);
|
|
8769
8888
|
}
|
|
8770
8889
|
}
|
|
@@ -8823,6 +8942,12 @@ var LinesService = class {
|
|
|
8823
8942
|
};
|
|
8824
8943
|
} catch (error) {
|
|
8825
8944
|
console.error("Error fetching line:", error);
|
|
8945
|
+
captureHandledFrontendException(error, {
|
|
8946
|
+
surface: "lines_service",
|
|
8947
|
+
operation: "getLineById",
|
|
8948
|
+
line_id: lineId,
|
|
8949
|
+
pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
|
|
8950
|
+
});
|
|
8826
8951
|
throw new Error(`Failed to fetch line: ${error.message}`);
|
|
8827
8952
|
}
|
|
8828
8953
|
}
|
|
@@ -10541,6 +10666,17 @@ var AuthProvider = ({ children }) => {
|
|
|
10541
10666
|
const isRecoveringSession = authStatus === "recovering";
|
|
10542
10667
|
useEffect(() => {
|
|
10543
10668
|
currentUserRef.current = user;
|
|
10669
|
+
if (user) {
|
|
10670
|
+
setSentryUserContext({
|
|
10671
|
+
id: user.id,
|
|
10672
|
+
email: user.email,
|
|
10673
|
+
role: user.role,
|
|
10674
|
+
role_level: user.role_level,
|
|
10675
|
+
company_id: user.company_id
|
|
10676
|
+
});
|
|
10677
|
+
return;
|
|
10678
|
+
}
|
|
10679
|
+
clearSentryContext();
|
|
10544
10680
|
}, [user]);
|
|
10545
10681
|
const setTrackedSession = useCallback((nextSession) => {
|
|
10546
10682
|
latestSessionRef.current = nextSession;
|
|
@@ -10701,6 +10837,17 @@ var AuthProvider = ({ children }) => {
|
|
|
10701
10837
|
}
|
|
10702
10838
|
if (isRetryableSessionError(err)) {
|
|
10703
10839
|
console.warn("[AuthContext] Retryable session hydration error, entering recovery mode");
|
|
10840
|
+
if (recoveryAttemptRef.current === 0) {
|
|
10841
|
+
captureSentryException(err, {
|
|
10842
|
+
surface: "auth_session_hydration",
|
|
10843
|
+
phase: isReauth ? "reauth" : "initial",
|
|
10844
|
+
retryable: true,
|
|
10845
|
+
auth_status: authStatus,
|
|
10846
|
+
pathname: typeof window !== "undefined" ? window.location.pathname : "unknown",
|
|
10847
|
+
visibility_state: typeof document !== "undefined" ? document.visibilityState : "unknown",
|
|
10848
|
+
online_state: typeof navigator !== "undefined" ? navigator.onLine : "unknown"
|
|
10849
|
+
});
|
|
10850
|
+
}
|
|
10704
10851
|
enterRecoveryMode(supabaseSession);
|
|
10705
10852
|
return;
|
|
10706
10853
|
}
|
|
@@ -10720,6 +10867,13 @@ var AuthProvider = ({ children }) => {
|
|
|
10720
10867
|
}
|
|
10721
10868
|
resetRecoveryState();
|
|
10722
10869
|
clearAuthSnapshot();
|
|
10870
|
+
captureSentryException(fatalError, {
|
|
10871
|
+
surface: "auth_session_hydration",
|
|
10872
|
+
phase: isReauth ? "reauth" : "initial",
|
|
10873
|
+
retryable: false,
|
|
10874
|
+
auth_status: authStatus,
|
|
10875
|
+
pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
|
|
10876
|
+
});
|
|
10723
10877
|
setError(fatalError);
|
|
10724
10878
|
setAuthStatus("failed");
|
|
10725
10879
|
setUser(null);
|
|
@@ -11414,7 +11568,7 @@ var useMobileMenu = () => {
|
|
|
11414
11568
|
};
|
|
11415
11569
|
var useHideMobileHeader = (shouldHide = true) => {
|
|
11416
11570
|
const context = useMobileMenu();
|
|
11417
|
-
|
|
11571
|
+
React143__default.useEffect(() => {
|
|
11418
11572
|
if (context && shouldHide) {
|
|
11419
11573
|
context.setHideMobileHeader(true);
|
|
11420
11574
|
return () => {
|
|
@@ -13256,7 +13410,13 @@ var parseEfficiencyLegend = (legend) => {
|
|
|
13256
13410
|
critical_threshold: coerce(legend.critical_threshold, DEFAULT_EFFICIENCY_LEGEND.critical_threshold)
|
|
13257
13411
|
};
|
|
13258
13412
|
};
|
|
13259
|
-
var useDashboardMetrics = ({
|
|
13413
|
+
var useDashboardMetrics = ({
|
|
13414
|
+
onLineMetricsUpdate,
|
|
13415
|
+
lineId,
|
|
13416
|
+
lineIds,
|
|
13417
|
+
userAccessibleLineIds,
|
|
13418
|
+
enabled = true
|
|
13419
|
+
}) => {
|
|
13260
13420
|
const { supabaseUrl, supabaseKey } = useDashboardConfig();
|
|
13261
13421
|
const entityConfig = useEntityConfig();
|
|
13262
13422
|
const databaseConfig = useDatabaseConfig();
|
|
@@ -13371,7 +13531,7 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, lineIds, userAccessibl
|
|
|
13371
13531
|
isTimezoneLoading,
|
|
13372
13532
|
companySpecificMetricsTable
|
|
13373
13533
|
});
|
|
13374
|
-
if (!currentLineIdToUse || !supabase || shiftLoading || isTimezoneLoading || companySpecificMetricsTable.includes("unknown_company")) {
|
|
13534
|
+
if (!currentLineIdToUse || !supabase || !enabled || shiftLoading || isTimezoneLoading || companySpecificMetricsTable.includes("unknown_company")) {
|
|
13375
13535
|
updateQueueRef.current = false;
|
|
13376
13536
|
if (!metrics2?.workspaceMetrics?.length && !metrics2?.lineMetrics?.length && !shiftLoading) setIsLoading(false);
|
|
13377
13537
|
if (companySpecificMetricsTable.includes("unknown_company") && !error) {
|
|
@@ -13415,19 +13575,6 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, lineIds, userAccessibl
|
|
|
13415
13575
|
abortControllerRef.current = abortController;
|
|
13416
13576
|
inFlightFetchKeyRef.current = fetchKey;
|
|
13417
13577
|
try {
|
|
13418
|
-
const { data: { session } } = await supabase.auth.getSession();
|
|
13419
|
-
logDebug("[useDashboardMetrics] Session check:", {
|
|
13420
|
-
hasSession: !!session,
|
|
13421
|
-
hasToken: !!session?.access_token,
|
|
13422
|
-
tokenPreview: session?.access_token?.substring(0, 20) + "..."
|
|
13423
|
-
});
|
|
13424
|
-
if (!session?.access_token) {
|
|
13425
|
-
throw new Error("No authentication token available. Please log in.");
|
|
13426
|
-
}
|
|
13427
|
-
const apiUrl = process.env.NEXT_PUBLIC_BACKEND_URL;
|
|
13428
|
-
if (!apiUrl) {
|
|
13429
|
-
throw new Error("Backend URL is not configured. Please set NEXT_PUBLIC_BACKEND_URL in your environment.");
|
|
13430
|
-
}
|
|
13431
13578
|
if (targetLineIds.length === 0) {
|
|
13432
13579
|
logDebug("[useDashboardMetrics] Skipping fetch: no target line IDs after scope filtering");
|
|
13433
13580
|
setMetrics({
|
|
@@ -13446,6 +13593,10 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, lineIds, userAccessibl
|
|
|
13446
13593
|
let idleTimeVlmByLine = {};
|
|
13447
13594
|
let efficiencyLegend;
|
|
13448
13595
|
const forceParam = force ? "&force_refresh=true" : "";
|
|
13596
|
+
const buildMetricsEndpoint = (params) => {
|
|
13597
|
+
const lineIdsParam = isFactory ? `line_ids=${params.groupLineIds.join(",")}` : `line_id=${params.groupLineIds[0]}`;
|
|
13598
|
+
return `/api/dashboard/metrics?${lineIdsParam}&date=${params.date}&shift_id=${params.shiftId}&company_id=${companyId}${forceParam}`;
|
|
13599
|
+
};
|
|
13449
13600
|
if (usesShiftGroups) {
|
|
13450
13601
|
logDebug("[useDashboardMetrics] Factory view shift groups fetch:", {
|
|
13451
13602
|
groupCount: shiftGroups.length,
|
|
@@ -13462,32 +13613,23 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, lineIds, userAccessibl
|
|
|
13462
13613
|
if (groupLineIds.length === 0) {
|
|
13463
13614
|
return null;
|
|
13464
13615
|
}
|
|
13465
|
-
const
|
|
13466
|
-
|
|
13616
|
+
const endpoint = buildMetricsEndpoint({
|
|
13617
|
+
groupLineIds,
|
|
13618
|
+
date: group.date,
|
|
13619
|
+
shiftId: group.shiftId
|
|
13620
|
+
});
|
|
13467
13621
|
logDebug(`[useDashboardMetrics] \u{1F4CA} Fetching for shift ${group.shiftId} (${group.shiftName}):`, {
|
|
13468
13622
|
lineIds: groupLineIds,
|
|
13469
|
-
date: group.date
|
|
13623
|
+
date: group.date,
|
|
13624
|
+
endpoint
|
|
13470
13625
|
});
|
|
13471
|
-
|
|
13626
|
+
return await fetchBackendJson(supabase, endpoint, {
|
|
13472
13627
|
method: "GET",
|
|
13473
|
-
|
|
13474
|
-
|
|
13475
|
-
|
|
13476
|
-
},
|
|
13477
|
-
signal: abortController.signal
|
|
13628
|
+
signal: abortController.signal,
|
|
13629
|
+
timeoutMs: 1e4,
|
|
13630
|
+
retries: 1,
|
|
13631
|
+
dedupeKey: `dashboard-metrics::${requestLineId}::${group.date}::${group.shiftId}::${groupLineIds.join(",")}::${force ? "force" : "cached"}`
|
|
13478
13632
|
});
|
|
13479
|
-
if (!response.ok) {
|
|
13480
|
-
const errorText = await response.text();
|
|
13481
|
-
console.error(`[useDashboardMetrics] Backend API error for shift ${group.shiftId}:`, errorText);
|
|
13482
|
-
throw new Error(`Backend API error (${response.status}): ${errorText}`);
|
|
13483
|
-
}
|
|
13484
|
-
const responseText = await response.text();
|
|
13485
|
-
try {
|
|
13486
|
-
return JSON.parse(responseText);
|
|
13487
|
-
} catch (parseError) {
|
|
13488
|
-
console.error("[useDashboardMetrics] Failed to parse response:", responseText.substring(0, 500));
|
|
13489
|
-
throw new Error(`Invalid JSON response from backend`);
|
|
13490
|
-
}
|
|
13491
13633
|
});
|
|
13492
13634
|
const results = (await Promise.all(metricsPromises)).filter((result) => !!result);
|
|
13493
13635
|
hasFlowBuffers = results.some((result) => result?.metadata?.has_flow_buffers);
|
|
@@ -13522,39 +13664,23 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, lineIds, userAccessibl
|
|
|
13522
13664
|
if (!currentShiftDetails) {
|
|
13523
13665
|
throw new Error("Shift details not available for metrics fetch.");
|
|
13524
13666
|
}
|
|
13525
|
-
const
|
|
13526
|
-
|
|
13527
|
-
|
|
13667
|
+
const endpoint = buildMetricsEndpoint({
|
|
13668
|
+
groupLineIds: targetLineIds,
|
|
13669
|
+
date: currentShiftDetails.date,
|
|
13670
|
+
shiftId: currentShiftDetails.shiftId
|
|
13671
|
+
});
|
|
13528
13672
|
logDebug("[useDashboardMetrics] Calling backend API:", {
|
|
13529
|
-
|
|
13530
|
-
apiUrl,
|
|
13531
|
-
lineIdsParam,
|
|
13532
|
-
operationalDate,
|
|
13673
|
+
endpoint,
|
|
13533
13674
|
shiftId: currentShiftDetails.shiftId,
|
|
13534
13675
|
companyId
|
|
13535
13676
|
});
|
|
13536
|
-
const
|
|
13677
|
+
const backendData = await fetchBackendJson(supabase, endpoint, {
|
|
13537
13678
|
method: "GET",
|
|
13538
|
-
|
|
13539
|
-
|
|
13540
|
-
|
|
13541
|
-
},
|
|
13542
|
-
signal: abortController.signal
|
|
13679
|
+
signal: abortController.signal,
|
|
13680
|
+
timeoutMs: 1e4,
|
|
13681
|
+
retries: 1,
|
|
13682
|
+
dedupeKey: `dashboard-metrics::${requestLineId}::${currentShiftDetails.date}::${currentShiftDetails.shiftId}::${targetLineIds.join(",")}::${force ? "force" : "cached"}`
|
|
13543
13683
|
});
|
|
13544
|
-
logDebug("[useDashboardMetrics] Response status:", response.status, response.statusText);
|
|
13545
|
-
if (!response.ok) {
|
|
13546
|
-
const errorText = await response.text();
|
|
13547
|
-
console.error("[useDashboardMetrics] Backend API error response:", errorText);
|
|
13548
|
-
throw new Error(`Backend API error (${response.status}): ${errorText}`);
|
|
13549
|
-
}
|
|
13550
|
-
const responseText = await response.text();
|
|
13551
|
-
let backendData;
|
|
13552
|
-
try {
|
|
13553
|
-
backendData = JSON.parse(responseText);
|
|
13554
|
-
} catch (parseError) {
|
|
13555
|
-
console.error("[useDashboardMetrics] Failed to parse response as JSON. Response text:", responseText.substring(0, 500));
|
|
13556
|
-
throw new Error(`Invalid JSON response from backend. Received: ${responseText.substring(0, 100)}...`);
|
|
13557
|
-
}
|
|
13558
13684
|
logDebug("[useDashboardMetrics] Backend response:", {
|
|
13559
13685
|
workspaceCount: backendData.workspace_metrics?.length || 0,
|
|
13560
13686
|
lineCount: backendData.line_metrics?.length || 0
|
|
@@ -13609,6 +13735,7 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, lineIds, userAccessibl
|
|
|
13609
13735
|
date: item.date,
|
|
13610
13736
|
workspace_uuid: item.workspace_id,
|
|
13611
13737
|
workspace_name: item.workspace_name,
|
|
13738
|
+
displayName: item.workspace_display_name || item.display_name || void 0,
|
|
13612
13739
|
action_count: item.total_output || 0,
|
|
13613
13740
|
pph: item.avg_pph || 0,
|
|
13614
13741
|
performance_score: item.performance_score || 0,
|
|
@@ -13672,6 +13799,17 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, lineIds, userAccessibl
|
|
|
13672
13799
|
return;
|
|
13673
13800
|
}
|
|
13674
13801
|
console.error("[useDashboardMetrics] Error fetching dashboard metrics:", err);
|
|
13802
|
+
captureSentryException(err, {
|
|
13803
|
+
surface: "home_live_monitor_metrics",
|
|
13804
|
+
route: "/api/dashboard/metrics",
|
|
13805
|
+
line_id: requestLineId,
|
|
13806
|
+
selected_line_ids: targetLineIds,
|
|
13807
|
+
is_factory_view: isFactory,
|
|
13808
|
+
reason: options.reason || "unknown",
|
|
13809
|
+
auth_deferred: !enabled,
|
|
13810
|
+
visibility_state: typeof document !== "undefined" ? document.visibilityState : "unknown",
|
|
13811
|
+
online_state: typeof navigator !== "undefined" ? navigator.onLine : "unknown"
|
|
13812
|
+
});
|
|
13675
13813
|
setError({ message: err.message, code: err.code || "FETCH_ERROR" });
|
|
13676
13814
|
} finally {
|
|
13677
13815
|
if (requestId === activeRequestIdRef.current) {
|
|
@@ -13685,6 +13823,7 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, lineIds, userAccessibl
|
|
|
13685
13823
|
}, [
|
|
13686
13824
|
supabase,
|
|
13687
13825
|
companySpecificMetricsTable,
|
|
13826
|
+
enabled,
|
|
13688
13827
|
companyId,
|
|
13689
13828
|
factoryViewId,
|
|
13690
13829
|
defaultTimezone,
|
|
@@ -13721,24 +13860,24 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, lineIds, userAccessibl
|
|
|
13721
13860
|
logDebug("[useDashboardMetrics] queueUpdate triggered from realtime");
|
|
13722
13861
|
updateQueueRef.current = true;
|
|
13723
13862
|
fetchAllMetricsRef.current({ force: true, reason: "subscription" });
|
|
13724
|
-
}, [supabase]);
|
|
13863
|
+
}, [supabase, enabled]);
|
|
13725
13864
|
useEffect(() => {
|
|
13726
|
-
if (lineId && supabase && !shiftLoading && !isTimezoneLoading) {
|
|
13865
|
+
if (enabled && lineId && supabase && !shiftLoading && !isTimezoneLoading) {
|
|
13727
13866
|
fetchAllMetrics({ reason: "line-change" });
|
|
13728
13867
|
}
|
|
13729
|
-
}, [lineId, supabase, fetchAllMetrics, shiftLoading, isTimezoneLoading]);
|
|
13868
|
+
}, [enabled, lineId, supabase, fetchAllMetrics, shiftLoading, isTimezoneLoading]);
|
|
13730
13869
|
useEffect(() => {
|
|
13731
|
-
if (isFactoryView || !operationalShiftKey) return;
|
|
13870
|
+
if (!enabled || isFactoryView || !operationalShiftKey) return;
|
|
13732
13871
|
if (!supabase || shiftLoading || isTimezoneLoading) return;
|
|
13733
13872
|
fetchAllMetrics({ force: true, reason: "shift-change" });
|
|
13734
|
-
}, [isFactoryView, operationalShiftKey, supabase, shiftLoading, isTimezoneLoading, fetchAllMetrics]);
|
|
13873
|
+
}, [enabled, isFactoryView, operationalShiftKey, supabase, shiftLoading, isTimezoneLoading, fetchAllMetrics]);
|
|
13735
13874
|
useEffect(() => {
|
|
13736
|
-
if (!isFactoryView || !shiftGroupsKey) return;
|
|
13875
|
+
if (!enabled || !isFactoryView || !shiftGroupsKey) return;
|
|
13737
13876
|
if (!supabase || shiftLoading || isTimezoneLoading) return;
|
|
13738
13877
|
fetchAllMetrics({ force: true, reason: "shift-change" });
|
|
13739
|
-
}, [isFactoryView, shiftGroupsKey, supabase, shiftLoading, isTimezoneLoading, fetchAllMetrics]);
|
|
13878
|
+
}, [enabled, isFactoryView, shiftGroupsKey, supabase, shiftLoading, isTimezoneLoading, fetchAllMetrics]);
|
|
13740
13879
|
useEffect(() => {
|
|
13741
|
-
if (!lineId || !supabase || shiftLoading || isTimezoneLoading) {
|
|
13880
|
+
if (!enabled || !lineId || !supabase || shiftLoading || isTimezoneLoading) {
|
|
13742
13881
|
return;
|
|
13743
13882
|
}
|
|
13744
13883
|
let intervalId = null;
|
|
@@ -13764,15 +13903,16 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, lineIds, userAccessibl
|
|
|
13764
13903
|
window.clearInterval(intervalId);
|
|
13765
13904
|
}
|
|
13766
13905
|
};
|
|
13767
|
-
}, [lineId, supabase, shiftLoading, isTimezoneLoading]);
|
|
13906
|
+
}, [enabled, lineId, supabase, shiftLoading, isTimezoneLoading]);
|
|
13768
13907
|
const subscriptionKey = useMemo(() => {
|
|
13769
|
-
if (!supabase || !entityConfig?.companyId) return null;
|
|
13908
|
+
if (!enabled || !supabase || !entityConfig?.companyId) return null;
|
|
13770
13909
|
if (shiftLoading || isTimezoneLoading) return null;
|
|
13771
13910
|
const isFactory = lineId === (entityConfig.factoryViewId || "factory");
|
|
13772
13911
|
if (isFactory && shiftGroups.length === 0) return null;
|
|
13773
13912
|
const shiftGroupsKeyPart = isFactory ? shiftGroups.map((g) => `${g.date}-${g.shiftId}-${g.lineIds.join("_")}`).join("|") : operationalShiftKey;
|
|
13774
13913
|
return `${lineId}|${entityConfig.companyId}|${shiftGroupsKeyPart}`;
|
|
13775
13914
|
}, [
|
|
13915
|
+
enabled,
|
|
13776
13916
|
supabase,
|
|
13777
13917
|
entityConfig?.companyId,
|
|
13778
13918
|
entityConfig?.factoryViewId,
|
|
@@ -14098,9 +14238,14 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, lineIds, userAccessibl
|
|
|
14098
14238
|
lineMetrics: safeMetrics?.lineMetrics || [],
|
|
14099
14239
|
efficiencyLegend: safeMetrics?.efficiencyLegend || DEFAULT_EFFICIENCY_LEGEND,
|
|
14100
14240
|
metadata: safeMetrics?.metadata,
|
|
14101
|
-
isLoading: isLoading || !isMetricsForActiveLine,
|
|
14241
|
+
isLoading: enabled ? isLoading || !isMetricsForActiveLine : false,
|
|
14102
14242
|
error,
|
|
14103
|
-
refetch: () =>
|
|
14243
|
+
refetch: () => {
|
|
14244
|
+
if (!enabled) {
|
|
14245
|
+
return;
|
|
14246
|
+
}
|
|
14247
|
+
fetchAllMetrics({ force: true, reason: "manual" });
|
|
14248
|
+
}
|
|
14104
14249
|
};
|
|
14105
14250
|
};
|
|
14106
14251
|
var useLineKPIs = ({ lineId, enabled }) => {
|
|
@@ -20256,11 +20401,21 @@ var apiUtils = {
|
|
|
20256
20401
|
const token = sessionResponse.data.session?.access_token;
|
|
20257
20402
|
if (!token) {
|
|
20258
20403
|
console.error("API Util: No authentication token available.");
|
|
20404
|
+
captureHandledFrontendException(new Error("Authentication required."), {
|
|
20405
|
+
surface: "api_utils",
|
|
20406
|
+
endpoint: relativeEndpoint,
|
|
20407
|
+
reason: "missing_auth_token"
|
|
20408
|
+
});
|
|
20259
20409
|
throw new Error("Authentication required.");
|
|
20260
20410
|
}
|
|
20261
20411
|
const baseUrl = config.apiBaseUrl;
|
|
20262
20412
|
if (!baseUrl) {
|
|
20263
20413
|
console.error("API Util: apiBaseUrl is not configured.");
|
|
20414
|
+
captureHandledFrontendException(new Error("API base URL is not configured."), {
|
|
20415
|
+
surface: "api_utils",
|
|
20416
|
+
endpoint: relativeEndpoint,
|
|
20417
|
+
reason: "missing_api_base_url"
|
|
20418
|
+
});
|
|
20264
20419
|
throw new Error("API base URL is not configured.");
|
|
20265
20420
|
}
|
|
20266
20421
|
const endpoint = `${baseUrl.replace(/\/$/, "")}/${relativeEndpoint.replace(/^\//, "")}`;
|
|
@@ -20289,6 +20444,12 @@ var apiUtils = {
|
|
|
20289
20444
|
return await response.json();
|
|
20290
20445
|
} catch (error) {
|
|
20291
20446
|
console.error(`Network or fetch error calling ${endpoint}:`, error);
|
|
20447
|
+
captureHandledFrontendException(error, {
|
|
20448
|
+
surface: "api_utils",
|
|
20449
|
+
endpoint,
|
|
20450
|
+
method: options.method || "GET",
|
|
20451
|
+
pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
|
|
20452
|
+
});
|
|
20292
20453
|
if (error instanceof Error) {
|
|
20293
20454
|
throw error;
|
|
20294
20455
|
} else {
|
|
@@ -23472,7 +23633,7 @@ var MotionConfigContext = createContext({
|
|
|
23472
23633
|
});
|
|
23473
23634
|
|
|
23474
23635
|
// ../../node_modules/framer-motion/dist/es/components/AnimatePresence/PopChild.mjs
|
|
23475
|
-
var PopChildMeasure = class extends
|
|
23636
|
+
var PopChildMeasure = class extends React143.Component {
|
|
23476
23637
|
getSnapshotBeforeUpdate(prevProps) {
|
|
23477
23638
|
const element = this.props.childRef.current;
|
|
23478
23639
|
if (element && prevProps.isPresent && !this.props.isPresent) {
|
|
@@ -23527,7 +23688,7 @@ function PopChild({ children, isPresent }) {
|
|
|
23527
23688
|
document.head.removeChild(style);
|
|
23528
23689
|
};
|
|
23529
23690
|
}, [isPresent]);
|
|
23530
|
-
return jsx(PopChildMeasure, { isPresent, childRef: ref, sizeRef: size, children:
|
|
23691
|
+
return jsx(PopChildMeasure, { isPresent, childRef: ref, sizeRef: size, children: React143.cloneElement(children, { ref }) });
|
|
23531
23692
|
}
|
|
23532
23693
|
|
|
23533
23694
|
// ../../node_modules/framer-motion/dist/es/components/AnimatePresence/PresenceChild.mjs
|
|
@@ -23564,7 +23725,7 @@ var PresenceChild = ({ children, initial, isPresent, onExitComplete, custom, pre
|
|
|
23564
23725
|
useMemo(() => {
|
|
23565
23726
|
presenceChildren.forEach((_, key) => presenceChildren.set(key, false));
|
|
23566
23727
|
}, [isPresent]);
|
|
23567
|
-
|
|
23728
|
+
React143.useEffect(() => {
|
|
23568
23729
|
!isPresent && !presenceChildren.size && onExitComplete && onExitComplete();
|
|
23569
23730
|
}, [isPresent]);
|
|
23570
23731
|
if (mode === "popLayout") {
|
|
@@ -31349,7 +31510,7 @@ var withAuth = (WrappedComponent2, options) => {
|
|
|
31349
31510
|
requireAuth: true,
|
|
31350
31511
|
...options
|
|
31351
31512
|
};
|
|
31352
|
-
const WithAuthComponent =
|
|
31513
|
+
const WithAuthComponent = React143.memo(function WithAuthComponent2(props) {
|
|
31353
31514
|
const {
|
|
31354
31515
|
session,
|
|
31355
31516
|
user,
|
|
@@ -31360,9 +31521,9 @@ var withAuth = (WrappedComponent2, options) => {
|
|
|
31360
31521
|
retrySessionHydration
|
|
31361
31522
|
} = useAuth();
|
|
31362
31523
|
const router = useRouter();
|
|
31363
|
-
const [localLoading, setLocalLoading] =
|
|
31364
|
-
const [loadingTimeoutReached, setLoadingTimeoutReached] =
|
|
31365
|
-
|
|
31524
|
+
const [localLoading, setLocalLoading] = React143.useState(loading);
|
|
31525
|
+
const [loadingTimeoutReached, setLoadingTimeoutReached] = React143.useState(false);
|
|
31526
|
+
React143.useEffect(() => {
|
|
31366
31527
|
if (process.env.NODE_ENV === "development" && process.env.DEBUG_AUTH === "true") {
|
|
31367
31528
|
console.log("withAuth state:", {
|
|
31368
31529
|
loading,
|
|
@@ -31374,7 +31535,7 @@ var withAuth = (WrappedComponent2, options) => {
|
|
|
31374
31535
|
});
|
|
31375
31536
|
}
|
|
31376
31537
|
}, [authStatus, error, loading, session, user]);
|
|
31377
|
-
const handleLoadingTimeout =
|
|
31538
|
+
const handleLoadingTimeout = React143.useCallback(() => {
|
|
31378
31539
|
console.warn("[withAuth] Loading timeout reached");
|
|
31379
31540
|
setLoadingTimeoutReached(true);
|
|
31380
31541
|
if (hasStoredSupabaseSession()) {
|
|
@@ -31386,13 +31547,13 @@ var withAuth = (WrappedComponent2, options) => {
|
|
|
31386
31547
|
router.replace(defaultOptions.redirectTo);
|
|
31387
31548
|
}
|
|
31388
31549
|
}, [retrySessionHydration, router]);
|
|
31389
|
-
|
|
31550
|
+
React143.useEffect(() => {
|
|
31390
31551
|
if (!loading && authStatus !== "recovering" && defaultOptions.requireAuth && !session && !error) {
|
|
31391
31552
|
console.log("[withAuth] No session found, redirecting to login");
|
|
31392
31553
|
router.replace(defaultOptions.redirectTo);
|
|
31393
31554
|
}
|
|
31394
31555
|
}, [authStatus, defaultOptions.requireAuth, error, loading, router, session]);
|
|
31395
|
-
|
|
31556
|
+
React143.useEffect(() => {
|
|
31396
31557
|
setLocalLoading(loading);
|
|
31397
31558
|
}, [loading]);
|
|
31398
31559
|
if (loading || localLoading) {
|
|
@@ -32391,11 +32552,11 @@ var BarChartComponent = ({
|
|
|
32391
32552
|
aspect = 2,
|
|
32392
32553
|
...restOfChartProps
|
|
32393
32554
|
}) => {
|
|
32394
|
-
const containerRef =
|
|
32395
|
-
const [containerReady, setContainerReady] =
|
|
32555
|
+
const containerRef = React143__default.useRef(null);
|
|
32556
|
+
const [containerReady, setContainerReady] = React143__default.useState(false);
|
|
32396
32557
|
const themeConfig = useThemeConfig();
|
|
32397
32558
|
const { formatNumber } = useFormatNumber();
|
|
32398
|
-
|
|
32559
|
+
React143__default.useEffect(() => {
|
|
32399
32560
|
const checkContainerDimensions = () => {
|
|
32400
32561
|
if (containerRef.current) {
|
|
32401
32562
|
const rect = containerRef.current.getBoundingClientRect();
|
|
@@ -32509,7 +32670,7 @@ var BarChartComponent = ({
|
|
|
32509
32670
|
}
|
|
32510
32671
|
return /* @__PURE__ */ jsx("div", { className: clsx("w-full", className), children: chartContent });
|
|
32511
32672
|
};
|
|
32512
|
-
var BarChart =
|
|
32673
|
+
var BarChart = React143__default.memo(BarChartComponent, (prevProps, nextProps) => {
|
|
32513
32674
|
if (prevProps.xAxisDataKey !== nextProps.xAxisDataKey || prevProps.xAxisLabel !== nextProps.xAxisLabel || prevProps.yAxisLabel !== nextProps.yAxisLabel || prevProps.yAxisUnit !== nextProps.yAxisUnit || JSON.stringify(prevProps.referenceLines || []) !== JSON.stringify(nextProps.referenceLines || []) || prevProps.layout !== nextProps.layout || prevProps.className !== nextProps.className || prevProps.showGrid !== nextProps.showGrid || prevProps.showLegend !== nextProps.showLegend || prevProps.showTooltip !== nextProps.showTooltip || prevProps.responsive !== nextProps.responsive || prevProps.aspect !== nextProps.aspect) {
|
|
32514
32675
|
return false;
|
|
32515
32676
|
}
|
|
@@ -32560,10 +32721,10 @@ var LineChartComponent = ({
|
|
|
32560
32721
|
fillContainer = false,
|
|
32561
32722
|
...restOfChartProps
|
|
32562
32723
|
}) => {
|
|
32563
|
-
const containerRef =
|
|
32564
|
-
const [dimensions, setDimensions] =
|
|
32565
|
-
const [hasValidData, setHasValidData] =
|
|
32566
|
-
|
|
32724
|
+
const containerRef = React143__default.useRef(null);
|
|
32725
|
+
const [dimensions, setDimensions] = React143__default.useState({ width: 0, height: 0 });
|
|
32726
|
+
const [hasValidData, setHasValidData] = React143__default.useState(false);
|
|
32727
|
+
React143__default.useEffect(() => {
|
|
32567
32728
|
const currentHasValidData = data && lines && lines.length > 0 && data.some(
|
|
32568
32729
|
(item) => lines.some((line) => {
|
|
32569
32730
|
const val = item[line.dataKey];
|
|
@@ -32574,7 +32735,7 @@ var LineChartComponent = ({
|
|
|
32574
32735
|
setHasValidData(true);
|
|
32575
32736
|
}
|
|
32576
32737
|
}, [data, lines, hasValidData]);
|
|
32577
|
-
|
|
32738
|
+
React143__default.useEffect(() => {
|
|
32578
32739
|
if (!containerRef.current) return;
|
|
32579
32740
|
const observer = new ResizeObserver((entries) => {
|
|
32580
32741
|
const entry = entries[0];
|
|
@@ -32699,7 +32860,7 @@ var LineChartComponent = ({
|
|
|
32699
32860
|
}
|
|
32700
32861
|
return /* @__PURE__ */ jsx("div", { className: clsx("w-full", className), children: renderChartContent(restOfChartProps.width, restOfChartProps.height) });
|
|
32701
32862
|
};
|
|
32702
|
-
var LineChart =
|
|
32863
|
+
var LineChart = React143__default.memo(LineChartComponent, (prevProps, nextProps) => {
|
|
32703
32864
|
if (prevProps.xAxisDataKey !== nextProps.xAxisDataKey || prevProps.xAxisLabel !== nextProps.xAxisLabel || prevProps.yAxisLabel !== nextProps.yAxisLabel || prevProps.yAxisUnit !== nextProps.yAxisUnit || prevProps.className !== nextProps.className || prevProps.showGrid !== nextProps.showGrid || prevProps.showLegend !== nextProps.showLegend || prevProps.showTooltip !== nextProps.showTooltip || prevProps.responsive !== nextProps.responsive || prevProps.aspect !== nextProps.aspect || JSON.stringify(prevProps.yAxisDomain) !== JSON.stringify(nextProps.yAxisDomain)) {
|
|
32704
32865
|
return false;
|
|
32705
32866
|
}
|
|
@@ -32793,7 +32954,7 @@ var OutputProgressChartComponent = ({
|
|
|
32793
32954
|
] }) })
|
|
32794
32955
|
] }) });
|
|
32795
32956
|
};
|
|
32796
|
-
var OutputProgressChart =
|
|
32957
|
+
var OutputProgressChart = React143__default.memo(OutputProgressChartComponent);
|
|
32797
32958
|
OutputProgressChart.displayName = "OutputProgressChart";
|
|
32798
32959
|
var LargeOutputProgressChart = ({
|
|
32799
32960
|
currentOutput,
|
|
@@ -32933,7 +33094,7 @@ var CycleTimeChartComponent = ({
|
|
|
32933
33094
|
}
|
|
32934
33095
|
) }) });
|
|
32935
33096
|
};
|
|
32936
|
-
var CycleTimeChart =
|
|
33097
|
+
var CycleTimeChart = React143__default.memo(CycleTimeChartComponent, (prevProps, nextProps) => {
|
|
32937
33098
|
if (prevProps.className !== nextProps.className) {
|
|
32938
33099
|
return false;
|
|
32939
33100
|
}
|
|
@@ -33171,16 +33332,16 @@ var CycleTimeOverTimeChart = ({
|
|
|
33171
33332
|
idleTimeSlots = []
|
|
33172
33333
|
}) => {
|
|
33173
33334
|
const MAX_DATA_POINTS = 40;
|
|
33174
|
-
const containerRef =
|
|
33175
|
-
const [dimensions, setDimensions] =
|
|
33176
|
-
const [hasValidData, setHasValidData] =
|
|
33177
|
-
|
|
33335
|
+
const containerRef = React143__default.useRef(null);
|
|
33336
|
+
const [dimensions, setDimensions] = React143__default.useState({ width: 0, height: 0 });
|
|
33337
|
+
const [hasValidData, setHasValidData] = React143__default.useState(false);
|
|
33338
|
+
React143__default.useEffect(() => {
|
|
33178
33339
|
const currentHasValidData = data && data.some((val) => val !== null && val > 0);
|
|
33179
33340
|
if (currentHasValidData && !hasValidData) {
|
|
33180
33341
|
setHasValidData(true);
|
|
33181
33342
|
}
|
|
33182
33343
|
}, [data, hasValidData]);
|
|
33183
|
-
|
|
33344
|
+
React143__default.useEffect(() => {
|
|
33184
33345
|
if (!containerRef.current) return;
|
|
33185
33346
|
const observer = new ResizeObserver((entries) => {
|
|
33186
33347
|
const entry = entries[0];
|
|
@@ -33212,7 +33373,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
33212
33373
|
const endLabel = shiftEnd && slotIndex === DURATION - 1 ? formatHourLabel(slotIndex + 1) : formatHourLabel(slotIndex + 1);
|
|
33213
33374
|
return `${startLabel} - ${endLabel}`;
|
|
33214
33375
|
};
|
|
33215
|
-
const getDisplayData =
|
|
33376
|
+
const getDisplayData = React143__default.useCallback((rawData) => {
|
|
33216
33377
|
if (xAxisMode === "hourly") return rawData;
|
|
33217
33378
|
return rawData.slice(Math.max(0, rawData.length - MAX_DATA_POINTS));
|
|
33218
33379
|
}, [xAxisMode]);
|
|
@@ -33220,7 +33381,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
33220
33381
|
const DURATION = displayData.length;
|
|
33221
33382
|
const effectiveDatasetKey = datasetKey || `cycle-time:${xAxisMode}`;
|
|
33222
33383
|
const finalData = displayData;
|
|
33223
|
-
const labelInterval =
|
|
33384
|
+
const labelInterval = React143__default.useMemo(() => {
|
|
33224
33385
|
if (xAxisMode === "hourly") {
|
|
33225
33386
|
return Math.max(1, Math.ceil(DURATION / 8));
|
|
33226
33387
|
}
|
|
@@ -33261,8 +33422,8 @@ var CycleTimeOverTimeChart = ({
|
|
|
33261
33422
|
return `${minutes} minutes ${seconds} seconds ago`;
|
|
33262
33423
|
}
|
|
33263
33424
|
};
|
|
33264
|
-
const getNumericValue =
|
|
33265
|
-
const renderChartTooltip =
|
|
33425
|
+
const getNumericValue = React143__default.useCallback((value) => typeof value === "number" && Number.isFinite(value) ? value : null, []);
|
|
33426
|
+
const renderChartTooltip = React143__default.useCallback((tooltipProps) => {
|
|
33266
33427
|
const { active, payload } = tooltipProps;
|
|
33267
33428
|
if (!active || !Array.isArray(payload) || payload.length === 0) {
|
|
33268
33429
|
return null;
|
|
@@ -33325,7 +33486,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
33325
33486
|
] })
|
|
33326
33487
|
] });
|
|
33327
33488
|
}, [getNumericValue, shiftStart, showIdleTime]);
|
|
33328
|
-
const renderCycleDot =
|
|
33489
|
+
const renderCycleDot = React143__default.useCallback((props) => {
|
|
33329
33490
|
const { cx: cx2, cy, payload } = props;
|
|
33330
33491
|
const cycleTime = getNumericValue(payload?.cycleTime);
|
|
33331
33492
|
if (cycleTime === null) {
|
|
@@ -33358,7 +33519,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
33358
33519
|
}
|
|
33359
33520
|
);
|
|
33360
33521
|
}, [getNumericValue, idealCycleTime]);
|
|
33361
|
-
const renderCycleActiveDot =
|
|
33522
|
+
const renderCycleActiveDot = React143__default.useCallback((props) => {
|
|
33362
33523
|
const { cx: cx2, cy, payload } = props;
|
|
33363
33524
|
const cycleTime = getNumericValue(payload?.cycleTime);
|
|
33364
33525
|
if (cycleTime === null) {
|
|
@@ -33379,7 +33540,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
33379
33540
|
}
|
|
33380
33541
|
);
|
|
33381
33542
|
}, [getNumericValue, idealCycleTime]);
|
|
33382
|
-
const renderIdleDot =
|
|
33543
|
+
const renderIdleDot = React143__default.useCallback((props) => {
|
|
33383
33544
|
const { cx: cx2, cy, payload } = props;
|
|
33384
33545
|
const idleMinutes = getNumericValue(payload?.idleMinutes);
|
|
33385
33546
|
if (idleMinutes === null) {
|
|
@@ -33401,7 +33562,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
33401
33562
|
}
|
|
33402
33563
|
);
|
|
33403
33564
|
}, [getNumericValue, showIdleTime]);
|
|
33404
|
-
const renderIdleActiveDot =
|
|
33565
|
+
const renderIdleActiveDot = React143__default.useCallback((props) => {
|
|
33405
33566
|
const { cx: cx2, cy, payload } = props;
|
|
33406
33567
|
const idleMinutes = getNumericValue(payload?.idleMinutes);
|
|
33407
33568
|
if (idleMinutes === null || !showIdleTime) {
|
|
@@ -33419,7 +33580,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
33419
33580
|
}
|
|
33420
33581
|
);
|
|
33421
33582
|
}, [getNumericValue, showIdleTime]);
|
|
33422
|
-
const chartData =
|
|
33583
|
+
const chartData = React143__default.useMemo(() => Array.from({ length: DURATION }, (_, i) => {
|
|
33423
33584
|
const cycleTime = getNumericValue(finalData[i]);
|
|
33424
33585
|
const useIdleSlots = idleTimeSlots.length > 0;
|
|
33425
33586
|
const idleSlot = useIdleSlots ? idleTimeSlots[i] ?? null : null;
|
|
@@ -33616,7 +33777,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
33616
33777
|
}
|
|
33617
33778
|
);
|
|
33618
33779
|
};
|
|
33619
|
-
var Card =
|
|
33780
|
+
var Card = React143.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
33620
33781
|
"div",
|
|
33621
33782
|
{
|
|
33622
33783
|
ref,
|
|
@@ -33628,7 +33789,7 @@ var Card = React142.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
|
33628
33789
|
}
|
|
33629
33790
|
));
|
|
33630
33791
|
Card.displayName = "Card";
|
|
33631
|
-
var CardHeader =
|
|
33792
|
+
var CardHeader = React143.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
33632
33793
|
"div",
|
|
33633
33794
|
{
|
|
33634
33795
|
ref,
|
|
@@ -33637,7 +33798,7 @@ var CardHeader = React142.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
33637
33798
|
}
|
|
33638
33799
|
));
|
|
33639
33800
|
CardHeader.displayName = "CardHeader";
|
|
33640
|
-
var CardTitle =
|
|
33801
|
+
var CardTitle = React143.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
33641
33802
|
"h3",
|
|
33642
33803
|
{
|
|
33643
33804
|
ref,
|
|
@@ -33649,7 +33810,7 @@ var CardTitle = React142.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
33649
33810
|
}
|
|
33650
33811
|
));
|
|
33651
33812
|
CardTitle.displayName = "CardTitle";
|
|
33652
|
-
var CardDescription =
|
|
33813
|
+
var CardDescription = React143.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
33653
33814
|
"p",
|
|
33654
33815
|
{
|
|
33655
33816
|
ref,
|
|
@@ -33658,9 +33819,9 @@ var CardDescription = React142.forwardRef(({ className, ...props }, ref) => /* @
|
|
|
33658
33819
|
}
|
|
33659
33820
|
));
|
|
33660
33821
|
CardDescription.displayName = "CardDescription";
|
|
33661
|
-
var CardContent =
|
|
33822
|
+
var CardContent = React143.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("p-6 pt-0", className), ...props }));
|
|
33662
33823
|
CardContent.displayName = "CardContent";
|
|
33663
|
-
var CardFooter =
|
|
33824
|
+
var CardFooter = React143.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
33664
33825
|
"div",
|
|
33665
33826
|
{
|
|
33666
33827
|
ref,
|
|
@@ -33736,7 +33897,7 @@ var buttonVariants = cva(
|
|
|
33736
33897
|
}
|
|
33737
33898
|
}
|
|
33738
33899
|
);
|
|
33739
|
-
var Button =
|
|
33900
|
+
var Button = React143.forwardRef(
|
|
33740
33901
|
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
33741
33902
|
const Comp = asChild ? Slot : "button";
|
|
33742
33903
|
return /* @__PURE__ */ jsx(
|
|
@@ -33759,10 +33920,10 @@ var HourlyOutputChartComponent = ({
|
|
|
33759
33920
|
idleTimeHourly,
|
|
33760
33921
|
className = ""
|
|
33761
33922
|
}) => {
|
|
33762
|
-
const containerRef =
|
|
33763
|
-
const [containerReady, setContainerReady] =
|
|
33764
|
-
const [containerWidth, setContainerWidth] =
|
|
33765
|
-
const idleSlots =
|
|
33923
|
+
const containerRef = React143__default.useRef(null);
|
|
33924
|
+
const [containerReady, setContainerReady] = React143__default.useState(false);
|
|
33925
|
+
const [containerWidth, setContainerWidth] = React143__default.useState(0);
|
|
33926
|
+
const idleSlots = React143__default.useMemo(
|
|
33766
33927
|
() => buildHourlyIdleSlots({
|
|
33767
33928
|
idleTimeHourly,
|
|
33768
33929
|
shiftStart,
|
|
@@ -33771,12 +33932,12 @@ var HourlyOutputChartComponent = ({
|
|
|
33771
33932
|
[idleTimeHourly, shiftStart, shiftEnd]
|
|
33772
33933
|
);
|
|
33773
33934
|
const SHIFT_DURATION = idleSlots.length;
|
|
33774
|
-
const [animatedData, setAnimatedData] =
|
|
33935
|
+
const [animatedData, setAnimatedData] = React143__default.useState(
|
|
33775
33936
|
() => Array(SHIFT_DURATION).fill(0)
|
|
33776
33937
|
);
|
|
33777
|
-
const prevDataRef =
|
|
33778
|
-
const animationFrameRef =
|
|
33779
|
-
|
|
33938
|
+
const prevDataRef = React143__default.useRef(Array(SHIFT_DURATION).fill(0));
|
|
33939
|
+
const animationFrameRef = React143__default.useRef(null);
|
|
33940
|
+
React143__default.useEffect(() => {
|
|
33780
33941
|
setAnimatedData((prev) => {
|
|
33781
33942
|
if (prev.length !== SHIFT_DURATION) {
|
|
33782
33943
|
return Array(SHIFT_DURATION).fill(0);
|
|
@@ -33785,14 +33946,14 @@ var HourlyOutputChartComponent = ({
|
|
|
33785
33946
|
});
|
|
33786
33947
|
prevDataRef.current = Array(SHIFT_DURATION).fill(0);
|
|
33787
33948
|
}, [SHIFT_DURATION]);
|
|
33788
|
-
const [idleBarState, setIdleBarState] =
|
|
33949
|
+
const [idleBarState, setIdleBarState] = React143__default.useState({
|
|
33789
33950
|
visible: showIdleTime,
|
|
33790
33951
|
key: 0,
|
|
33791
33952
|
shouldAnimate: false
|
|
33792
33953
|
});
|
|
33793
|
-
const prevShowIdleTimeRef =
|
|
33794
|
-
const stateUpdateTimeoutRef =
|
|
33795
|
-
|
|
33954
|
+
const prevShowIdleTimeRef = React143__default.useRef(showIdleTime);
|
|
33955
|
+
const stateUpdateTimeoutRef = React143__default.useRef(null);
|
|
33956
|
+
React143__default.useEffect(() => {
|
|
33796
33957
|
if (stateUpdateTimeoutRef.current) {
|
|
33797
33958
|
clearTimeout(stateUpdateTimeoutRef.current);
|
|
33798
33959
|
}
|
|
@@ -33817,7 +33978,7 @@ var HourlyOutputChartComponent = ({
|
|
|
33817
33978
|
}
|
|
33818
33979
|
};
|
|
33819
33980
|
}, [showIdleTime]);
|
|
33820
|
-
const animateToNewData =
|
|
33981
|
+
const animateToNewData = React143__default.useCallback((targetData) => {
|
|
33821
33982
|
const startData = [...prevDataRef.current];
|
|
33822
33983
|
const startTime = performance.now();
|
|
33823
33984
|
const duration = 1200;
|
|
@@ -33847,7 +34008,7 @@ var HourlyOutputChartComponent = ({
|
|
|
33847
34008
|
}
|
|
33848
34009
|
animationFrameRef.current = requestAnimationFrame(animate);
|
|
33849
34010
|
}, []);
|
|
33850
|
-
|
|
34011
|
+
React143__default.useEffect(() => {
|
|
33851
34012
|
if (JSON.stringify(data) !== JSON.stringify(prevDataRef.current)) {
|
|
33852
34013
|
const shiftData = data.slice(0, SHIFT_DURATION);
|
|
33853
34014
|
animateToNewData(shiftData);
|
|
@@ -33858,7 +34019,7 @@ var HourlyOutputChartComponent = ({
|
|
|
33858
34019
|
}
|
|
33859
34020
|
};
|
|
33860
34021
|
}, [data, animateToNewData]);
|
|
33861
|
-
|
|
34022
|
+
React143__default.useEffect(() => {
|
|
33862
34023
|
const checkContainerDimensions = () => {
|
|
33863
34024
|
if (containerRef.current) {
|
|
33864
34025
|
const rect = containerRef.current.getBoundingClientRect();
|
|
@@ -33884,7 +34045,7 @@ var HourlyOutputChartComponent = ({
|
|
|
33884
34045
|
clearTimeout(fallbackTimeout);
|
|
33885
34046
|
};
|
|
33886
34047
|
}, []);
|
|
33887
|
-
const xAxisConfig =
|
|
34048
|
+
const xAxisConfig = React143__default.useMemo(() => {
|
|
33888
34049
|
if (containerWidth >= 960) {
|
|
33889
34050
|
return { interval: 0, angle: -45, height: 92, tickFont: 10, tickMargin: 12 };
|
|
33890
34051
|
}
|
|
@@ -33893,7 +34054,7 @@ var HourlyOutputChartComponent = ({
|
|
|
33893
34054
|
}
|
|
33894
34055
|
return { interval: 0, angle: -30, height: 64, tickFont: 9, tickMargin: 6 };
|
|
33895
34056
|
}, [containerWidth]);
|
|
33896
|
-
const chartData =
|
|
34057
|
+
const chartData = React143__default.useMemo(() => {
|
|
33897
34058
|
return Array.from({ length: SHIFT_DURATION }, (_, i) => {
|
|
33898
34059
|
const idleSlot = idleSlots[i];
|
|
33899
34060
|
return {
|
|
@@ -33909,7 +34070,7 @@ var HourlyOutputChartComponent = ({
|
|
|
33909
34070
|
};
|
|
33910
34071
|
});
|
|
33911
34072
|
}, [animatedData, data, pphThreshold, idleSlots, SHIFT_DURATION]);
|
|
33912
|
-
const IdleBar =
|
|
34073
|
+
const IdleBar = React143__default.useMemo(() => {
|
|
33913
34074
|
if (!idleBarState.visible) return null;
|
|
33914
34075
|
return /* @__PURE__ */ jsx(
|
|
33915
34076
|
Bar,
|
|
@@ -34207,7 +34368,7 @@ var HourlyOutputChartComponent = ({
|
|
|
34207
34368
|
}
|
|
34208
34369
|
);
|
|
34209
34370
|
};
|
|
34210
|
-
var HourlyOutputChart =
|
|
34371
|
+
var HourlyOutputChart = React143__default.memo(HourlyOutputChartComponent, (prevProps, nextProps) => {
|
|
34211
34372
|
if (prevProps.pphThreshold !== nextProps.pphThreshold || prevProps.shiftStart !== nextProps.shiftStart || prevProps.shiftEnd !== nextProps.shiftEnd || prevProps.shiftDate !== nextProps.shiftDate || prevProps.timezone !== nextProps.timezone || prevProps.showIdleTime !== nextProps.showIdleTime || prevProps.className !== nextProps.className) {
|
|
34212
34373
|
return false;
|
|
34213
34374
|
}
|
|
@@ -34387,7 +34548,7 @@ function getTrendArrowAndColor(trend) {
|
|
|
34387
34548
|
return { arrow: "\u2192", color: "text-gray-400" };
|
|
34388
34549
|
}
|
|
34389
34550
|
}
|
|
34390
|
-
var VideoCard =
|
|
34551
|
+
var VideoCard = React143__default.memo(({
|
|
34391
34552
|
workspace,
|
|
34392
34553
|
hlsUrl,
|
|
34393
34554
|
shouldPlay,
|
|
@@ -34585,7 +34746,7 @@ var logDebug2 = (...args) => {
|
|
|
34585
34746
|
if (!DEBUG_DASHBOARD_LOGS2) return;
|
|
34586
34747
|
console.log(...args);
|
|
34587
34748
|
};
|
|
34588
|
-
var VideoGridView =
|
|
34749
|
+
var VideoGridView = React143__default.memo(({
|
|
34589
34750
|
workspaces,
|
|
34590
34751
|
selectedLine,
|
|
34591
34752
|
lineNames = {},
|
|
@@ -34861,7 +35022,7 @@ var VideoGridView = React142__default.memo(({
|
|
|
34861
35022
|
efficiency: workspace.efficiency,
|
|
34862
35023
|
action_count: workspace.action_count
|
|
34863
35024
|
});
|
|
34864
|
-
const displayName = getWorkspaceDisplayName(workspace.workspace_name, workspace.line_id);
|
|
35025
|
+
const displayName = workspace.displayName || displayNames[`${workspace.line_id}_${workspace.workspace_name}`] || getWorkspaceDisplayName(workspace.workspace_name, workspace.line_id);
|
|
34865
35026
|
const currentPath = (router.asPath || "/").split("#")[0];
|
|
34866
35027
|
const navParams = getWorkspaceNavigationParams(workspaceId, displayName, workspace.line_id, currentPath);
|
|
34867
35028
|
router.push(`/workspace/${workspaceId}${navParams}`);
|
|
@@ -35019,7 +35180,7 @@ var VideoGridView = React142__default.memo(({
|
|
|
35019
35180
|
) });
|
|
35020
35181
|
});
|
|
35021
35182
|
VideoGridView.displayName = "VideoGridView";
|
|
35022
|
-
var MapGridView =
|
|
35183
|
+
var MapGridView = React143__default.memo(({
|
|
35023
35184
|
workspaces,
|
|
35024
35185
|
className = "",
|
|
35025
35186
|
displayNames = {},
|
|
@@ -35858,7 +36019,7 @@ var UptimeLineChartComponent = ({ points, className = "" }) => {
|
|
|
35858
36019
|
)
|
|
35859
36020
|
] }) }) });
|
|
35860
36021
|
};
|
|
35861
|
-
var UptimeLineChart =
|
|
36022
|
+
var UptimeLineChart = React143__default.memo(UptimeLineChartComponent);
|
|
35862
36023
|
var padTime = (value) => value.toString().padStart(2, "0");
|
|
35863
36024
|
var parseTime = (timeValue) => {
|
|
35864
36025
|
if (!timeValue) return null;
|
|
@@ -36098,10 +36259,10 @@ var HourlyUptimeChartComponent = ({
|
|
|
36098
36259
|
elapsedMinutes,
|
|
36099
36260
|
className = ""
|
|
36100
36261
|
}) => {
|
|
36101
|
-
const containerRef =
|
|
36102
|
-
const [containerReady, setContainerReady] =
|
|
36103
|
-
const [containerWidth, setContainerWidth] =
|
|
36104
|
-
const uptimeSeries =
|
|
36262
|
+
const containerRef = React143__default.useRef(null);
|
|
36263
|
+
const [containerReady, setContainerReady] = React143__default.useState(false);
|
|
36264
|
+
const [containerWidth, setContainerWidth] = React143__default.useState(0);
|
|
36265
|
+
const uptimeSeries = React143__default.useMemo(() => buildUptimeSeries({
|
|
36105
36266
|
idleTimeHourly,
|
|
36106
36267
|
shiftStart,
|
|
36107
36268
|
shiftEnd,
|
|
@@ -36110,11 +36271,11 @@ var HourlyUptimeChartComponent = ({
|
|
|
36110
36271
|
elapsedMinutes
|
|
36111
36272
|
}), [idleTimeHourly, shiftStart, shiftEnd, shiftDate, timezone, elapsedMinutes]);
|
|
36112
36273
|
const hasAggregateData = Boolean(hourlyAggregates && hourlyAggregates.length > 0);
|
|
36113
|
-
const shiftStartTime =
|
|
36274
|
+
const shiftStartTime = React143__default.useMemo(
|
|
36114
36275
|
() => getTimeFromTimeString(shiftStart),
|
|
36115
36276
|
[shiftStart]
|
|
36116
36277
|
);
|
|
36117
|
-
const { shiftDuration, shiftEndTime } =
|
|
36278
|
+
const { shiftDuration, shiftEndTime } = React143__default.useMemo(() => {
|
|
36118
36279
|
if (!shiftEnd) {
|
|
36119
36280
|
const fallbackHours = uptimeSeries.shiftMinutes > 0 ? Math.ceil(uptimeSeries.shiftMinutes / 60) : 0;
|
|
36120
36281
|
return { shiftDuration: fallbackHours, shiftEndTime: null };
|
|
@@ -36128,7 +36289,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
36128
36289
|
const hourCount = hasPartial ? Math.ceil(duration) : Math.round(duration);
|
|
36129
36290
|
return { shiftDuration: hourCount, shiftEndTime: endTime };
|
|
36130
36291
|
}, [shiftEnd, shiftStartTime.decimalHour, uptimeSeries.shiftMinutes]);
|
|
36131
|
-
const formatHour =
|
|
36292
|
+
const formatHour = React143__default.useCallback((hourIndex) => {
|
|
36132
36293
|
const isLastHour = hourIndex === shiftDuration - 1;
|
|
36133
36294
|
const startDecimalHour = shiftStartTime.decimalHour + hourIndex;
|
|
36134
36295
|
const startHour = Math.floor(startDecimalHour) % 24;
|
|
@@ -36153,7 +36314,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
36153
36314
|
};
|
|
36154
36315
|
return `${formatTime5(startHour, startMinute)}-${formatTime5(endHour, endMinute)}`;
|
|
36155
36316
|
}, [shiftDuration, shiftStartTime.decimalHour, shiftEndTime]);
|
|
36156
|
-
const formatTimeRange2 =
|
|
36317
|
+
const formatTimeRange2 = React143__default.useCallback((hourIndex) => {
|
|
36157
36318
|
const isLastHour = hourIndex === shiftDuration - 1;
|
|
36158
36319
|
const startDecimalHour = shiftStartTime.decimalHour + hourIndex;
|
|
36159
36320
|
const startHour = Math.floor(startDecimalHour) % 24;
|
|
@@ -36175,7 +36336,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
36175
36336
|
};
|
|
36176
36337
|
return `${formatTime5(startHour, startMinute)} - ${formatTime5(endHour, endMinute)}`;
|
|
36177
36338
|
}, [shiftDuration, shiftStartTime.decimalHour, shiftEndTime]);
|
|
36178
|
-
const chartData =
|
|
36339
|
+
const chartData = React143__default.useMemo(() => {
|
|
36179
36340
|
if (shiftDuration <= 0) return [];
|
|
36180
36341
|
if (hasAggregateData) {
|
|
36181
36342
|
return hourlyAggregates.map((entry, hourIndex) => ({
|
|
@@ -36217,7 +36378,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
36217
36378
|
}, [hasAggregateData, hourlyAggregates, uptimeSeries.points, uptimeSeries.elapsedMinutes, uptimeSeries.shiftMinutes, shiftDuration, formatHour, formatTimeRange2]);
|
|
36218
36379
|
const maxYValue = 100;
|
|
36219
36380
|
const yAxisTicks = [0, 25, 50, 75, 100];
|
|
36220
|
-
|
|
36381
|
+
React143__default.useEffect(() => {
|
|
36221
36382
|
const checkContainerDimensions = () => {
|
|
36222
36383
|
if (containerRef.current) {
|
|
36223
36384
|
const rect = containerRef.current.getBoundingClientRect();
|
|
@@ -36243,7 +36404,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
36243
36404
|
clearTimeout(fallbackTimeout);
|
|
36244
36405
|
};
|
|
36245
36406
|
}, []);
|
|
36246
|
-
const xAxisConfig =
|
|
36407
|
+
const xAxisConfig = React143__default.useMemo(() => {
|
|
36247
36408
|
if (containerWidth >= 960) {
|
|
36248
36409
|
return { interval: 0, angle: -45, height: 92, tickFont: 10, tickMargin: 12, labelMode: "full" };
|
|
36249
36410
|
}
|
|
@@ -36252,7 +36413,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
36252
36413
|
}
|
|
36253
36414
|
return { interval: 0, angle: -30, height: 64, tickFont: 9, tickMargin: 6, labelMode: "start" };
|
|
36254
36415
|
}, [containerWidth]);
|
|
36255
|
-
const formatXAxisTick =
|
|
36416
|
+
const formatXAxisTick = React143__default.useCallback((raw) => {
|
|
36256
36417
|
const label = typeof raw === "string" ? raw : String(raw);
|
|
36257
36418
|
if (xAxisConfig.labelMode === "full") return label;
|
|
36258
36419
|
const parts = label.split("-");
|
|
@@ -36458,7 +36619,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
36458
36619
|
}
|
|
36459
36620
|
);
|
|
36460
36621
|
};
|
|
36461
|
-
var HourlyUptimeChart =
|
|
36622
|
+
var HourlyUptimeChart = React143__default.memo(HourlyUptimeChartComponent);
|
|
36462
36623
|
var DEFAULT_COLORS2 = ["#00AB45", "#ef4444"];
|
|
36463
36624
|
var UptimeDonutChartComponent = ({
|
|
36464
36625
|
data,
|
|
@@ -36528,7 +36689,7 @@ var UptimeDonutChartComponent = ({
|
|
|
36528
36689
|
] }) })
|
|
36529
36690
|
] }) });
|
|
36530
36691
|
};
|
|
36531
|
-
var UptimeDonutChart =
|
|
36692
|
+
var UptimeDonutChart = React143__default.memo(UptimeDonutChartComponent);
|
|
36532
36693
|
UptimeDonutChart.displayName = "UptimeDonutChart";
|
|
36533
36694
|
var TrendIcon = ({ trend }) => {
|
|
36534
36695
|
if (trend === "up") {
|
|
@@ -36647,7 +36808,7 @@ var EmptyStateMessage = ({
|
|
|
36647
36808
|
iconClassName
|
|
36648
36809
|
}) => {
|
|
36649
36810
|
let IconContent = null;
|
|
36650
|
-
if (
|
|
36811
|
+
if (React143__default.isValidElement(iconType)) {
|
|
36651
36812
|
IconContent = iconType;
|
|
36652
36813
|
} else if (typeof iconType === "string") {
|
|
36653
36814
|
const MappedIcon = IconMap[iconType];
|
|
@@ -38930,7 +39091,7 @@ function Skeleton({ className, ...props }) {
|
|
|
38930
39091
|
var Select = SelectPrimitive.Root;
|
|
38931
39092
|
var SelectGroup = SelectPrimitive.Group;
|
|
38932
39093
|
var SelectValue = SelectPrimitive.Value;
|
|
38933
|
-
var SelectTrigger =
|
|
39094
|
+
var SelectTrigger = React143.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
38934
39095
|
SelectPrimitive.Trigger,
|
|
38935
39096
|
{
|
|
38936
39097
|
ref,
|
|
@@ -38946,7 +39107,7 @@ var SelectTrigger = React142.forwardRef(({ className, children, ...props }, ref)
|
|
|
38946
39107
|
}
|
|
38947
39108
|
));
|
|
38948
39109
|
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
|
|
38949
|
-
var SelectScrollUpButton =
|
|
39110
|
+
var SelectScrollUpButton = React143.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
38950
39111
|
SelectPrimitive.ScrollUpButton,
|
|
38951
39112
|
{
|
|
38952
39113
|
ref,
|
|
@@ -38956,7 +39117,7 @@ var SelectScrollUpButton = React142.forwardRef(({ className, ...props }, ref) =>
|
|
|
38956
39117
|
}
|
|
38957
39118
|
));
|
|
38958
39119
|
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
|
|
38959
|
-
var SelectScrollDownButton =
|
|
39120
|
+
var SelectScrollDownButton = React143.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
38960
39121
|
SelectPrimitive.ScrollDownButton,
|
|
38961
39122
|
{
|
|
38962
39123
|
ref,
|
|
@@ -38966,7 +39127,7 @@ var SelectScrollDownButton = React142.forwardRef(({ className, ...props }, ref)
|
|
|
38966
39127
|
}
|
|
38967
39128
|
));
|
|
38968
39129
|
SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
|
|
38969
|
-
var SelectContent =
|
|
39130
|
+
var SelectContent = React143.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
|
|
38970
39131
|
SelectPrimitive.Content,
|
|
38971
39132
|
{
|
|
38972
39133
|
ref,
|
|
@@ -38994,7 +39155,7 @@ var SelectContent = React142.forwardRef(({ className, children, position = "popp
|
|
|
38994
39155
|
}
|
|
38995
39156
|
) }));
|
|
38996
39157
|
SelectContent.displayName = SelectPrimitive.Content.displayName;
|
|
38997
|
-
var SelectLabel =
|
|
39158
|
+
var SelectLabel = React143.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
38998
39159
|
SelectPrimitive.Label,
|
|
38999
39160
|
{
|
|
39000
39161
|
ref,
|
|
@@ -39003,7 +39164,7 @@ var SelectLabel = React142.forwardRef(({ className, ...props }, ref) => /* @__PU
|
|
|
39003
39164
|
}
|
|
39004
39165
|
));
|
|
39005
39166
|
SelectLabel.displayName = SelectPrimitive.Label.displayName;
|
|
39006
|
-
var SelectItem =
|
|
39167
|
+
var SelectItem = React143.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
39007
39168
|
SelectPrimitive.Item,
|
|
39008
39169
|
{
|
|
39009
39170
|
ref,
|
|
@@ -39019,7 +39180,7 @@ var SelectItem = React142.forwardRef(({ className, children, ...props }, ref) =>
|
|
|
39019
39180
|
}
|
|
39020
39181
|
));
|
|
39021
39182
|
SelectItem.displayName = SelectPrimitive.Item.displayName;
|
|
39022
|
-
var SelectSeparator =
|
|
39183
|
+
var SelectSeparator = React143.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
39023
39184
|
SelectPrimitive.Separator,
|
|
39024
39185
|
{
|
|
39025
39186
|
ref,
|
|
@@ -39641,7 +39802,7 @@ var TimePickerDropdown = ({
|
|
|
39641
39802
|
)
|
|
39642
39803
|
] });
|
|
39643
39804
|
};
|
|
39644
|
-
var SilentErrorBoundary = class extends
|
|
39805
|
+
var SilentErrorBoundary = class extends React143__default.Component {
|
|
39645
39806
|
constructor(props) {
|
|
39646
39807
|
super(props);
|
|
39647
39808
|
this.handleClearAndReload = () => {
|
|
@@ -39674,6 +39835,12 @@ var SilentErrorBoundary = class extends React142__default.Component {
|
|
|
39674
39835
|
componentStack: errorInfo.componentStack,
|
|
39675
39836
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
39676
39837
|
});
|
|
39838
|
+
captureSentryException(error, {
|
|
39839
|
+
surface: "react_error_boundary",
|
|
39840
|
+
component_stack: errorInfo.componentStack,
|
|
39841
|
+
error_count: this.state.errorCount + 1,
|
|
39842
|
+
pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
|
|
39843
|
+
});
|
|
39677
39844
|
this.setState((prev) => ({
|
|
39678
39845
|
errorCount: prev.errorCount + 1,
|
|
39679
39846
|
lastError: error,
|
|
@@ -46510,8 +46677,8 @@ var IdleTimeReasonChartComponent = ({
|
|
|
46510
46677
|
updateAnimation = "replay",
|
|
46511
46678
|
variant = "pie"
|
|
46512
46679
|
}) => {
|
|
46513
|
-
const [activeData, setActiveData] =
|
|
46514
|
-
|
|
46680
|
+
const [activeData, setActiveData] = React143__default.useState([]);
|
|
46681
|
+
React143__default.useEffect(() => {
|
|
46515
46682
|
if (updateAnimation === "smooth") {
|
|
46516
46683
|
setActiveData(data && data.length > 0 ? data : []);
|
|
46517
46684
|
return;
|
|
@@ -46530,7 +46697,7 @@ var IdleTimeReasonChartComponent = ({
|
|
|
46530
46697
|
setActiveData([]);
|
|
46531
46698
|
}
|
|
46532
46699
|
}, [data, updateAnimation]);
|
|
46533
|
-
|
|
46700
|
+
React143__default.useEffect(() => {
|
|
46534
46701
|
if (!data || data.length === 0) return;
|
|
46535
46702
|
data.forEach((entry, index) => {
|
|
46536
46703
|
if (entry.name.toLowerCase().includes("other")) {
|
|
@@ -46538,7 +46705,7 @@ var IdleTimeReasonChartComponent = ({
|
|
|
46538
46705
|
}
|
|
46539
46706
|
});
|
|
46540
46707
|
}, [data]);
|
|
46541
|
-
const pieKey =
|
|
46708
|
+
const pieKey = React143__default.useMemo(() => {
|
|
46542
46709
|
if (updateAnimation === "smooth") {
|
|
46543
46710
|
return "smooth";
|
|
46544
46711
|
}
|
|
@@ -46708,7 +46875,7 @@ var IdleTimeReasonChartComponent = ({
|
|
|
46708
46875
|
)
|
|
46709
46876
|
] });
|
|
46710
46877
|
};
|
|
46711
|
-
var IdleTimeReasonChart =
|
|
46878
|
+
var IdleTimeReasonChart = React143__default.memo(IdleTimeReasonChartComponent);
|
|
46712
46879
|
IdleTimeReasonChart.displayName = "IdleTimeReasonChart";
|
|
46713
46880
|
var IdleTimeReasonChart_default = IdleTimeReasonChart;
|
|
46714
46881
|
var DEFAULT_PERFORMANCE_DATA = {
|
|
@@ -51075,7 +51242,7 @@ var arePropsEqual = (prevProps, nextProps) => {
|
|
|
51075
51242
|
return prevProps.data.efficiency === nextProps.data.efficiency && prevProps.data.trend_score === nextProps.data.trend_score && prevProps.data.workspace_id === nextProps.data.workspace_id && prevProps.data.workspace_name === nextProps.data.workspace_name && prevProps.isBottleneck === nextProps.isBottleneck && prevProps.isLowEfficiency === nextProps.isLowEfficiency && prevProps.isVeryLowEfficiency === nextProps.isVeryLowEfficiency && prevLegend.green_min === nextLegend.green_min && prevLegend.green_max === nextLegend.green_max && prevLegend.yellow_min === nextLegend.yellow_min && prevLegend.yellow_max === nextLegend.yellow_max && prevLegend.red_min === nextLegend.red_min && prevLegend.red_max === nextLegend.red_max && prevLegend.critical_threshold === nextLegend.critical_threshold && // Position doesn't need deep equality check as it's generally static
|
|
51076
51243
|
prevProps.position.id === nextProps.position.id;
|
|
51077
51244
|
};
|
|
51078
|
-
var WorkspaceGridItem =
|
|
51245
|
+
var WorkspaceGridItem = React143__default.memo(({
|
|
51079
51246
|
data,
|
|
51080
51247
|
position,
|
|
51081
51248
|
isBottleneck = false,
|
|
@@ -51103,7 +51270,7 @@ var WorkspaceGridItem = React142__default.memo(({
|
|
|
51103
51270
|
const handleClick = useCallback((e) => {
|
|
51104
51271
|
e.preventDefault();
|
|
51105
51272
|
if (isInactive) return;
|
|
51106
|
-
const displayName = getWorkspaceDisplayName(data.workspace_name, data.line_id);
|
|
51273
|
+
const displayName = data.displayName || getWorkspaceDisplayName(data.workspace_name, data.line_id);
|
|
51107
51274
|
const currentPath = typeof window !== "undefined" ? `${window.location.pathname}${window.location.search}` : "/";
|
|
51108
51275
|
const navParams = getWorkspaceNavigationParams(data.workspace_id, displayName, data.line_id, currentPath);
|
|
51109
51276
|
navigate(`/workspace/${data.workspace_id}${navParams}`, {
|
|
@@ -51152,7 +51319,7 @@ var WorkspaceGridItem = React142__default.memo(({
|
|
|
51152
51319
|
onClick: handleClick,
|
|
51153
51320
|
className: `${styles2} ${colorClass} ${isBottleneck ? "ring-2 ring-red-500/70" : ""} ${isVeryLowEfficiency ? "ring-2 ring-red-500/50" : ""} ${isInactive ? "bg-gray-200" : ""} shadow-lg touch-manipulation active:scale-[0.98] transition-transform`,
|
|
51154
51321
|
"aria-label": isInactive ? `Inactive workspace ${workspaceNumber}` : `View details for workspace ${workspaceNumber}`,
|
|
51155
|
-
title: isInactive ? `Inactive: ${getWorkspaceDisplayName(data.workspace_name, data.line_id)}` : getWorkspaceDisplayName(data.workspace_name, data.line_id),
|
|
51322
|
+
title: isInactive ? `Inactive: ${data.displayName || getWorkspaceDisplayName(data.workspace_name, data.line_id)}` : data.displayName || getWorkspaceDisplayName(data.workspace_name, data.line_id),
|
|
51156
51323
|
children: /* @__PURE__ */ jsx("div", { className: `font-semibold tracking-wide text-lg sm:text-xl md:text-[min(4vw,2rem)] uppercase ${isInactive ? "text-gray-400" : "text-white"} drop-shadow-sm`, children: workspaceNumber })
|
|
51157
51324
|
}
|
|
51158
51325
|
),
|
|
@@ -51170,7 +51337,7 @@ var WorkspaceGridItem = React142__default.memo(({
|
|
|
51170
51337
|
);
|
|
51171
51338
|
}, arePropsEqual);
|
|
51172
51339
|
WorkspaceGridItem.displayName = "WorkspaceGridItem";
|
|
51173
|
-
var WorkspaceGrid =
|
|
51340
|
+
var WorkspaceGrid = React143__default.memo(({
|
|
51174
51341
|
workspaces,
|
|
51175
51342
|
isPdfMode = false,
|
|
51176
51343
|
customWorkspacePositions,
|
|
@@ -51434,7 +51601,7 @@ var KPICard = ({
|
|
|
51434
51601
|
}) => {
|
|
51435
51602
|
useThemeConfig();
|
|
51436
51603
|
const { formatNumber } = useFormatNumber();
|
|
51437
|
-
const trendInfo =
|
|
51604
|
+
const trendInfo = React143__default.useMemo(() => {
|
|
51438
51605
|
let trendValue = trend || "neutral";
|
|
51439
51606
|
if (change !== void 0 && trend === void 0) {
|
|
51440
51607
|
trendValue = change > 0 ? "up" : change < 0 ? "down" : "neutral";
|
|
@@ -51461,7 +51628,7 @@ var KPICard = ({
|
|
|
51461
51628
|
const shouldShowTrend = !(change === 0 && trend === void 0);
|
|
51462
51629
|
return { trendValue, Icon: Icon2, colorClass, bgClass, shouldShowTrend };
|
|
51463
51630
|
}, [trend, change]);
|
|
51464
|
-
const formattedValue =
|
|
51631
|
+
const formattedValue = React143__default.useMemo(() => {
|
|
51465
51632
|
if (title === "Quality Compliance" && typeof value === "number") {
|
|
51466
51633
|
return value.toFixed(1);
|
|
51467
51634
|
}
|
|
@@ -51475,7 +51642,7 @@ var KPICard = ({
|
|
|
51475
51642
|
}
|
|
51476
51643
|
return value;
|
|
51477
51644
|
}, [value, title]);
|
|
51478
|
-
const formattedChange =
|
|
51645
|
+
const formattedChange = React143__default.useMemo(() => {
|
|
51479
51646
|
if (change === void 0 || change === 0 && !showZeroChange) return null;
|
|
51480
51647
|
const absChange = Math.abs(change);
|
|
51481
51648
|
return formatNumber(absChange, { minimumFractionDigits: 0, maximumFractionDigits: 1 });
|
|
@@ -52982,7 +53149,7 @@ var Breadcrumbs = ({ items }) => {
|
|
|
52982
53149
|
}
|
|
52983
53150
|
}
|
|
52984
53151
|
};
|
|
52985
|
-
return /* @__PURE__ */ jsx("nav", { "aria-label": "Breadcrumb", className: "mb-1 flex items-center space-x-1 text-xs font-medium text-gray-500 dark:text-gray-400", children: items.map((item, index) => /* @__PURE__ */ jsxs(
|
|
53152
|
+
return /* @__PURE__ */ jsx("nav", { "aria-label": "Breadcrumb", className: "mb-1 flex items-center space-x-1 text-xs font-medium text-gray-500 dark:text-gray-400", children: items.map((item, index) => /* @__PURE__ */ jsxs(React143__default.Fragment, { children: [
|
|
52986
53153
|
index > 0 && /* @__PURE__ */ jsx(ChevronRight, { className: "h-3 w-3 text-gray-400 dark:text-gray-500" }),
|
|
52987
53154
|
/* @__PURE__ */ jsxs(
|
|
52988
53155
|
"span",
|
|
@@ -54458,7 +54625,7 @@ var AwardBadge = ({
|
|
|
54458
54625
|
}) => {
|
|
54459
54626
|
const styles2 = getBadgeStyles(type);
|
|
54460
54627
|
const Icon2 = CustomIcon || getDefaultIcon(type);
|
|
54461
|
-
const randomDelay =
|
|
54628
|
+
const randomDelay = React143__default.useMemo(() => Math.random() * 2, []);
|
|
54462
54629
|
const floatingAnimation = {
|
|
54463
54630
|
animate: {
|
|
54464
54631
|
y: [0, -10, 0],
|
|
@@ -59962,67 +60129,77 @@ var NotificationService = class {
|
|
|
59962
60129
|
this.supabaseClient = supabaseClient || null;
|
|
59963
60130
|
}
|
|
59964
60131
|
async fetchWithAuth(url, options = {}) {
|
|
59965
|
-
|
|
59966
|
-
|
|
59967
|
-
|
|
59968
|
-
const { data: { session }, error: sessionError } = await this.supabaseClient.auth.getSession();
|
|
59969
|
-
if (sessionError) {
|
|
59970
|
-
console.error("Session error:", sessionError);
|
|
59971
|
-
throw new Error("Failed to get authentication session. Please log in.");
|
|
59972
|
-
}
|
|
59973
|
-
if (!session) {
|
|
59974
|
-
console.error("No session found. User must be logged in.");
|
|
59975
|
-
throw new Error("User not authenticated. Please log in.");
|
|
59976
|
-
}
|
|
59977
|
-
if (!session.access_token) {
|
|
59978
|
-
console.error("Session exists but no access_token found");
|
|
59979
|
-
throw new Error("Invalid session. Please log in again.");
|
|
59980
|
-
}
|
|
59981
|
-
const token = session.access_token;
|
|
59982
|
-
if (process.env.NODE_ENV === "development") {
|
|
59983
|
-
console.log("[NotificationService] Using JWT token for notifications API");
|
|
59984
|
-
}
|
|
59985
|
-
const headers = {
|
|
59986
|
-
"Content-Type": "application/json",
|
|
59987
|
-
...options.headers,
|
|
59988
|
-
"Authorization": `Bearer ${token}`
|
|
59989
|
-
};
|
|
59990
|
-
const response = await fetch(url, {
|
|
59991
|
-
...options,
|
|
59992
|
-
headers
|
|
59993
|
-
});
|
|
59994
|
-
if (response.status === 401) {
|
|
59995
|
-
console.error("401 Unauthorized - Token expired or invalid");
|
|
59996
|
-
throw new Error("Authentication failed. Please log in again.");
|
|
59997
|
-
}
|
|
59998
|
-
if (response.status === 403) {
|
|
59999
|
-
console.error("403 Forbidden - User does not have permission");
|
|
60000
|
-
throw new Error("Access denied. You do not have permission to access this resource.");
|
|
60001
|
-
}
|
|
60002
|
-
if (response.status === 500) {
|
|
60003
|
-
console.error("500 Internal Server Error - Backend error");
|
|
60004
|
-
let errorDetail = "Internal server error occurred.";
|
|
60005
|
-
try {
|
|
60006
|
-
const errorData = await response.text();
|
|
60007
|
-
console.error("Backend error details:", errorData);
|
|
60008
|
-
errorDetail = errorData || errorDetail;
|
|
60009
|
-
} catch (e) {
|
|
60132
|
+
try {
|
|
60133
|
+
if (!this.supabaseClient) {
|
|
60134
|
+
throw new Error("Supabase client not initialized. Please provide a Supabase client to NotificationService.");
|
|
60010
60135
|
}
|
|
60011
|
-
|
|
60012
|
-
|
|
60013
|
-
|
|
60014
|
-
|
|
60015
|
-
|
|
60016
|
-
|
|
60017
|
-
|
|
60018
|
-
|
|
60019
|
-
|
|
60136
|
+
const { data: { session }, error: sessionError } = await this.supabaseClient.auth.getSession();
|
|
60137
|
+
if (sessionError) {
|
|
60138
|
+
console.error("Session error:", sessionError);
|
|
60139
|
+
throw new Error("Failed to get authentication session. Please log in.");
|
|
60140
|
+
}
|
|
60141
|
+
if (!session) {
|
|
60142
|
+
console.error("No session found. User must be logged in.");
|
|
60143
|
+
throw new Error("User not authenticated. Please log in.");
|
|
60144
|
+
}
|
|
60145
|
+
if (!session.access_token) {
|
|
60146
|
+
console.error("Session exists but no access_token found");
|
|
60147
|
+
throw new Error("Invalid session. Please log in again.");
|
|
60148
|
+
}
|
|
60149
|
+
const token = session.access_token;
|
|
60150
|
+
if (process.env.NODE_ENV === "development") {
|
|
60151
|
+
console.log("[NotificationService] Using JWT token for notifications API");
|
|
60152
|
+
}
|
|
60153
|
+
const headers = {
|
|
60154
|
+
"Content-Type": "application/json",
|
|
60155
|
+
...options.headers,
|
|
60156
|
+
"Authorization": `Bearer ${token}`
|
|
60157
|
+
};
|
|
60158
|
+
const response = await fetch(url, {
|
|
60159
|
+
...options,
|
|
60160
|
+
headers
|
|
60161
|
+
});
|
|
60162
|
+
if (response.status === 401) {
|
|
60163
|
+
console.error("401 Unauthorized - Token expired or invalid");
|
|
60164
|
+
throw new Error("Authentication failed. Please log in again.");
|
|
60165
|
+
}
|
|
60166
|
+
if (response.status === 403) {
|
|
60167
|
+
console.error("403 Forbidden - User does not have permission");
|
|
60168
|
+
throw new Error("Access denied. You do not have permission to access this resource.");
|
|
60169
|
+
}
|
|
60170
|
+
if (response.status === 500) {
|
|
60171
|
+
console.error("500 Internal Server Error - Backend error");
|
|
60172
|
+
let errorDetail = "Internal server error occurred.";
|
|
60173
|
+
try {
|
|
60174
|
+
const errorData = await response.text();
|
|
60175
|
+
console.error("Backend error details:", errorData);
|
|
60176
|
+
errorDetail = errorData || errorDetail;
|
|
60177
|
+
} catch (e) {
|
|
60020
60178
|
}
|
|
60021
|
-
|
|
60179
|
+
throw new Error(`Backend error: ${errorDetail}`);
|
|
60180
|
+
}
|
|
60181
|
+
if (!response.ok) {
|
|
60182
|
+
console.error(`HTTP ${response.status} - ${response.statusText}`);
|
|
60183
|
+
let errorDetail = response.statusText;
|
|
60184
|
+
try {
|
|
60185
|
+
const errorData = await response.json();
|
|
60186
|
+
if (errorData.detail) {
|
|
60187
|
+
errorDetail = errorData.detail;
|
|
60188
|
+
}
|
|
60189
|
+
} catch (e) {
|
|
60190
|
+
}
|
|
60191
|
+
throw new Error(`Request failed (${response.status}): ${errorDetail}`);
|
|
60022
60192
|
}
|
|
60023
|
-
|
|
60193
|
+
return response;
|
|
60194
|
+
} catch (error) {
|
|
60195
|
+
captureHandledFrontendException(error, {
|
|
60196
|
+
surface: "notification_service",
|
|
60197
|
+
url,
|
|
60198
|
+
method: options.method || "GET",
|
|
60199
|
+
pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
|
|
60200
|
+
});
|
|
60201
|
+
throw error;
|
|
60024
60202
|
}
|
|
60025
|
-
return response;
|
|
60026
60203
|
}
|
|
60027
60204
|
/**
|
|
60028
60205
|
* Get bottleneck notifications
|
|
@@ -60096,8 +60273,6 @@ function HomeView({
|
|
|
60096
60273
|
}) {
|
|
60097
60274
|
const [isHydrated, setIsHydrated] = useState(false);
|
|
60098
60275
|
const [isChangingFilter, setIsChangingFilter] = useState(false);
|
|
60099
|
-
const [errorMessage, setErrorMessage] = useState(null);
|
|
60100
|
-
const [displayNamesInitialized, setDisplayNamesInitialized] = useState(false);
|
|
60101
60276
|
const [hasInitialDataLoaded, setHasInitialDataLoaded] = useState(false);
|
|
60102
60277
|
const [showDataLoading, setShowDataLoading] = useState(false);
|
|
60103
60278
|
const loadingStartRef = useRef(null);
|
|
@@ -60106,7 +60281,7 @@ function HomeView({
|
|
|
60106
60281
|
const dashboardConfig = useDashboardConfig();
|
|
60107
60282
|
const entityConfig = useEntityConfig();
|
|
60108
60283
|
const supabaseClient = useSupabaseClient();
|
|
60109
|
-
const { user } = useAuth();
|
|
60284
|
+
const { user, authStatus, isRecoveringSession, retrySessionHydration } = useAuth();
|
|
60110
60285
|
const { lines: dbLines } = useLines();
|
|
60111
60286
|
const mergedLineNames = useMemo(() => {
|
|
60112
60287
|
const merged = { ...lineNames };
|
|
@@ -60240,26 +60415,7 @@ function HomeView({
|
|
|
60240
60415
|
visibleLineIds,
|
|
60241
60416
|
dashboardConfig?.shiftConfig
|
|
60242
60417
|
);
|
|
60243
|
-
|
|
60244
|
-
const initDisplayNames = async () => {
|
|
60245
|
-
try {
|
|
60246
|
-
for (const lineId of selectedLineIds) {
|
|
60247
|
-
await preInitializeWorkspaceDisplayNames(lineId);
|
|
60248
|
-
}
|
|
60249
|
-
setDisplayNamesInitialized(true);
|
|
60250
|
-
} catch (error) {
|
|
60251
|
-
console.error("Failed to pre-initialize workspace display names:", error);
|
|
60252
|
-
setDisplayNamesInitialized(true);
|
|
60253
|
-
}
|
|
60254
|
-
};
|
|
60255
|
-
initDisplayNames();
|
|
60256
|
-
}, [selectedLineIdsKey]);
|
|
60257
|
-
const displayNameLineId = isMultiLineSelection ? void 0 : primarySelectedLineId;
|
|
60258
|
-
const {
|
|
60259
|
-
displayNames: workspaceDisplayNames,
|
|
60260
|
-
loading: displayNamesLoading,
|
|
60261
|
-
error: displayNamesError
|
|
60262
|
-
} = useWorkspaceDisplayNames(displayNameLineId, void 0);
|
|
60418
|
+
const shouldEnableMetricsFetch = authStatus === "ready";
|
|
60263
60419
|
const handleLineMetricsUpdate = useCallback(() => {
|
|
60264
60420
|
if (trendRefreshTimerRef.current) {
|
|
60265
60421
|
window.clearTimeout(trendRefreshTimerRef.current);
|
|
@@ -60286,9 +60442,32 @@ function HomeView({
|
|
|
60286
60442
|
lineId: metricsScopeLineId,
|
|
60287
60443
|
lineIds: selectedLineIds,
|
|
60288
60444
|
onLineMetricsUpdate: handleLineMetricsUpdate,
|
|
60289
|
-
userAccessibleLineIds: visibleLineIds
|
|
60445
|
+
userAccessibleLineIds: visibleLineIds,
|
|
60290
60446
|
// Pass user's accessible lines for supervisor filtering
|
|
60447
|
+
enabled: shouldEnableMetricsFetch
|
|
60291
60448
|
});
|
|
60449
|
+
const metricsDisplayNames = useMemo(() => {
|
|
60450
|
+
const nextDisplayNames = {};
|
|
60451
|
+
workspaceMetrics.forEach((workspace) => {
|
|
60452
|
+
if (!workspace.displayName) {
|
|
60453
|
+
return;
|
|
60454
|
+
}
|
|
60455
|
+
nextDisplayNames[`${workspace.line_id}_${workspace.workspace_name}`] = workspace.displayName;
|
|
60456
|
+
});
|
|
60457
|
+
return nextDisplayNames;
|
|
60458
|
+
}, [workspaceMetrics]);
|
|
60459
|
+
useEffect(() => {
|
|
60460
|
+
workspaceMetrics.forEach((workspace) => {
|
|
60461
|
+
if (!workspace.displayName) {
|
|
60462
|
+
return;
|
|
60463
|
+
}
|
|
60464
|
+
upsertWorkspaceDisplayNameInCache({
|
|
60465
|
+
lineId: workspace.line_id,
|
|
60466
|
+
workspaceId: workspace.workspace_name,
|
|
60467
|
+
displayName: workspace.displayName
|
|
60468
|
+
});
|
|
60469
|
+
});
|
|
60470
|
+
}, [workspaceMetrics]);
|
|
60292
60471
|
const trendGroups = useMemo(() => {
|
|
60293
60472
|
const lineMetricsRows = lineMetrics || [];
|
|
60294
60473
|
if (!lineMetricsRows.length) return null;
|
|
@@ -60729,13 +60908,13 @@ function HomeView({
|
|
|
60729
60908
|
dashboard_surface: "monitor"
|
|
60730
60909
|
});
|
|
60731
60910
|
}, []);
|
|
60732
|
-
|
|
60733
|
-
|
|
60734
|
-
|
|
60735
|
-
|
|
60736
|
-
setErrorMessage(null);
|
|
60911
|
+
const metricsErrorMessage = metricsError?.message || null;
|
|
60912
|
+
const handleRetryDashboardData = useCallback(async () => {
|
|
60913
|
+
if (isRecoveringSession) {
|
|
60914
|
+
await retrySessionHydration();
|
|
60737
60915
|
}
|
|
60738
|
-
|
|
60916
|
+
refetchMetrics();
|
|
60917
|
+
}, [isRecoveringSession, refetchMetrics, retrySessionHydration]);
|
|
60739
60918
|
const getTrackedLineScope = useCallback((lineIdsForScope) => {
|
|
60740
60919
|
if (isAllLinesSelection(lineIdsForScope)) {
|
|
60741
60920
|
return factoryViewId;
|
|
@@ -60793,7 +60972,7 @@ function HomeView({
|
|
|
60793
60972
|
}
|
|
60794
60973
|
}, [metricsLoading, isChangingFilter]);
|
|
60795
60974
|
useEffect(() => {
|
|
60796
|
-
if (!metricsLoading && !hasInitialDataLoaded) {
|
|
60975
|
+
if (shouldEnableMetricsFetch && !metricsLoading && !metricsError && !hasInitialDataLoaded) {
|
|
60797
60976
|
setHasInitialDataLoaded(true);
|
|
60798
60977
|
trackCoreEvent("monitor page loaded", {
|
|
60799
60978
|
default_line_id: defaultLineId,
|
|
@@ -60802,7 +60981,7 @@ function HomeView({
|
|
|
60802
60981
|
dashboard_surface: "monitor"
|
|
60803
60982
|
});
|
|
60804
60983
|
}
|
|
60805
|
-
}, [metricsLoading, hasInitialDataLoaded, defaultLineId, factoryViewId, isSupervisor]);
|
|
60984
|
+
}, [shouldEnableMetricsFetch, metricsLoading, metricsError, hasInitialDataLoaded, defaultLineId, factoryViewId, isSupervisor]);
|
|
60806
60985
|
const lineTitle = useMemo(() => {
|
|
60807
60986
|
return factoryName;
|
|
60808
60987
|
}, [factoryName]);
|
|
@@ -60952,8 +61131,9 @@ function HomeView({
|
|
|
60952
61131
|
}, [isLoading, minDuration]);
|
|
60953
61132
|
return showLoading;
|
|
60954
61133
|
};
|
|
60955
|
-
const
|
|
60956
|
-
const
|
|
61134
|
+
const isAuthBootstrapping = authStatus === "loading";
|
|
61135
|
+
const isInitialLoading = !isHydrated || !hasInitialDataLoaded && (isAuthBootstrapping || shouldEnableMetricsFetch && metricsLoading);
|
|
61136
|
+
const isDataLoading = metricsLoading;
|
|
60957
61137
|
const hasKpiDataReady = useMemo(() => {
|
|
60958
61138
|
const lineMetricsRows = lineMetrics || [];
|
|
60959
61139
|
if (selectedLineIds.length > 1) {
|
|
@@ -60962,6 +61142,10 @@ function HomeView({
|
|
|
60962
61142
|
return lineMetricsRows.some((row) => row?.line_id === primarySelectedLineId);
|
|
60963
61143
|
}, [lineMetrics, primarySelectedLineId, selectedLineIdSet, selectedLineIds.length]);
|
|
60964
61144
|
const isKpiLoading = !hasKpiDataReady;
|
|
61145
|
+
const shouldShowReconnectScreen = !hasInitialDataLoaded && (isRecoveringSession || !shouldEnableMetricsFetch && authStatus !== "failed" || !!metricsErrorMessage && authStatus !== "failed");
|
|
61146
|
+
const shouldShowFatalLoadFailure = !hasInitialDataLoaded && !!metricsErrorMessage && authStatus === "failed";
|
|
61147
|
+
const shouldShowRecoveryBanner = hasInitialDataLoaded && (isRecoveringSession || !!metricsErrorMessage);
|
|
61148
|
+
const recoveryBannerMessage = isRecoveringSession ? "Reconnecting to the dashboard. Showing the last good data while auth recovers." : metricsErrorMessage ? "Live data refresh failed. Showing the last good dashboard snapshot." : null;
|
|
60965
61149
|
useEffect(() => {
|
|
60966
61150
|
const minLoadingDurationMs = 250;
|
|
60967
61151
|
if (isDataLoading) {
|
|
@@ -61001,14 +61185,41 @@ function HomeView({
|
|
|
61001
61185
|
if (isInitialLoading) {
|
|
61002
61186
|
return /* @__PURE__ */ jsx(LoadingPageCmp, { message: "Loading Dashboard..." });
|
|
61003
61187
|
}
|
|
61004
|
-
if (
|
|
61005
|
-
return /* @__PURE__ */ jsx("div", { className: "flex h-screen items-center justify-center
|
|
61006
|
-
/* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-6 w-6", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "
|
|
61007
|
-
/* @__PURE__ */
|
|
61008
|
-
|
|
61009
|
-
|
|
61010
|
-
|
|
61011
|
-
|
|
61188
|
+
if (shouldShowReconnectScreen) {
|
|
61189
|
+
return /* @__PURE__ */ jsx("div", { className: "flex h-screen items-center justify-center bg-slate-50 px-6", children: /* @__PURE__ */ jsxs("div", { className: "max-w-md rounded-2xl border border-slate-200 bg-white p-8 text-center shadow-sm", children: [
|
|
61190
|
+
/* @__PURE__ */ jsx("div", { className: "mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-amber-50 text-amber-600", children: /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-6 w-6", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 4v5h.582m14.836 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-14.837-2m14.837 2H15" }) }) }),
|
|
61191
|
+
/* @__PURE__ */ jsx("h2", { className: "mt-4 text-lg font-semibold text-slate-900", children: "Reconnecting to Optifye" }),
|
|
61192
|
+
/* @__PURE__ */ jsx("p", { className: "mt-2 text-sm text-slate-600", children: metricsErrorMessage || "Your session is recovering after the tab resumed. We will retry automatically." }),
|
|
61193
|
+
/* @__PURE__ */ jsx(
|
|
61194
|
+
"button",
|
|
61195
|
+
{
|
|
61196
|
+
type: "button",
|
|
61197
|
+
onClick: () => {
|
|
61198
|
+
void handleRetryDashboardData();
|
|
61199
|
+
},
|
|
61200
|
+
className: "mt-5 inline-flex items-center justify-center rounded-md bg-slate-900 px-4 py-2 text-sm font-medium text-white transition-colors hover:bg-slate-800",
|
|
61201
|
+
children: "Retry Now"
|
|
61202
|
+
}
|
|
61203
|
+
)
|
|
61204
|
+
] }) });
|
|
61205
|
+
}
|
|
61206
|
+
if (shouldShowFatalLoadFailure) {
|
|
61207
|
+
return /* @__PURE__ */ jsx("div", { className: "flex h-screen items-center justify-center bg-slate-50 px-6", children: /* @__PURE__ */ jsxs("div", { className: "max-w-md rounded-2xl border border-red-200 bg-white p-8 text-center shadow-sm", children: [
|
|
61208
|
+
/* @__PURE__ */ jsx("div", { className: "mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-red-50 text-red-600", children: /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-6 w-6", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) }) }),
|
|
61209
|
+
/* @__PURE__ */ jsx("h2", { className: "mt-4 text-lg font-semibold text-slate-900", children: "Unable to load the dashboard" }),
|
|
61210
|
+
/* @__PURE__ */ jsx("p", { className: "mt-2 text-sm text-slate-600", children: metricsErrorMessage }),
|
|
61211
|
+
/* @__PURE__ */ jsx(
|
|
61212
|
+
"button",
|
|
61213
|
+
{
|
|
61214
|
+
type: "button",
|
|
61215
|
+
onClick: () => {
|
|
61216
|
+
void handleRetryDashboardData();
|
|
61217
|
+
},
|
|
61218
|
+
className: "mt-5 inline-flex items-center justify-center rounded-md bg-slate-900 px-4 py-2 text-sm font-medium text-white transition-colors hover:bg-slate-800",
|
|
61219
|
+
children: "Retry Now"
|
|
61220
|
+
}
|
|
61221
|
+
)
|
|
61222
|
+
] }) });
|
|
61012
61223
|
}
|
|
61013
61224
|
return /* @__PURE__ */ jsx(
|
|
61014
61225
|
motion.div,
|
|
@@ -61027,6 +61238,20 @@ function HomeView({
|
|
|
61027
61238
|
headerControls: kpiSectionControl
|
|
61028
61239
|
}
|
|
61029
61240
|
) }) }),
|
|
61241
|
+
shouldShowRecoveryBanner && recoveryBannerMessage ? /* @__PURE__ */ jsx("div", { className: "border-b border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-900", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between", children: [
|
|
61242
|
+
/* @__PURE__ */ jsx("span", { children: recoveryBannerMessage }),
|
|
61243
|
+
/* @__PURE__ */ jsx(
|
|
61244
|
+
"button",
|
|
61245
|
+
{
|
|
61246
|
+
type: "button",
|
|
61247
|
+
onClick: () => {
|
|
61248
|
+
void handleRetryDashboardData();
|
|
61249
|
+
},
|
|
61250
|
+
className: "inline-flex items-center justify-center rounded-md border border-amber-300 bg-white px-3 py-1.5 text-xs font-medium text-amber-900 transition-colors hover:bg-amber-100",
|
|
61251
|
+
children: "Retry"
|
|
61252
|
+
}
|
|
61253
|
+
)
|
|
61254
|
+
] }) }) : null,
|
|
61030
61255
|
/* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto sm:overflow-hidden relative flex flex-col", children: /* @__PURE__ */ jsx("div", { className: "flex-1 min-h-[calc(100vh-100px)] sm:min-h-0", children: workspaceMetricsWithBreakState.length > 0 ? /* @__PURE__ */ jsx(
|
|
61031
61256
|
motion.div,
|
|
61032
61257
|
{
|
|
@@ -61034,7 +61259,7 @@ function HomeView({
|
|
|
61034
61259
|
animate: { opacity: 1, scale: 1 },
|
|
61035
61260
|
transition: { duration: 0.3 },
|
|
61036
61261
|
className: "h-full",
|
|
61037
|
-
children:
|
|
61262
|
+
children: React143__default.createElement(WorkspaceGrid, {
|
|
61038
61263
|
workspaces: workspaceMetricsWithBreakState,
|
|
61039
61264
|
lineNames: mergedLineNames,
|
|
61040
61265
|
lineOrder: selectedLineIds,
|
|
@@ -61043,7 +61268,7 @@ function HomeView({
|
|
|
61043
61268
|
videoSources,
|
|
61044
61269
|
videoStreamsByWorkspaceId,
|
|
61045
61270
|
videoStreamsLoading,
|
|
61046
|
-
displayNames:
|
|
61271
|
+
displayNames: metricsDisplayNames,
|
|
61047
61272
|
hasFlowBuffers,
|
|
61048
61273
|
className: "h-full",
|
|
61049
61274
|
toolbarRightContent: lineSelectorComponent,
|
|
@@ -61067,7 +61292,7 @@ function HomeView({
|
|
|
61067
61292
|
animate: { opacity: 1, scale: 1 },
|
|
61068
61293
|
transition: { duration: 0.3 },
|
|
61069
61294
|
className: "h-full",
|
|
61070
|
-
children:
|
|
61295
|
+
children: React143__default.createElement(WorkspaceGrid, {
|
|
61071
61296
|
workspaces: [],
|
|
61072
61297
|
// Show empty grid while loading
|
|
61073
61298
|
lineNames: mergedLineNames,
|
|
@@ -61077,7 +61302,7 @@ function HomeView({
|
|
|
61077
61302
|
videoSources,
|
|
61078
61303
|
videoStreamsByWorkspaceId,
|
|
61079
61304
|
videoStreamsLoading,
|
|
61080
|
-
displayNames:
|
|
61305
|
+
displayNames: metricsDisplayNames,
|
|
61081
61306
|
hasFlowBuffers,
|
|
61082
61307
|
className: "h-full",
|
|
61083
61308
|
toolbarRightContent: lineSelectorComponent,
|
|
@@ -61135,7 +61360,7 @@ function HomeView({
|
|
|
61135
61360
|
}
|
|
61136
61361
|
);
|
|
61137
61362
|
}
|
|
61138
|
-
var AuthenticatedHomeView = withAuth(
|
|
61363
|
+
var AuthenticatedHomeView = withAuth(React143__default.memo(HomeView));
|
|
61139
61364
|
var HomeView_default = HomeView;
|
|
61140
61365
|
function withWorkspaceDisplayNames(Component3, options = {}) {
|
|
61141
61366
|
const {
|
|
@@ -61333,6 +61558,7 @@ var buildLineInfoSnapshot = (lineDetails, metrics2) => {
|
|
|
61333
61558
|
shift_id: metrics2.shift_id ?? 0,
|
|
61334
61559
|
date: metrics2.date || "",
|
|
61335
61560
|
monitoring_mode: lineDetails.monitoring_mode ?? void 0,
|
|
61561
|
+
assembly: lineDetails.assembly ?? null,
|
|
61336
61562
|
metrics: {
|
|
61337
61563
|
avg_efficiency: metrics2.avg_efficiency ?? 0,
|
|
61338
61564
|
avg_cycle_time: metrics2.avg_cycle_time ?? 0,
|
|
@@ -61365,6 +61591,7 @@ var transformWorkspaceMetrics = (workspaceData, lineId, companyId, queryDate, qu
|
|
|
61365
61591
|
pph: item.avg_pph || 0,
|
|
61366
61592
|
performance_score: item.performance_score || 0,
|
|
61367
61593
|
avg_cycle_time: item.avg_cycle_time || 0,
|
|
61594
|
+
ideal_cycle_time: item.ideal_cycle_time ?? void 0,
|
|
61368
61595
|
trend: item.trend_score === 1 ? 2 : 0,
|
|
61369
61596
|
predicted_output: item.ideal_output || 0,
|
|
61370
61597
|
efficiency: item.efficiency || 0,
|
|
@@ -61400,7 +61627,8 @@ var transformLineDetails = (lineId, detailResponse) => {
|
|
|
61400
61627
|
id: detailResponse.line_details.factory_id || "",
|
|
61401
61628
|
factory_name: detailResponse.line_details.factory_name || ""
|
|
61402
61629
|
},
|
|
61403
|
-
monitoring_mode: detailResponse.line_details.monitoring_mode ?? void 0
|
|
61630
|
+
monitoring_mode: detailResponse.line_details.monitoring_mode ?? void 0,
|
|
61631
|
+
assembly: detailResponse.line_details.assembly ?? null
|
|
61404
61632
|
};
|
|
61405
61633
|
};
|
|
61406
61634
|
var transformLineMetrics = (lineId, detailResponse, queryDate, queryShiftId) => {
|
|
@@ -61801,6 +62029,56 @@ function useEfficiencyLegend(companyId) {
|
|
|
61801
62029
|
refetch: fetchLegend
|
|
61802
62030
|
};
|
|
61803
62031
|
}
|
|
62032
|
+
|
|
62033
|
+
// src/lib/utils/cycleTime.ts
|
|
62034
|
+
var toFiniteNumber = (value) => {
|
|
62035
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
62036
|
+
if (typeof value === "string" && value.trim() !== "") {
|
|
62037
|
+
const parsed = Number(value);
|
|
62038
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
62039
|
+
}
|
|
62040
|
+
return null;
|
|
62041
|
+
};
|
|
62042
|
+
var getCycleRatio = (workspace) => {
|
|
62043
|
+
const idealCycleTime = toFiniteNumber(workspace.ideal_cycle_time);
|
|
62044
|
+
const avgCycleTime = toFiniteNumber(workspace.avg_cycle_time);
|
|
62045
|
+
if (idealCycleTime === null || avgCycleTime === null || idealCycleTime <= 0 || avgCycleTime <= 0) {
|
|
62046
|
+
return null;
|
|
62047
|
+
}
|
|
62048
|
+
return idealCycleTime / avgCycleTime;
|
|
62049
|
+
};
|
|
62050
|
+
var formatCycleTimeValue = (value) => {
|
|
62051
|
+
const numericValue = toFiniteNumber(value);
|
|
62052
|
+
if (numericValue === null || numericValue <= 0) return "--";
|
|
62053
|
+
return `${numericValue.toFixed(1)}s`;
|
|
62054
|
+
};
|
|
62055
|
+
var CycleTimeComparison = memo$1(({
|
|
62056
|
+
workspace
|
|
62057
|
+
}) => {
|
|
62058
|
+
const averageValue = formatCycleTimeValue(workspace.avg_cycle_time);
|
|
62059
|
+
const standardValue = formatCycleTimeValue(workspace.ideal_cycle_time);
|
|
62060
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 tabular-nums", children: [
|
|
62061
|
+
/* @__PURE__ */ jsx("span", { className: "font-semibold text-gray-900", children: averageValue }),
|
|
62062
|
+
/* @__PURE__ */ jsx("span", { className: "text-gray-400 font-normal", children: "/" }),
|
|
62063
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-gray-500", children: standardValue })
|
|
62064
|
+
] });
|
|
62065
|
+
}, (prevProps, nextProps) => prevProps.workspace.avg_cycle_time === nextProps.workspace.avg_cycle_time && prevProps.workspace.ideal_cycle_time === nextProps.workspace.ideal_cycle_time);
|
|
62066
|
+
CycleTimeComparison.displayName = "CycleTimeComparison";
|
|
62067
|
+
|
|
62068
|
+
// src/lib/utils/kpiPoorestPerformers.ts
|
|
62069
|
+
var getWorstAssemblyCycleTimeWorkspaces = (workspaces, limit = 5) => {
|
|
62070
|
+
return workspaces.map((workspace, index) => ({
|
|
62071
|
+
workspace,
|
|
62072
|
+
index,
|
|
62073
|
+
cycleRatio: getCycleRatio(workspace)
|
|
62074
|
+
})).sort((a, b) => {
|
|
62075
|
+
if (a.cycleRatio === null && b.cycleRatio === null) return a.index - b.index;
|
|
62076
|
+
if (a.cycleRatio === null) return 1;
|
|
62077
|
+
if (b.cycleRatio === null) return -1;
|
|
62078
|
+
if (a.cycleRatio !== b.cycleRatio) return a.cycleRatio - b.cycleRatio;
|
|
62079
|
+
return a.index - b.index;
|
|
62080
|
+
}).slice(0, limit).map(({ workspace }) => workspace);
|
|
62081
|
+
};
|
|
61804
62082
|
var WEEKDAYS4 = ["S", "M", "T", "W", "T", "F", "S"];
|
|
61805
62083
|
var MonthlyRangeFilter = ({
|
|
61806
62084
|
month,
|
|
@@ -62400,7 +62678,13 @@ var BottomSection = memo$1(({
|
|
|
62400
62678
|
}) => {
|
|
62401
62679
|
const navigation = useNavigation();
|
|
62402
62680
|
const handleNavigate = navigate || navigation.navigate;
|
|
62681
|
+
const isAssemblyLine = (lineInfo.assembly === true || workspaceData.some((workspace) => workspace.assembly_enabled)) && lineInfo.monitoring_mode !== "uptime";
|
|
62682
|
+
const assemblyRows = useMemo(
|
|
62683
|
+
() => isAssemblyLine ? getWorstAssemblyCycleTimeWorkspaces(workspaceData) : [],
|
|
62684
|
+
[isAssemblyLine, workspaceData]
|
|
62685
|
+
);
|
|
62403
62686
|
const handleWorkspaceClick = useCallback((ws, index) => {
|
|
62687
|
+
const cycleRatio = getCycleRatio(ws);
|
|
62404
62688
|
trackCoreEvent("Workspace from KPI Clicked", {
|
|
62405
62689
|
workspace_name: ws.workspace_name,
|
|
62406
62690
|
workspace_id: ws.workspace_uuid,
|
|
@@ -62409,9 +62693,13 @@ var BottomSection = memo$1(({
|
|
|
62409
62693
|
efficiency: ws.efficiency,
|
|
62410
62694
|
action_count: ws.action_count,
|
|
62411
62695
|
action_threshold: ws.action_threshold,
|
|
62696
|
+
avg_cycle_time: ws.avg_cycle_time ?? null,
|
|
62697
|
+
ideal_cycle_time: ws.ideal_cycle_time ?? null,
|
|
62698
|
+
cycle_ratio: cycleRatio,
|
|
62699
|
+
ranking_metric: isAssemblyLine ? "cycle_time" : "efficiency",
|
|
62412
62700
|
section: "Poorest Performing Workspaces"
|
|
62413
62701
|
});
|
|
62414
|
-
}, [workspaceData.length]);
|
|
62702
|
+
}, [isAssemblyLine, workspaceData.length]);
|
|
62415
62703
|
return /* @__PURE__ */ jsxs(
|
|
62416
62704
|
motion.div,
|
|
62417
62705
|
{
|
|
@@ -62433,14 +62721,42 @@ var BottomSection = memo$1(({
|
|
|
62433
62721
|
)
|
|
62434
62722
|
] }),
|
|
62435
62723
|
/* @__PURE__ */ jsxs("div", { className: "divide-y overflow-auto flex-1 pr-1 sm:pr-2", children: [
|
|
62436
|
-
/* @__PURE__ */
|
|
62724
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-between pb-2", children: isAssemblyLine ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
62725
|
+
/* @__PURE__ */ jsx("div", { className: "font-medium text-gray-500 min-w-[80px] sm:min-w-[100px] md:min-w-[120px] text-xs sm:text-sm md:text-base", children: "Workspace" }),
|
|
62726
|
+
/* @__PURE__ */ jsx("div", { className: "text-xs md:text-sm font-medium text-gray-500 pr-1 sm:pr-2", children: "Cycle Time" })
|
|
62727
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
62437
62728
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 sm:gap-3 md:gap-6", children: [
|
|
62438
62729
|
/* @__PURE__ */ jsx("div", { className: "font-medium text-gray-500 min-w-[80px] sm:min-w-[100px] md:min-w-[120px] text-xs sm:text-sm md:text-base", children: "Workspace" }),
|
|
62439
62730
|
/* @__PURE__ */ jsx("div", { className: "text-xs md:text-sm font-medium text-gray-500", children: "Current/Ideal" })
|
|
62440
62731
|
] }),
|
|
62441
62732
|
/* @__PURE__ */ jsx("div", { className: "text-xs md:text-sm font-medium text-gray-500 pr-1 sm:pr-2", children: "Efficiency" })
|
|
62442
|
-
] }),
|
|
62443
|
-
|
|
62733
|
+
] }) }),
|
|
62734
|
+
isAssemblyLine ? assemblyRows.map((ws, index) => {
|
|
62735
|
+
if (!ws.workspace_uuid) {
|
|
62736
|
+
return null;
|
|
62737
|
+
}
|
|
62738
|
+
const clickHandler = () => handleWorkspaceClick(ws, index);
|
|
62739
|
+
const displayName = workspaceDisplayNames && workspaceDisplayNames[ws.workspace_name] || getWorkspaceDisplayName(ws.workspace_name, lineId);
|
|
62740
|
+
const navParams = getWorkspaceNavigationParams(ws.workspace_uuid, displayName, lineId);
|
|
62741
|
+
const dateShiftParams = urlDate ? `&date=${urlDate}&shift=${urlShift || "0"}` : "";
|
|
62742
|
+
const returnToParam = `&returnTo=${encodeURIComponent(`/kpis/${lineInfo?.line_id}`)}`;
|
|
62743
|
+
const fullUrl = `/workspace/${ws.workspace_uuid}${navParams}${dateShiftParams}${returnToParam}`;
|
|
62744
|
+
return /* @__PURE__ */ jsx(
|
|
62745
|
+
"div",
|
|
62746
|
+
{
|
|
62747
|
+
onClick: () => {
|
|
62748
|
+
clickHandler();
|
|
62749
|
+
handleNavigate && handleNavigate(fullUrl);
|
|
62750
|
+
},
|
|
62751
|
+
className: "block py-2 sm:py-3 hover:bg-gray-50 transition-colors rounded-lg cursor-pointer",
|
|
62752
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3", children: [
|
|
62753
|
+
/* @__PURE__ */ jsx("div", { className: "min-w-[80px] sm:min-w-[100px] md:min-w-[120px]", children: /* @__PURE__ */ jsx("div", { className: "font-medium text-gray-900 text-xs sm:text-sm md:text-base truncate", children: displayName }) }),
|
|
62754
|
+
/* @__PURE__ */ jsx("div", { className: "shrink-0 text-xs md:text-sm", children: /* @__PURE__ */ jsx(CycleTimeComparison, { workspace: ws }) })
|
|
62755
|
+
] })
|
|
62756
|
+
},
|
|
62757
|
+
ws.workspace_uuid
|
|
62758
|
+
);
|
|
62759
|
+
}) : lineInfo.metrics.poorest_performing_workspaces && lineInfo.metrics.poorest_performing_workspaces.length > 0 ? lineInfo.metrics.poorest_performing_workspaces.map((ws, index) => {
|
|
62444
62760
|
const wsMetrics = workspaceData.find((w) => w.workspace_name === ws.workspace_name);
|
|
62445
62761
|
const wsUuid = wsMetrics?.workspace_uuid;
|
|
62446
62762
|
if (!wsUuid) {
|
|
@@ -62536,10 +62852,63 @@ var BottomSection = memo$1(({
|
|
|
62536
62852
|
const prevPoorest = prevProps.lineInfo.metrics.poorest_performing_workspaces || [];
|
|
62537
62853
|
const nextPoorest = nextProps.lineInfo.metrics.poorest_performing_workspaces || [];
|
|
62538
62854
|
if (prevPoorest.length !== nextPoorest.length) return false;
|
|
62855
|
+
const prevPoorestSignature = JSON.stringify(prevPoorest);
|
|
62856
|
+
const nextPoorestSignature = JSON.stringify(nextPoorest);
|
|
62857
|
+
if (prevPoorestSignature !== nextPoorestSignature) return false;
|
|
62858
|
+
if (prevProps.lineInfo.assembly !== nextProps.lineInfo.assembly) return false;
|
|
62859
|
+
if (prevProps.lineInfo.monitoring_mode !== nextProps.lineInfo.monitoring_mode) return false;
|
|
62539
62860
|
if (prevProps.hourlyOutputData.length !== nextProps.hourlyOutputData.length) return false;
|
|
62540
62861
|
const hourlyDataChanged = prevProps.hourlyOutputData.some((value, index) => value !== nextProps.hourlyOutputData[index]);
|
|
62541
62862
|
if (hourlyDataChanged) return false;
|
|
62542
62863
|
if (prevProps.sortedByEfficiency.length !== nextProps.sortedByEfficiency.length) return false;
|
|
62864
|
+
const prevSortedSignature = JSON.stringify(
|
|
62865
|
+
prevProps.sortedByEfficiency.map((workspace) => ({
|
|
62866
|
+
workspace_uuid: workspace.workspace_uuid,
|
|
62867
|
+
workspace_name: workspace.workspace_name,
|
|
62868
|
+
efficiency: workspace.efficiency,
|
|
62869
|
+
action_count: workspace.action_count,
|
|
62870
|
+
predicted_output: workspace.predicted_output,
|
|
62871
|
+
avg_cycle_time: workspace.avg_cycle_time,
|
|
62872
|
+
ideal_cycle_time: workspace.ideal_cycle_time ?? null
|
|
62873
|
+
}))
|
|
62874
|
+
);
|
|
62875
|
+
const nextSortedSignature = JSON.stringify(
|
|
62876
|
+
nextProps.sortedByEfficiency.map((workspace) => ({
|
|
62877
|
+
workspace_uuid: workspace.workspace_uuid,
|
|
62878
|
+
workspace_name: workspace.workspace_name,
|
|
62879
|
+
efficiency: workspace.efficiency,
|
|
62880
|
+
action_count: workspace.action_count,
|
|
62881
|
+
predicted_output: workspace.predicted_output,
|
|
62882
|
+
avg_cycle_time: workspace.avg_cycle_time,
|
|
62883
|
+
ideal_cycle_time: workspace.ideal_cycle_time ?? null
|
|
62884
|
+
}))
|
|
62885
|
+
);
|
|
62886
|
+
if (prevSortedSignature !== nextSortedSignature) return false;
|
|
62887
|
+
const prevWorkspaceSignature = JSON.stringify(
|
|
62888
|
+
prevProps.workspaceData.map((workspace) => ({
|
|
62889
|
+
workspace_uuid: workspace.workspace_uuid,
|
|
62890
|
+
workspace_name: workspace.workspace_name,
|
|
62891
|
+
efficiency: workspace.efficiency,
|
|
62892
|
+
action_count: workspace.action_count,
|
|
62893
|
+
action_threshold: workspace.action_threshold,
|
|
62894
|
+
predicted_output: workspace.predicted_output,
|
|
62895
|
+
avg_cycle_time: workspace.avg_cycle_time,
|
|
62896
|
+
ideal_cycle_time: workspace.ideal_cycle_time ?? null
|
|
62897
|
+
}))
|
|
62898
|
+
);
|
|
62899
|
+
const nextWorkspaceSignature = JSON.stringify(
|
|
62900
|
+
nextProps.workspaceData.map((workspace) => ({
|
|
62901
|
+
workspace_uuid: workspace.workspace_uuid,
|
|
62902
|
+
workspace_name: workspace.workspace_name,
|
|
62903
|
+
efficiency: workspace.efficiency,
|
|
62904
|
+
action_count: workspace.action_count,
|
|
62905
|
+
action_threshold: workspace.action_threshold,
|
|
62906
|
+
predicted_output: workspace.predicted_output,
|
|
62907
|
+
avg_cycle_time: workspace.avg_cycle_time,
|
|
62908
|
+
ideal_cycle_time: workspace.ideal_cycle_time ?? null
|
|
62909
|
+
}))
|
|
62910
|
+
);
|
|
62911
|
+
if (prevWorkspaceSignature !== nextWorkspaceSignature) return false;
|
|
62543
62912
|
if (prevProps.lineInfo.metrics.shift_start !== nextProps.lineInfo.metrics.shift_start) return false;
|
|
62544
62913
|
if (prevProps.hourlyThreshold !== nextProps.hourlyThreshold) return false;
|
|
62545
62914
|
if (prevProps.urlDate !== nextProps.urlDate || prevProps.urlShift !== nextProps.urlShift) return false;
|
|
@@ -63014,6 +63383,7 @@ var KPIDetailView = ({
|
|
|
63014
63383
|
shift_id: metrics2.shift_id ?? 0,
|
|
63015
63384
|
date: metrics2.date || getOperationalDate(timezone || "UTC"),
|
|
63016
63385
|
monitoring_mode: lineDetails.monitoring_mode ?? void 0,
|
|
63386
|
+
assembly: lineDetails.assembly ?? null,
|
|
63017
63387
|
metrics: {
|
|
63018
63388
|
avg_efficiency: metrics2.avg_efficiency ?? 0,
|
|
63019
63389
|
avg_cycle_time: metrics2.avg_cycle_time ?? 0,
|
|
@@ -64105,18 +64475,18 @@ var LinesLeaderboard = ({
|
|
|
64105
64475
|
isHistoricalDaily
|
|
64106
64476
|
}) => {
|
|
64107
64477
|
const formatEfficiency = (value) => typeof value === "number" && Number.isFinite(value) ? `${value.toFixed(1)}%` : "--";
|
|
64108
|
-
const assignedLineIdSet =
|
|
64478
|
+
const assignedLineIdSet = React143__default.useMemo(
|
|
64109
64479
|
() => new Set(assignedLineIds || []),
|
|
64110
64480
|
[assignedLineIds]
|
|
64111
64481
|
);
|
|
64112
|
-
const canClickLine =
|
|
64482
|
+
const canClickLine = React143__default.useCallback(
|
|
64113
64483
|
(lineId) => {
|
|
64114
64484
|
if (!assignedLineIds) return true;
|
|
64115
64485
|
return assignedLineIdSet.has(lineId);
|
|
64116
64486
|
},
|
|
64117
64487
|
[assignedLineIds, assignedLineIdSet]
|
|
64118
64488
|
);
|
|
64119
|
-
const handleTimeRangeChange =
|
|
64489
|
+
const handleTimeRangeChange = React143__default.useCallback((newRange) => {
|
|
64120
64490
|
if (newRange === timeRange) return;
|
|
64121
64491
|
trackCoreEvent("Leaderboard Time Range Changed", {
|
|
64122
64492
|
from_range: timeRange,
|
|
@@ -64127,7 +64497,7 @@ var LinesLeaderboard = ({
|
|
|
64127
64497
|
});
|
|
64128
64498
|
setTimeRange(newRange);
|
|
64129
64499
|
}, [timeRange, lines.length, monthlyEfficiencyByLineId, setTimeRange]);
|
|
64130
|
-
const handleLeaderboardLineClick =
|
|
64500
|
+
const handleLeaderboardLineClick = React143__default.useCallback((item, clickSource) => {
|
|
64131
64501
|
if (!canClickLine(item.line.id)) return;
|
|
64132
64502
|
trackCoreEvent("Leaderboard Line Clicked", {
|
|
64133
64503
|
line_id: item.line.id,
|
|
@@ -64141,8 +64511,8 @@ var LinesLeaderboard = ({
|
|
|
64141
64511
|
});
|
|
64142
64512
|
onLineClick(item.line);
|
|
64143
64513
|
}, [canClickLine, onLineClick, timeRange]);
|
|
64144
|
-
const viewLoadedTrackedRef =
|
|
64145
|
-
const leaderboardData =
|
|
64514
|
+
const viewLoadedTrackedRef = React143__default.useRef(null);
|
|
64515
|
+
const leaderboardData = React143__default.useMemo(() => {
|
|
64146
64516
|
const loading = timeRange === "today" ? isLoadingToday : isLoadingMonthly;
|
|
64147
64517
|
const efficiencyMap = timeRange === "today" ? todayEfficiencyByLineId : monthlyEfficiencyByLineId;
|
|
64148
64518
|
return lines.map((line) => {
|
|
@@ -64173,7 +64543,7 @@ var LinesLeaderboard = ({
|
|
|
64173
64543
|
isLoadingToday,
|
|
64174
64544
|
isLoadingMonthly
|
|
64175
64545
|
]);
|
|
64176
|
-
|
|
64546
|
+
React143__default.useEffect(() => {
|
|
64177
64547
|
const isLoading = timeRange === "today" ? isLoadingToday : isLoadingMonthly;
|
|
64178
64548
|
const trackingKey = `${timeRange}-${leaderboardData.length}`;
|
|
64179
64549
|
if (leaderboardData.length > 0 && !isLoading && viewLoadedTrackedRef.current !== trackingKey) {
|
|
@@ -64199,7 +64569,7 @@ var LinesLeaderboard = ({
|
|
|
64199
64569
|
const countdownFormat = timeRange === "monthly" ? "days" : "clock";
|
|
64200
64570
|
const countdownFinishedLabel = timeRange === "monthly" ? "Finished" : "Shift Ended";
|
|
64201
64571
|
const showCountdown = timeRange === "monthly" || !isHistoricalDaily;
|
|
64202
|
-
const handleCountdownFinished =
|
|
64572
|
+
const handleCountdownFinished = React143__default.useCallback(() => {
|
|
64203
64573
|
trackCoreEvent("Leaderboard Countdown Finished", {
|
|
64204
64574
|
countdown_type: timeRange === "monthly" ? "month_end" : "shift_end",
|
|
64205
64575
|
time_range: timeRange,
|
|
@@ -64226,7 +64596,7 @@ var LinesLeaderboard = ({
|
|
|
64226
64596
|
return "bg-white border-gray-100";
|
|
64227
64597
|
}
|
|
64228
64598
|
};
|
|
64229
|
-
|
|
64599
|
+
React143__default.useEffect(() => {
|
|
64230
64600
|
const style = document.createElement("style");
|
|
64231
64601
|
style.innerHTML = `
|
|
64232
64602
|
@keyframes float {
|
|
@@ -64413,7 +64783,7 @@ var LineCard = ({
|
|
|
64413
64783
|
supervisors
|
|
64414
64784
|
}) => {
|
|
64415
64785
|
const isUptimeLine = (line.monitoring_mode ?? "output") === "uptime";
|
|
64416
|
-
const isOnTrack =
|
|
64786
|
+
const isOnTrack = React143__default.useMemo(() => {
|
|
64417
64787
|
if (!kpis) return null;
|
|
64418
64788
|
return isEfficiencyOnTrack(kpis.efficiency.value);
|
|
64419
64789
|
}, [kpis]);
|
|
@@ -64611,46 +64981,46 @@ var KPIsOverviewView = ({
|
|
|
64611
64981
|
const configuredTimezone = dbTimezone || dateTimeConfig.defaultTimezone || "UTC";
|
|
64612
64982
|
const { startDate: monthStartDate, endDate: monthEndDateKey, monthEndDate } = getMonthDateInfo(configuredTimezone);
|
|
64613
64983
|
const isSuperAdmin = user?.scope_mode === "SUPER_ADMIN" || !!user?.access_scope?.is_super_admin;
|
|
64614
|
-
const scopedLineIds =
|
|
64984
|
+
const scopedLineIds = React143__default.useMemo(
|
|
64615
64985
|
() => Array.isArray(user?.access_scope?.line_ids) ? user.access_scope.line_ids.filter((lineId) => typeof lineId === "string" && lineId.length > 0) : [],
|
|
64616
64986
|
[user?.access_scope?.line_ids]
|
|
64617
64987
|
);
|
|
64618
64988
|
const hasCanonicalScope = !!user?.scope_mode || !!user?.access_scope;
|
|
64619
64989
|
const scopeRole = (user?.role_level || user?.role || "").toLowerCase();
|
|
64620
64990
|
const isStrictLineScopedRole = scopeRole === "supervisor" || isFactoryScopedRole(scopeRole);
|
|
64621
|
-
const resolvedAssignedLineIds =
|
|
64991
|
+
const resolvedAssignedLineIds = React143__default.useMemo(() => {
|
|
64622
64992
|
if (isSuperAdmin) return [];
|
|
64623
64993
|
if (scopedLineIds.length > 0) return scopedLineIds;
|
|
64624
64994
|
if (lineIds && lineIds.length > 0) return lineIds;
|
|
64625
64995
|
if (isStrictLineScopedRole && hasCanonicalScope) return [];
|
|
64626
64996
|
return [];
|
|
64627
64997
|
}, [isSuperAdmin, scopedLineIds, lineIds, isStrictLineScopedRole, hasCanonicalScope]);
|
|
64628
|
-
const assignedLineIdSet =
|
|
64998
|
+
const assignedLineIdSet = React143__default.useMemo(
|
|
64629
64999
|
() => new Set(resolvedAssignedLineIds),
|
|
64630
65000
|
[resolvedAssignedLineIds]
|
|
64631
65001
|
);
|
|
64632
|
-
const metricsLineIds =
|
|
65002
|
+
const metricsLineIds = React143__default.useMemo(() => {
|
|
64633
65003
|
if (isSuperAdmin) {
|
|
64634
65004
|
return lineIds ?? [];
|
|
64635
65005
|
}
|
|
64636
65006
|
return resolvedAssignedLineIds;
|
|
64637
65007
|
}, [isSuperAdmin, lineIds, resolvedAssignedLineIds]);
|
|
64638
65008
|
const assignedLineIdsForLeaderboard = isSuperAdmin ? void 0 : resolvedAssignedLineIds;
|
|
64639
|
-
const leaderboardLinesForView =
|
|
65009
|
+
const leaderboardLinesForView = React143__default.useMemo(() => {
|
|
64640
65010
|
const targetMode = viewType === "machine" ? "uptime" : "output";
|
|
64641
65011
|
return leaderboardLines.filter((line) => (line.monitoring_mode ?? "output") === targetMode);
|
|
64642
65012
|
}, [leaderboardLines, viewType]);
|
|
64643
|
-
const linesForView =
|
|
65013
|
+
const linesForView = React143__default.useMemo(() => {
|
|
64644
65014
|
const targetMode = viewType === "machine" ? "uptime" : "output";
|
|
64645
65015
|
return lines.filter((line) => (line.monitoring_mode ?? "output") === targetMode);
|
|
64646
65016
|
}, [lines, viewType]);
|
|
64647
|
-
const relevantLinesForMode =
|
|
65017
|
+
const relevantLinesForMode = React143__default.useMemo(() => {
|
|
64648
65018
|
if (activeTab === "leaderboard") {
|
|
64649
65019
|
return leaderboardLines.length > 0 ? leaderboardLines : lines;
|
|
64650
65020
|
}
|
|
64651
65021
|
return lines;
|
|
64652
65022
|
}, [activeTab, leaderboardLines, lines]);
|
|
64653
|
-
const { hasUptime, hasOutput } =
|
|
65023
|
+
const { hasUptime, hasOutput } = React143__default.useMemo(() => {
|
|
64654
65024
|
let uptime = false;
|
|
64655
65025
|
let output = false;
|
|
64656
65026
|
for (const line of relevantLinesForMode) {
|
|
@@ -64675,14 +65045,14 @@ var KPIsOverviewView = ({
|
|
|
64675
65045
|
const currentShiftDetails = getCurrentShift(configuredTimezone, shiftConfig);
|
|
64676
65046
|
const currentShiftDate = currentShiftDetails.date;
|
|
64677
65047
|
const currentShiftId = currentShiftDetails.shiftId;
|
|
64678
|
-
const activeFiltersCount =
|
|
65048
|
+
const activeFiltersCount = React143__default.useMemo(() => {
|
|
64679
65049
|
let count = 0;
|
|
64680
65050
|
if (selectedLeaderboardShiftId !== currentShiftId) {
|
|
64681
65051
|
count++;
|
|
64682
65052
|
}
|
|
64683
65053
|
return count;
|
|
64684
65054
|
}, [selectedLeaderboardShiftId, currentShiftId]);
|
|
64685
|
-
const clearFilters =
|
|
65055
|
+
const clearFilters = React143__default.useCallback(() => {
|
|
64686
65056
|
setSelectedLeaderboardShiftId(currentShiftId);
|
|
64687
65057
|
}, [currentShiftId]);
|
|
64688
65058
|
useEffect(() => {
|
|
@@ -64696,11 +65066,11 @@ var KPIsOverviewView = ({
|
|
|
64696
65066
|
document.addEventListener("mousedown", handleClickOutside);
|
|
64697
65067
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
64698
65068
|
}, []);
|
|
64699
|
-
const shiftEndDate =
|
|
65069
|
+
const shiftEndDate = React143__default.useMemo(
|
|
64700
65070
|
() => getShiftEndDate(currentShiftDetails, configuredTimezone),
|
|
64701
65071
|
[currentShiftDetails, configuredTimezone]
|
|
64702
65072
|
);
|
|
64703
|
-
const leaderboardShiftOptions =
|
|
65073
|
+
const leaderboardShiftOptions = React143__default.useMemo(() => {
|
|
64704
65074
|
if (shiftConfig?.shifts && shiftConfig.shifts.length > 0) {
|
|
64705
65075
|
return shiftConfig.shifts.map((shift) => ({
|
|
64706
65076
|
id: shift.shiftId,
|
|
@@ -64780,15 +65150,15 @@ var KPIsOverviewView = ({
|
|
|
64780
65150
|
lineId: factoryViewId,
|
|
64781
65151
|
userAccessibleLineIds: metricsLineIds
|
|
64782
65152
|
});
|
|
64783
|
-
const defaultKPIs =
|
|
64784
|
-
const kpisByLineId =
|
|
65153
|
+
const defaultKPIs = React143__default.useMemo(() => createDefaultKPIs(), []);
|
|
65154
|
+
const kpisByLineId = React143__default.useMemo(() => {
|
|
64785
65155
|
const map = /* @__PURE__ */ new Map();
|
|
64786
65156
|
lineMetrics.forEach((row) => {
|
|
64787
65157
|
if (row?.line_id) map.set(row.line_id, buildKPIsFromLineMetricsRow(row));
|
|
64788
65158
|
});
|
|
64789
65159
|
return map;
|
|
64790
65160
|
}, [lineMetrics]);
|
|
64791
|
-
const supervisorLineIds =
|
|
65161
|
+
const supervisorLineIds = React143__default.useMemo(
|
|
64792
65162
|
() => (leaderboardLines.length > 0 ? leaderboardLines : lines).map((l) => l.id),
|
|
64793
65163
|
[leaderboardLines, lines]
|
|
64794
65164
|
);
|
|
@@ -65628,39 +65998,6 @@ var KPIsOverviewView = ({
|
|
|
65628
65998
|
] });
|
|
65629
65999
|
};
|
|
65630
66000
|
var KPIsOverviewView_default = KPIsOverviewView;
|
|
65631
|
-
var toFiniteNumber = (value) => {
|
|
65632
|
-
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
65633
|
-
if (typeof value === "string" && value.trim() !== "") {
|
|
65634
|
-
const parsed = Number(value);
|
|
65635
|
-
return Number.isFinite(parsed) ? parsed : null;
|
|
65636
|
-
}
|
|
65637
|
-
return null;
|
|
65638
|
-
};
|
|
65639
|
-
var getCycleRatio = (workspace) => {
|
|
65640
|
-
const idealCycleTime = toFiniteNumber(workspace.ideal_cycle_time);
|
|
65641
|
-
const avgCycleTime = toFiniteNumber(workspace.avg_cycle_time);
|
|
65642
|
-
if (idealCycleTime === null || avgCycleTime === null || idealCycleTime <= 0 || avgCycleTime <= 0) {
|
|
65643
|
-
return null;
|
|
65644
|
-
}
|
|
65645
|
-
return idealCycleTime / avgCycleTime;
|
|
65646
|
-
};
|
|
65647
|
-
var formatCycleTimeValue = (value) => {
|
|
65648
|
-
const numericValue = toFiniteNumber(value);
|
|
65649
|
-
if (numericValue === null || numericValue <= 0) return "--";
|
|
65650
|
-
return `${numericValue.toFixed(1)}s`;
|
|
65651
|
-
};
|
|
65652
|
-
var CycleTimeComparison = memo$1(({
|
|
65653
|
-
workspace
|
|
65654
|
-
}) => {
|
|
65655
|
-
const averageValue = formatCycleTimeValue(workspace.avg_cycle_time);
|
|
65656
|
-
const standardValue = formatCycleTimeValue(workspace.ideal_cycle_time);
|
|
65657
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 tabular-nums", children: [
|
|
65658
|
-
/* @__PURE__ */ jsx("span", { className: "font-semibold text-gray-900", children: averageValue }),
|
|
65659
|
-
/* @__PURE__ */ jsx("span", { className: "text-gray-400 font-normal", children: "/" }),
|
|
65660
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium text-gray-500", children: standardValue })
|
|
65661
|
-
] });
|
|
65662
|
-
}, (prevProps, nextProps) => prevProps.workspace.avg_cycle_time === nextProps.workspace.avg_cycle_time && prevProps.workspace.ideal_cycle_time === nextProps.workspace.ideal_cycle_time);
|
|
65663
|
-
CycleTimeComparison.displayName = "CycleTimeComparison";
|
|
65664
66001
|
var IsolatedTimer = memo$1(() => {
|
|
65665
66002
|
return /* @__PURE__ */ jsx(ISTTimer_default, {});
|
|
65666
66003
|
});
|
|
@@ -65912,7 +66249,7 @@ var LeaderboardDetailView = memo$1(({
|
|
|
65912
66249
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
65913
66250
|
}, []);
|
|
65914
66251
|
const [isMobile, setIsMobile] = useState(false);
|
|
65915
|
-
|
|
66252
|
+
React143__default.useEffect(() => {
|
|
65916
66253
|
const checkMobile = () => setIsMobile(window.innerWidth < 640);
|
|
65917
66254
|
checkMobile();
|
|
65918
66255
|
window.addEventListener("resize", checkMobile);
|
|
@@ -66202,10 +66539,25 @@ var LeaderboardDetailView = memo$1(({
|
|
|
66202
66539
|
setTodayLoading(true);
|
|
66203
66540
|
setTodayError(null);
|
|
66204
66541
|
try {
|
|
66205
|
-
|
|
66542
|
+
if (!supabase) {
|
|
66543
|
+
throw new Error("Supabase client not initialized");
|
|
66544
|
+
}
|
|
66545
|
+
if (!entityConfig.companyId) {
|
|
66546
|
+
throw new Error("Company ID is not configured");
|
|
66547
|
+
}
|
|
66548
|
+
const searchParams = new URLSearchParams({
|
|
66549
|
+
company_id: entityConfig.companyId,
|
|
66206
66550
|
date: todayDate,
|
|
66207
|
-
|
|
66551
|
+
shift_id: todayShiftId.toString()
|
|
66208
66552
|
});
|
|
66553
|
+
if (configuredLineIds.length > 0) {
|
|
66554
|
+
searchParams.set("line_ids", configuredLineIds.join(","));
|
|
66555
|
+
}
|
|
66556
|
+
const metricsData = await fetchBackendJson(
|
|
66557
|
+
supabase,
|
|
66558
|
+
`/api/dashboard/metrics?${searchParams.toString()}`
|
|
66559
|
+
);
|
|
66560
|
+
const entries = metricsData.workspace_metrics || [];
|
|
66209
66561
|
if (todayRequestKeyRef.current !== requestKey) {
|
|
66210
66562
|
return;
|
|
66211
66563
|
}
|
|
@@ -66222,7 +66574,15 @@ var LeaderboardDetailView = memo$1(({
|
|
|
66222
66574
|
setTodayLoading(false);
|
|
66223
66575
|
}
|
|
66224
66576
|
}
|
|
66225
|
-
}, [
|
|
66577
|
+
}, [
|
|
66578
|
+
configuredLineIds,
|
|
66579
|
+
entityConfig.companyId,
|
|
66580
|
+
mapEntriesToWorkspaces,
|
|
66581
|
+
supabase,
|
|
66582
|
+
todayDate,
|
|
66583
|
+
todayShiftId,
|
|
66584
|
+
lineKey
|
|
66585
|
+
]);
|
|
66226
66586
|
const queueTodayLeaderboardRefresh = useCallback(() => {
|
|
66227
66587
|
if (leaderboardUpdateQueuedRef.current) return;
|
|
66228
66588
|
leaderboardUpdateQueuedRef.current = true;
|
|
@@ -68308,7 +68668,7 @@ var ShiftsView = ({
|
|
|
68308
68668
|
] })
|
|
68309
68669
|
] });
|
|
68310
68670
|
};
|
|
68311
|
-
var AuthenticatedShiftsView = withAuth(
|
|
68671
|
+
var AuthenticatedShiftsView = withAuth(React143__default.memo(ShiftsView));
|
|
68312
68672
|
var ShiftsView_default = ShiftsView;
|
|
68313
68673
|
|
|
68314
68674
|
// src/views/TargetsView.utils.ts
|
|
@@ -70010,7 +70370,7 @@ var TargetsView = ({
|
|
|
70010
70370
|
};
|
|
70011
70371
|
var TargetsViewWithDisplayNames = withAllWorkspaceDisplayNames(TargetsView);
|
|
70012
70372
|
var TargetsView_default = TargetsViewWithDisplayNames;
|
|
70013
|
-
var AuthenticatedTargetsView = withAuth(
|
|
70373
|
+
var AuthenticatedTargetsView = withAuth(React143__default.memo(TargetsViewWithDisplayNames));
|
|
70014
70374
|
function useTimezone(options = {}) {
|
|
70015
70375
|
const dashboardConfig = useDashboardConfig();
|
|
70016
70376
|
const workspaceConfig = useWorkspaceConfig();
|
|
@@ -73429,7 +73789,7 @@ function BottleneckClipsView({
|
|
|
73429
73789
|
) })
|
|
73430
73790
|
] }) });
|
|
73431
73791
|
}
|
|
73432
|
-
var AuthenticatedBottleneckClipsView = withAuth(
|
|
73792
|
+
var AuthenticatedBottleneckClipsView = withAuth(React143__default.memo(BottleneckClipsView));
|
|
73433
73793
|
var BottleneckClipsView_default = BottleneckClipsView;
|
|
73434
73794
|
|
|
73435
73795
|
// src/lib/services/ticketService.ts
|
|
@@ -73459,8 +73819,8 @@ var TicketService = class {
|
|
|
73459
73819
|
return response;
|
|
73460
73820
|
} catch (error) {
|
|
73461
73821
|
lastError = error instanceof Error ? error : new Error(String(error));
|
|
73462
|
-
const
|
|
73463
|
-
if (!
|
|
73822
|
+
const isRetryableError2 = lastError.message.includes("network") || lastError.message.includes("Failed to fetch") || lastError.message.includes("fetch failed") || lastError.message.includes("aborted") || lastError.message.includes("ENOTFOUND") || lastError.message.includes("ECONNREFUSED") || lastError.message.includes("503");
|
|
73823
|
+
if (!isRetryableError2 || attempt === retries) {
|
|
73464
73824
|
throw lastError;
|
|
73465
73825
|
}
|
|
73466
73826
|
const delay2 = 1e3 * Math.pow(2, attempt);
|
|
@@ -73475,69 +73835,78 @@ var TicketService = class {
|
|
|
73475
73835
|
* Uses the user's JWT access token from Supabase session (NOT the anon key)
|
|
73476
73836
|
*/
|
|
73477
73837
|
async fetchWithAuth(url, options = {}) {
|
|
73478
|
-
|
|
73479
|
-
|
|
73480
|
-
|
|
73481
|
-
const { data: { session }, error: sessionError } = await this.supabaseClient.auth.getSession();
|
|
73482
|
-
if (sessionError) {
|
|
73483
|
-
console.error("Session error:", sessionError);
|
|
73484
|
-
throw new Error("Failed to get authentication session. Please log in.");
|
|
73485
|
-
}
|
|
73486
|
-
if (!session) {
|
|
73487
|
-
console.error("No session found. User must be logged in.");
|
|
73488
|
-
throw new Error("User not authenticated. Please log in.");
|
|
73489
|
-
}
|
|
73490
|
-
if (!session.access_token) {
|
|
73491
|
-
console.error("Session exists but no access_token found");
|
|
73492
|
-
throw new Error("Invalid session. Please log in again.");
|
|
73493
|
-
}
|
|
73494
|
-
const token = session.access_token;
|
|
73495
|
-
if (process.env.NODE_ENV === "development") {
|
|
73496
|
-
console.log("[TicketService] Using JWT token (first 20 chars):", token.substring(0, 20) + "...");
|
|
73497
|
-
console.log("[TicketService] Token is NOT the anon key - it is the user JWT from session.access_token");
|
|
73498
|
-
}
|
|
73499
|
-
const headers = {
|
|
73500
|
-
"Content-Type": "application/json",
|
|
73501
|
-
...options.headers,
|
|
73502
|
-
"Authorization": `Bearer ${token}`
|
|
73503
|
-
// This is the USER's JWT, not the anon key
|
|
73504
|
-
};
|
|
73505
|
-
const response = await this.fetchWithRetry(url, {
|
|
73506
|
-
...options,
|
|
73507
|
-
headers
|
|
73508
|
-
});
|
|
73509
|
-
if (response.status === 401) {
|
|
73510
|
-
console.error("401 Unauthorized - Token expired or invalid");
|
|
73511
|
-
throw new Error("Authentication failed. Token expired or invalid. Please log in again.");
|
|
73512
|
-
}
|
|
73513
|
-
if (response.status === 403) {
|
|
73514
|
-
console.error("403 Forbidden - User does not have permission");
|
|
73515
|
-
throw new Error("Access denied. You do not have permission to access this resource.");
|
|
73516
|
-
}
|
|
73517
|
-
if (response.status === 500) {
|
|
73518
|
-
console.error("500 Internal Server Error - Backend error");
|
|
73519
|
-
let errorDetail = "Internal server error occurred.";
|
|
73520
|
-
try {
|
|
73521
|
-
const errorData = await response.text();
|
|
73522
|
-
console.error("Backend error details:", errorData);
|
|
73523
|
-
errorDetail = errorData || errorDetail;
|
|
73524
|
-
} catch (e) {
|
|
73838
|
+
try {
|
|
73839
|
+
if (!this.supabaseClient) {
|
|
73840
|
+
throw new Error("Supabase client not initialized. Please provide a Supabase client to TicketService.");
|
|
73525
73841
|
}
|
|
73526
|
-
|
|
73527
|
-
|
|
73528
|
-
|
|
73529
|
-
|
|
73530
|
-
|
|
73531
|
-
|
|
73532
|
-
|
|
73533
|
-
|
|
73534
|
-
|
|
73842
|
+
const { data: { session }, error: sessionError } = await this.supabaseClient.auth.getSession();
|
|
73843
|
+
if (sessionError) {
|
|
73844
|
+
console.error("Session error:", sessionError);
|
|
73845
|
+
throw new Error("Failed to get authentication session. Please log in.");
|
|
73846
|
+
}
|
|
73847
|
+
if (!session) {
|
|
73848
|
+
console.error("No session found. User must be logged in.");
|
|
73849
|
+
throw new Error("User not authenticated. Please log in.");
|
|
73850
|
+
}
|
|
73851
|
+
if (!session.access_token) {
|
|
73852
|
+
console.error("Session exists but no access_token found");
|
|
73853
|
+
throw new Error("Invalid session. Please log in again.");
|
|
73854
|
+
}
|
|
73855
|
+
const token = session.access_token;
|
|
73856
|
+
if (process.env.NODE_ENV === "development") {
|
|
73857
|
+
console.log("[TicketService] Using JWT token (first 20 chars):", token.substring(0, 20) + "...");
|
|
73858
|
+
console.log("[TicketService] Token is NOT the anon key - it is the user JWT from session.access_token");
|
|
73859
|
+
}
|
|
73860
|
+
const headers = {
|
|
73861
|
+
"Content-Type": "application/json",
|
|
73862
|
+
...options.headers,
|
|
73863
|
+
"Authorization": `Bearer ${token}`
|
|
73864
|
+
};
|
|
73865
|
+
const response = await this.fetchWithRetry(url, {
|
|
73866
|
+
...options,
|
|
73867
|
+
headers
|
|
73868
|
+
});
|
|
73869
|
+
if (response.status === 401) {
|
|
73870
|
+
console.error("401 Unauthorized - Token expired or invalid");
|
|
73871
|
+
throw new Error("Authentication failed. Token expired or invalid. Please log in again.");
|
|
73872
|
+
}
|
|
73873
|
+
if (response.status === 403) {
|
|
73874
|
+
console.error("403 Forbidden - User does not have permission");
|
|
73875
|
+
throw new Error("Access denied. You do not have permission to access this resource.");
|
|
73876
|
+
}
|
|
73877
|
+
if (response.status === 500) {
|
|
73878
|
+
console.error("500 Internal Server Error - Backend error");
|
|
73879
|
+
let errorDetail = "Internal server error occurred.";
|
|
73880
|
+
try {
|
|
73881
|
+
const errorData = await response.text();
|
|
73882
|
+
console.error("Backend error details:", errorData);
|
|
73883
|
+
errorDetail = errorData || errorDetail;
|
|
73884
|
+
} catch (e) {
|
|
73535
73885
|
}
|
|
73536
|
-
|
|
73886
|
+
throw new Error(`Backend error: ${errorDetail}`);
|
|
73887
|
+
}
|
|
73888
|
+
if (!response.ok) {
|
|
73889
|
+
console.error(`HTTP ${response.status} - ${response.statusText}`);
|
|
73890
|
+
let errorDetail = response.statusText;
|
|
73891
|
+
try {
|
|
73892
|
+
const errorData = await response.json();
|
|
73893
|
+
if (errorData.detail) {
|
|
73894
|
+
errorDetail = errorData.detail;
|
|
73895
|
+
}
|
|
73896
|
+
} catch (e) {
|
|
73897
|
+
}
|
|
73898
|
+
throw new Error(`Request failed (${response.status}): ${errorDetail}`);
|
|
73537
73899
|
}
|
|
73538
|
-
|
|
73900
|
+
return response;
|
|
73901
|
+
} catch (error) {
|
|
73902
|
+
captureHandledFrontendException(error, {
|
|
73903
|
+
surface: "ticket_service",
|
|
73904
|
+
url,
|
|
73905
|
+
method: options.method || "GET",
|
|
73906
|
+
pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
|
|
73907
|
+
});
|
|
73908
|
+
throw error;
|
|
73539
73909
|
}
|
|
73540
|
-
return response;
|
|
73541
73910
|
}
|
|
73542
73911
|
/**
|
|
73543
73912
|
* Get tickets with filters and pagination
|
|
@@ -74260,7 +74629,7 @@ Please ensure:
|
|
|
74260
74629
|
)
|
|
74261
74630
|
] });
|
|
74262
74631
|
}
|
|
74263
|
-
var AuthenticatedTicketsView = withAuth(
|
|
74632
|
+
var AuthenticatedTicketsView = withAuth(React143__default.memo(TicketsView));
|
|
74264
74633
|
var TicketsView_default = TicketsView;
|
|
74265
74634
|
|
|
74266
74635
|
// src/lib/utils/improvementDisplay.ts
|
|
@@ -75231,7 +75600,7 @@ var ImprovementCenterView = () => {
|
|
|
75231
75600
|
setSelectedMemberId("all");
|
|
75232
75601
|
}
|
|
75233
75602
|
}, [memberOptions, selectedMemberId]);
|
|
75234
|
-
const getRecommendationDisplayMetadata =
|
|
75603
|
+
const getRecommendationDisplayMetadata = React143__default.useCallback((rec) => {
|
|
75235
75604
|
const supervisors = rec.line_id ? supervisorsByLineId.get(rec.line_id) || [] : [];
|
|
75236
75605
|
return getImprovementDisplayMetadata({
|
|
75237
75606
|
location: rec.location,
|
|
@@ -75705,7 +76074,7 @@ var ThreadSidebar = ({
|
|
|
75705
76074
|
] }) })
|
|
75706
76075
|
] });
|
|
75707
76076
|
};
|
|
75708
|
-
var ProfilePicture =
|
|
76077
|
+
var ProfilePicture = React143__default.memo(({
|
|
75709
76078
|
alt = "Axel",
|
|
75710
76079
|
className = "",
|
|
75711
76080
|
size = "md",
|
|
@@ -78230,7 +78599,7 @@ var OverviewImprovementsSkeleton = () => /* @__PURE__ */ jsx("div", { className:
|
|
|
78230
78599
|
] }),
|
|
78231
78600
|
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-end flex-shrink-0 ml-4", children: /* @__PURE__ */ jsx(SectionPulse, { className: "h-6 w-20 rounded-full" }) })
|
|
78232
78601
|
] }, index)) });
|
|
78233
|
-
var OperationsOverviewHeader =
|
|
78602
|
+
var OperationsOverviewHeader = React143__default.memo(({
|
|
78234
78603
|
dateRange,
|
|
78235
78604
|
displayDateRange,
|
|
78236
78605
|
trendMode,
|
|
@@ -78250,65 +78619,65 @@ var OperationsOverviewHeader = React142__default.memo(({
|
|
|
78250
78619
|
bumpRenderCounter();
|
|
78251
78620
|
const subtitleRange = displayDateRange || dateRange;
|
|
78252
78621
|
const showLiveShiftMeta = isLiveScope && trendMode !== "all";
|
|
78253
|
-
const liveShiftLabel =
|
|
78622
|
+
const liveShiftLabel = React143__default.useMemo(
|
|
78254
78623
|
() => normalizeShiftLabel(liveShiftName, trendMode),
|
|
78255
78624
|
[liveShiftName, trendMode]
|
|
78256
78625
|
);
|
|
78257
|
-
const liveShiftIcon =
|
|
78626
|
+
const liveShiftIcon = React143__default.useMemo(
|
|
78258
78627
|
() => getShiftIcon(liveShiftName, trendMode),
|
|
78259
78628
|
[liveShiftName, trendMode]
|
|
78260
78629
|
);
|
|
78261
|
-
const [isFilterOpen, setIsFilterOpen] =
|
|
78262
|
-
const [isLinesDropdownOpen, setIsLinesDropdownOpen] =
|
|
78263
|
-
const filterRef =
|
|
78264
|
-
const filterButtonRef =
|
|
78265
|
-
const mobileFilterButtonRef =
|
|
78266
|
-
const linesDropdownRef =
|
|
78267
|
-
const mobileSubtitle =
|
|
78630
|
+
const [isFilterOpen, setIsFilterOpen] = React143__default.useState(false);
|
|
78631
|
+
const [isLinesDropdownOpen, setIsLinesDropdownOpen] = React143__default.useState(false);
|
|
78632
|
+
const filterRef = React143__default.useRef(null);
|
|
78633
|
+
const filterButtonRef = React143__default.useRef(null);
|
|
78634
|
+
const mobileFilterButtonRef = React143__default.useRef(null);
|
|
78635
|
+
const linesDropdownRef = React143__default.useRef(null);
|
|
78636
|
+
const mobileSubtitle = React143__default.useMemo(() => {
|
|
78268
78637
|
if (subtitleRange.startKey === subtitleRange.endKey) {
|
|
78269
78638
|
return format(parseDateKeyToDate(subtitleRange.startKey), "do MMM, yyyy");
|
|
78270
78639
|
}
|
|
78271
78640
|
return `${format(parseDateKeyToDate(subtitleRange.startKey), "do MMM")} - ${format(parseDateKeyToDate(subtitleRange.endKey), "do MMM, yyyy")}`;
|
|
78272
78641
|
}, [subtitleRange.endKey, subtitleRange.startKey]);
|
|
78273
|
-
const desktopSubtitle =
|
|
78642
|
+
const desktopSubtitle = React143__default.useMemo(() => {
|
|
78274
78643
|
if (subtitleRange.startKey === subtitleRange.endKey) {
|
|
78275
78644
|
return format(parseDateKeyToDate(subtitleRange.startKey), "do MMMM, yyyy");
|
|
78276
78645
|
}
|
|
78277
78646
|
return `${format(parseDateKeyToDate(subtitleRange.startKey), "do MMMM, yyyy")} - ${format(parseDateKeyToDate(subtitleRange.endKey), "do MMMM, yyyy")}`;
|
|
78278
78647
|
}, [subtitleRange.endKey, subtitleRange.startKey]);
|
|
78279
|
-
const availableLineIds =
|
|
78648
|
+
const availableLineIds = React143__default.useMemo(
|
|
78280
78649
|
() => lineOptions.map((line) => line.id),
|
|
78281
78650
|
[lineOptions]
|
|
78282
78651
|
);
|
|
78283
|
-
const selectedLineIdSet =
|
|
78652
|
+
const selectedLineIdSet = React143__default.useMemo(
|
|
78284
78653
|
() => new Set(selectedLineIds),
|
|
78285
78654
|
[selectedLineIds]
|
|
78286
78655
|
);
|
|
78287
|
-
const isAllLinesSelected =
|
|
78656
|
+
const isAllLinesSelected = React143__default.useMemo(() => {
|
|
78288
78657
|
if (availableLineIds.length === 0) return true;
|
|
78289
78658
|
return availableLineIds.every((lineId) => selectedLineIdSet.has(lineId));
|
|
78290
78659
|
}, [availableLineIds, selectedLineIdSet]);
|
|
78291
|
-
const activeFilterCount =
|
|
78660
|
+
const activeFilterCount = React143__default.useMemo(() => {
|
|
78292
78661
|
let count = 0;
|
|
78293
78662
|
if (trendMode !== "all") count += 1;
|
|
78294
78663
|
if (selectedSupervisorId !== "all") count += 1;
|
|
78295
78664
|
if (!isAllLinesSelected) count += 1;
|
|
78296
78665
|
return count;
|
|
78297
78666
|
}, [isAllLinesSelected, selectedSupervisorId, trendMode]);
|
|
78298
|
-
const handleFilterToggle =
|
|
78667
|
+
const handleFilterToggle = React143__default.useCallback(() => {
|
|
78299
78668
|
trackCoreEvent("Operations Overview Filter Toggled", {
|
|
78300
78669
|
action: !isFilterOpen ? "open" : "close"
|
|
78301
78670
|
});
|
|
78302
78671
|
setIsFilterOpen((previous) => !previous);
|
|
78303
78672
|
}, [isFilterOpen]);
|
|
78304
|
-
const handleTrendModeChange =
|
|
78673
|
+
const handleTrendModeChange = React143__default.useCallback((event) => {
|
|
78305
78674
|
const nextMode = event.target.value;
|
|
78306
78675
|
trackCoreEvent("Operations Overview Shift Filter Changed", {
|
|
78307
78676
|
shift_mode: nextMode
|
|
78308
78677
|
});
|
|
78309
78678
|
onTrendModeChange(nextMode);
|
|
78310
78679
|
}, [onTrendModeChange]);
|
|
78311
|
-
const handleAllLinesToggle =
|
|
78680
|
+
const handleAllLinesToggle = React143__default.useCallback(() => {
|
|
78312
78681
|
trackCoreEvent("Operations Overview Line Filter Changed", {
|
|
78313
78682
|
selected_line_ids: availableLineIds,
|
|
78314
78683
|
selected_line_count: availableLineIds.length,
|
|
@@ -78316,7 +78685,7 @@ var OperationsOverviewHeader = React142__default.memo(({
|
|
|
78316
78685
|
});
|
|
78317
78686
|
onSelectedLineIdsChange(availableLineIds);
|
|
78318
78687
|
}, [availableLineIds, onSelectedLineIdsChange]);
|
|
78319
|
-
const handleSupervisorChange =
|
|
78688
|
+
const handleSupervisorChange = React143__default.useCallback((event) => {
|
|
78320
78689
|
const supervisorId = event.target.value;
|
|
78321
78690
|
const selectedSupervisor = supervisorOptions.find((option) => option.id === supervisorId);
|
|
78322
78691
|
trackCoreEvent("Operations Overview Supervisor Filter Changed", {
|
|
@@ -78327,7 +78696,7 @@ var OperationsOverviewHeader = React142__default.memo(({
|
|
|
78327
78696
|
});
|
|
78328
78697
|
onSelectedSupervisorIdChange(supervisorId);
|
|
78329
78698
|
}, [availableLineIds, onSelectedSupervisorIdChange, supervisorOptions]);
|
|
78330
|
-
const handleLineToggle =
|
|
78699
|
+
const handleLineToggle = React143__default.useCallback((lineId) => {
|
|
78331
78700
|
const current = new Set(selectedLineIds);
|
|
78332
78701
|
if (current.has(lineId)) {
|
|
78333
78702
|
if (current.size <= 1) return;
|
|
@@ -78343,13 +78712,13 @@ var OperationsOverviewHeader = React142__default.memo(({
|
|
|
78343
78712
|
});
|
|
78344
78713
|
onSelectedLineIdsChange(next);
|
|
78345
78714
|
}, [availableLineIds, onSelectedLineIdsChange, selectedLineIds]);
|
|
78346
|
-
const handleClearAllFilters =
|
|
78715
|
+
const handleClearAllFilters = React143__default.useCallback(() => {
|
|
78347
78716
|
onTrendModeChange("all");
|
|
78348
78717
|
onSelectedSupervisorIdChange("all");
|
|
78349
78718
|
onSelectedLineIdsChange(availableLineIds);
|
|
78350
78719
|
setIsFilterOpen(false);
|
|
78351
78720
|
}, [availableLineIds, onSelectedLineIdsChange, onSelectedSupervisorIdChange, onTrendModeChange]);
|
|
78352
|
-
|
|
78721
|
+
React143__default.useEffect(() => {
|
|
78353
78722
|
const handleClickOutside = (event) => {
|
|
78354
78723
|
const target = event.target;
|
|
78355
78724
|
if (filterRef.current && !filterRef.current.contains(target) && filterButtonRef.current && !filterButtonRef.current.contains(target) && mobileFilterButtonRef.current && !mobileFilterButtonRef.current.contains(target)) {
|
|
@@ -78588,12 +78957,12 @@ var OperationsOverviewHeader = React142__default.memo(({
|
|
|
78588
78957
|
] }) });
|
|
78589
78958
|
});
|
|
78590
78959
|
OperationsOverviewHeader.displayName = "OperationsOverviewHeader";
|
|
78591
|
-
var OverviewSummaryCards =
|
|
78960
|
+
var OverviewSummaryCards = React143__default.memo(({ store }) => {
|
|
78592
78961
|
bumpRenderCounter();
|
|
78593
78962
|
const scope = useOperationsOverviewScope(store);
|
|
78594
78963
|
const snapshot = useOperationsOverviewSnapshot(store);
|
|
78595
78964
|
const showSnapshotSkeleton = snapshot.loading && !snapshot.hasLoadedOnce;
|
|
78596
|
-
const comparisonLabel =
|
|
78965
|
+
const comparisonLabel = React143__default.useMemo(() => {
|
|
78597
78966
|
return formatComparisonWindow({
|
|
78598
78967
|
currentDayCount: scope.current_range?.day_count ?? null,
|
|
78599
78968
|
previousDayCount: scope.previous_range?.day_count ?? null,
|
|
@@ -78606,27 +78975,27 @@ var OverviewSummaryCards = React142__default.memo(({ store }) => {
|
|
|
78606
78975
|
scope.previous_range?.day_count,
|
|
78607
78976
|
scope.shift_mode
|
|
78608
78977
|
]);
|
|
78609
|
-
const [isIdleContributorsOpen, setIsIdleContributorsOpen] =
|
|
78610
|
-
const [isIdleContributorsPinned, setIsIdleContributorsPinned] =
|
|
78611
|
-
const idleContributorsRef =
|
|
78612
|
-
const plantEfficiencyBadge =
|
|
78978
|
+
const [isIdleContributorsOpen, setIsIdleContributorsOpen] = React143__default.useState(false);
|
|
78979
|
+
const [isIdleContributorsPinned, setIsIdleContributorsPinned] = React143__default.useState(false);
|
|
78980
|
+
const idleContributorsRef = React143__default.useRef(null);
|
|
78981
|
+
const plantEfficiencyBadge = React143__default.useMemo(() => {
|
|
78613
78982
|
return buildDeltaBadge(snapshot.data.summary.plant_efficiency?.delta_pp, {
|
|
78614
78983
|
positiveIsGood: true,
|
|
78615
78984
|
formatter: (value) => `${value >= 0 ? "+" : ""}${roundOne(value)}%`,
|
|
78616
78985
|
comparisonLabel
|
|
78617
78986
|
});
|
|
78618
78987
|
}, [comparisonLabel, snapshot.data.summary.plant_efficiency?.delta_pp]);
|
|
78619
|
-
const idleBadge =
|
|
78988
|
+
const idleBadge = React143__default.useMemo(() => {
|
|
78620
78989
|
return buildDeltaBadge(snapshot.data.summary.avg_idle_per_workstation?.delta_seconds, {
|
|
78621
78990
|
positiveIsGood: false,
|
|
78622
78991
|
formatter: (value) => formatSignedIdleDuration(value),
|
|
78623
78992
|
comparisonLabel
|
|
78624
78993
|
});
|
|
78625
78994
|
}, [comparisonLabel, snapshot.data.summary.avg_idle_per_workstation?.delta_seconds]);
|
|
78626
|
-
const canInspectIdleContributors =
|
|
78995
|
+
const canInspectIdleContributors = React143__default.useMemo(() => {
|
|
78627
78996
|
return !showSnapshotSkeleton && snapshot.data.summary.avg_idle_per_workstation?.current_seconds !== null && snapshot.data.summary.avg_idle_per_workstation?.current_seconds !== void 0;
|
|
78628
78997
|
}, [showSnapshotSkeleton, snapshot.data.summary.avg_idle_per_workstation?.current_seconds]);
|
|
78629
|
-
const idleTopContributors =
|
|
78998
|
+
const idleTopContributors = React143__default.useMemo(() => {
|
|
78630
78999
|
return (snapshot.data.summary.avg_idle_per_workstation?.top_contributors || []).map((item) => ({
|
|
78631
79000
|
workspaceId: item.workspace_id || "",
|
|
78632
79001
|
workspaceName: item.workspace_name?.trim() || item.workspace_id || "Unknown",
|
|
@@ -78634,14 +79003,14 @@ var OverviewSummaryCards = React142__default.memo(({ store }) => {
|
|
|
78634
79003
|
avgIdleSeconds: toNumber3(item.avg_idle_seconds)
|
|
78635
79004
|
})).slice(0, 5);
|
|
78636
79005
|
}, [snapshot.data.summary.avg_idle_per_workstation?.top_contributors]);
|
|
78637
|
-
const showIdleContributorLineNames =
|
|
79006
|
+
const showIdleContributorLineNames = React143__default.useMemo(() => {
|
|
78638
79007
|
return (scope.line_count ?? 0) > 1;
|
|
78639
79008
|
}, [scope.line_count]);
|
|
78640
|
-
const closeIdleContributors =
|
|
79009
|
+
const closeIdleContributors = React143__default.useCallback(() => {
|
|
78641
79010
|
setIsIdleContributorsOpen(false);
|
|
78642
79011
|
setIsIdleContributorsPinned(false);
|
|
78643
79012
|
}, []);
|
|
78644
|
-
const handleIdleContributorsToggle =
|
|
79013
|
+
const handleIdleContributorsToggle = React143__default.useCallback(() => {
|
|
78645
79014
|
if (!canInspectIdleContributors) return;
|
|
78646
79015
|
setIsIdleContributorsPinned((previous) => {
|
|
78647
79016
|
const next = !previous;
|
|
@@ -78649,7 +79018,7 @@ var OverviewSummaryCards = React142__default.memo(({ store }) => {
|
|
|
78649
79018
|
return next;
|
|
78650
79019
|
});
|
|
78651
79020
|
}, [canInspectIdleContributors]);
|
|
78652
|
-
const handleIdleContributorsKeyDown =
|
|
79021
|
+
const handleIdleContributorsKeyDown = React143__default.useCallback((event) => {
|
|
78653
79022
|
if (!canInspectIdleContributors) return;
|
|
78654
79023
|
if (event.key === "Enter" || event.key === " ") {
|
|
78655
79024
|
event.preventDefault();
|
|
@@ -78661,11 +79030,11 @@ var OverviewSummaryCards = React142__default.memo(({ store }) => {
|
|
|
78661
79030
|
closeIdleContributors();
|
|
78662
79031
|
}
|
|
78663
79032
|
}, [canInspectIdleContributors, closeIdleContributors, handleIdleContributorsToggle]);
|
|
78664
|
-
|
|
79033
|
+
React143__default.useEffect(() => {
|
|
78665
79034
|
setIsIdleContributorsOpen(false);
|
|
78666
79035
|
setIsIdleContributorsPinned(false);
|
|
78667
79036
|
}, [scope.comparison_strategy, scope.current_range?.start_date, scope.current_range?.end_date, scope.line_count, scope.shift_mode]);
|
|
78668
|
-
|
|
79037
|
+
React143__default.useEffect(() => {
|
|
78669
79038
|
if (!isIdleContributorsOpen) return void 0;
|
|
78670
79039
|
const handleClickOutside = (event) => {
|
|
78671
79040
|
if (!isIdleContributorsPinned) return;
|
|
@@ -78803,7 +79172,7 @@ var OverviewSummaryCards = React142__default.memo(({ store }) => {
|
|
|
78803
79172
|
] });
|
|
78804
79173
|
});
|
|
78805
79174
|
OverviewSummaryCards.displayName = "OverviewSummaryCards";
|
|
78806
|
-
var PoorestPerformersCard =
|
|
79175
|
+
var PoorestPerformersCard = React143__default.memo(({
|
|
78807
79176
|
store,
|
|
78808
79177
|
supervisorsByLineId,
|
|
78809
79178
|
onViewAll,
|
|
@@ -78812,9 +79181,9 @@ var PoorestPerformersCard = React142__default.memo(({
|
|
|
78812
79181
|
bumpRenderCounter();
|
|
78813
79182
|
const scope = useOperationsOverviewScope(store);
|
|
78814
79183
|
const snapshot = useOperationsOverviewSnapshot(store);
|
|
78815
|
-
const [poorestLineMode, setPoorestLineMode] =
|
|
79184
|
+
const [poorestLineMode, setPoorestLineMode] = React143__default.useState("output");
|
|
78816
79185
|
const availableLineModes = scope.available_line_modes;
|
|
78817
|
-
|
|
79186
|
+
React143__default.useEffect(() => {
|
|
78818
79187
|
const hasOutput = !!availableLineModes?.has_output;
|
|
78819
79188
|
const hasUptime = !!availableLineModes?.has_uptime;
|
|
78820
79189
|
if (hasOutput && !hasUptime && poorestLineMode !== "output") {
|
|
@@ -78823,7 +79192,7 @@ var PoorestPerformersCard = React142__default.memo(({
|
|
|
78823
79192
|
setPoorestLineMode("uptime");
|
|
78824
79193
|
}
|
|
78825
79194
|
}, [availableLineModes?.has_output, availableLineModes?.has_uptime, poorestLineMode]);
|
|
78826
|
-
const comparisonLabel =
|
|
79195
|
+
const comparisonLabel = React143__default.useMemo(() => {
|
|
78827
79196
|
return formatComparisonWindow({
|
|
78828
79197
|
currentDayCount: scope.current_range?.day_count ?? null,
|
|
78829
79198
|
previousDayCount: scope.previous_range?.day_count ?? null,
|
|
@@ -78837,7 +79206,7 @@ var PoorestPerformersCard = React142__default.memo(({
|
|
|
78837
79206
|
scope.shift_mode
|
|
78838
79207
|
]);
|
|
78839
79208
|
const showSnapshotSkeleton = snapshot.loading && !snapshot.hasLoadedOnce;
|
|
78840
|
-
const mergedPoorestLines =
|
|
79209
|
+
const mergedPoorestLines = React143__default.useMemo(() => {
|
|
78841
79210
|
const rows = snapshot.data.poorest_lines?.[poorestLineMode] || [];
|
|
78842
79211
|
return rows.slice(0, 3).map((line) => {
|
|
78843
79212
|
const lineId = line.line_id || "";
|
|
@@ -78856,7 +79225,7 @@ var PoorestPerformersCard = React142__default.memo(({
|
|
|
78856
79225
|
}, [poorestLineMode, snapshot.data.poorest_lines, supervisorsByLineId]);
|
|
78857
79226
|
const showPoorestModeToggle = !!availableLineModes?.has_output && !!availableLineModes?.has_uptime;
|
|
78858
79227
|
const poorestMetricLabel = poorestLineMode === "uptime" ? "Uptime" : "Efficiency";
|
|
78859
|
-
const handlePoorestLineModeChange =
|
|
79228
|
+
const handlePoorestLineModeChange = React143__default.useCallback((mode) => {
|
|
78860
79229
|
trackCoreEvent("Operations Overview Poorest Line Mode Changed", { mode });
|
|
78861
79230
|
setPoorestLineMode(mode);
|
|
78862
79231
|
}, []);
|
|
@@ -78942,14 +79311,14 @@ var PoorestPerformersCard = React142__default.memo(({
|
|
|
78942
79311
|
] });
|
|
78943
79312
|
});
|
|
78944
79313
|
PoorestPerformersCard.displayName = "PoorestPerformersCard";
|
|
78945
|
-
var IdleBreakdownCard =
|
|
79314
|
+
var IdleBreakdownCard = React143__default.memo(({
|
|
78946
79315
|
store,
|
|
78947
79316
|
scopedLineCount
|
|
78948
79317
|
}) => {
|
|
78949
79318
|
bumpRenderCounter();
|
|
78950
79319
|
const idle = useOperationsOverviewIdle(store);
|
|
78951
79320
|
const showInitialSkeleton = idle.loading && idle.lastUpdated === null;
|
|
78952
|
-
const idleBreakdown =
|
|
79321
|
+
const idleBreakdown = React143__default.useMemo(() => {
|
|
78953
79322
|
return idle.data.map((item) => ({
|
|
78954
79323
|
name: item.display_name?.trim() || item.reason?.trim() || "Unknown",
|
|
78955
79324
|
reasonKey: item.reason_key?.trim() || item.reason?.trim() || "unknown",
|
|
@@ -78968,7 +79337,7 @@ var IdleBreakdownCard = React142__default.memo(({
|
|
|
78968
79337
|
}))
|
|
78969
79338
|
})).filter((item) => item.value > 0);
|
|
78970
79339
|
}, [idle.data]);
|
|
78971
|
-
const showIdleModuleNotEnabledState =
|
|
79340
|
+
const showIdleModuleNotEnabledState = React143__default.useMemo(() => {
|
|
78972
79341
|
const enabledLineCount = idle.scope.idle_time_vlm_enabled_line_count;
|
|
78973
79342
|
return !showInitialSkeleton && scopedLineCount > 0 && typeof enabledLineCount === "number" && enabledLineCount === 0;
|
|
78974
79343
|
}, [idle.scope.idle_time_vlm_enabled_line_count, scopedLineCount, showInitialSkeleton]);
|
|
@@ -78989,7 +79358,7 @@ var IdleBreakdownCard = React142__default.memo(({
|
|
|
78989
79358
|
] });
|
|
78990
79359
|
});
|
|
78991
79360
|
IdleBreakdownCard.displayName = "IdleBreakdownCard";
|
|
78992
|
-
var EfficiencyTrendCard =
|
|
79361
|
+
var EfficiencyTrendCard = React143__default.memo(({
|
|
78993
79362
|
store,
|
|
78994
79363
|
dateRange,
|
|
78995
79364
|
appTimezone,
|
|
@@ -78997,14 +79366,14 @@ var EfficiencyTrendCard = React142__default.memo(({
|
|
|
78997
79366
|
}) => {
|
|
78998
79367
|
bumpRenderCounter();
|
|
78999
79368
|
const trend = useOperationsOverviewTrend(store);
|
|
79000
|
-
const currentWeekRange =
|
|
79369
|
+
const currentWeekRange = React143__default.useMemo(
|
|
79001
79370
|
() => getCurrentWeekToDateRange(appTimezone),
|
|
79002
79371
|
[appTimezone]
|
|
79003
79372
|
);
|
|
79004
79373
|
const isCurrentWeekToDateRange = dateRange.startKey === currentWeekRange.startKey && dateRange.endKey === currentWeekRange.endKey;
|
|
79005
79374
|
const showInitialSkeleton = trend.loading && trend.lastUpdated === null;
|
|
79006
79375
|
const isHourlyTrend = trend.data.granularity === "hour";
|
|
79007
|
-
const trendData =
|
|
79376
|
+
const trendData = React143__default.useMemo(() => {
|
|
79008
79377
|
if (isHourlyTrend) {
|
|
79009
79378
|
return (trend.data.points || []).map((point, index) => ({
|
|
79010
79379
|
name: (() => {
|
|
@@ -79076,13 +79445,13 @@ var EfficiencyTrendCard = React142__default.memo(({
|
|
|
79076
79445
|
};
|
|
79077
79446
|
});
|
|
79078
79447
|
}, [currentWeekRange.startKey, hourlyLabelStartTime, isCurrentWeekToDateRange, isHourlyTrend, trend.data.points]);
|
|
79079
|
-
const trendTooltipLabelFormatter =
|
|
79448
|
+
const trendTooltipLabelFormatter = React143__default.useCallback((label, payload) => {
|
|
79080
79449
|
if (isHourlyTrend) return label;
|
|
79081
79450
|
const dayOfWeek = payload?.[0]?.payload?.dayOfWeek;
|
|
79082
79451
|
if (!dayOfWeek || typeof label !== "string") return label;
|
|
79083
79452
|
return `${label} (${dayOfWeek})`;
|
|
79084
79453
|
}, [isHourlyTrend]);
|
|
79085
|
-
const trendXAxisTickFormatter =
|
|
79454
|
+
const trendXAxisTickFormatter = React143__default.useCallback((value, index) => {
|
|
79086
79455
|
if (!isHourlyTrend) {
|
|
79087
79456
|
return typeof value === "string" ? value : String(value ?? "");
|
|
79088
79457
|
}
|
|
@@ -79109,7 +79478,7 @@ var EfficiencyTrendCard = React142__default.memo(({
|
|
|
79109
79478
|
] });
|
|
79110
79479
|
});
|
|
79111
79480
|
EfficiencyTrendCard.displayName = "EfficiencyTrendCard";
|
|
79112
|
-
var TopImprovementsCard =
|
|
79481
|
+
var TopImprovementsCard = React143__default.memo(({
|
|
79113
79482
|
store,
|
|
79114
79483
|
supervisorsByLineId,
|
|
79115
79484
|
onViewAll,
|
|
@@ -79118,7 +79487,7 @@ var TopImprovementsCard = React142__default.memo(({
|
|
|
79118
79487
|
bumpRenderCounter();
|
|
79119
79488
|
const improvements = useOperationsOverviewImprovements(store);
|
|
79120
79489
|
const showInitialSkeleton = improvements.loading && improvements.lastUpdated === null;
|
|
79121
|
-
const displayImprovements =
|
|
79490
|
+
const displayImprovements = React143__default.useMemo(() => {
|
|
79122
79491
|
return improvements.data.map((item) => {
|
|
79123
79492
|
const supervisors = item.lineId ? supervisorsByLineId.get(item.lineId) || [] : [];
|
|
79124
79493
|
return {
|
|
@@ -79191,7 +79560,7 @@ var debugRefreshLog = (message, payload) => {
|
|
|
79191
79560
|
}
|
|
79192
79561
|
console.log(`[OperationsOverviewRefresh] ${message}`);
|
|
79193
79562
|
};
|
|
79194
|
-
var
|
|
79563
|
+
var isAbortError2 = (error) => {
|
|
79195
79564
|
return error instanceof DOMException && error.name === "AbortError";
|
|
79196
79565
|
};
|
|
79197
79566
|
var toNumber4 = (value) => {
|
|
@@ -79246,33 +79615,33 @@ var useOperationsOverviewRefresh = ({
|
|
|
79246
79615
|
isLiveScope,
|
|
79247
79616
|
enabled = true
|
|
79248
79617
|
}) => {
|
|
79249
|
-
const lineIdsKey =
|
|
79250
|
-
const scopeSignature =
|
|
79618
|
+
const lineIdsKey = React143__default.useMemo(() => lineIds.join(","), [lineIds]);
|
|
79619
|
+
const scopeSignature = React143__default.useMemo(
|
|
79251
79620
|
() => [companyId || "", startKey, endKey, trendMode, comparisonStrategy || "", lineIdsKey].join("::"),
|
|
79252
79621
|
[companyId, comparisonStrategy, endKey, lineIdsKey, startKey, trendMode]
|
|
79253
79622
|
);
|
|
79254
|
-
const controllersRef =
|
|
79255
|
-
const requestIdsRef =
|
|
79623
|
+
const controllersRef = React143__default.useRef({});
|
|
79624
|
+
const requestIdsRef = React143__default.useRef({
|
|
79256
79625
|
snapshot: 0,
|
|
79257
79626
|
trend: 0,
|
|
79258
79627
|
idle: 0,
|
|
79259
79628
|
improvements: 0
|
|
79260
79629
|
});
|
|
79261
|
-
const intervalRef =
|
|
79262
|
-
const isPageActiveRef =
|
|
79263
|
-
const lastResumeRefreshAtRef =
|
|
79264
|
-
const abortAll =
|
|
79630
|
+
const intervalRef = React143__default.useRef(null);
|
|
79631
|
+
const isPageActiveRef = React143__default.useRef(true);
|
|
79632
|
+
const lastResumeRefreshAtRef = React143__default.useRef(0);
|
|
79633
|
+
const abortAll = React143__default.useCallback(() => {
|
|
79265
79634
|
Object.values(controllersRef.current).forEach((controller) => {
|
|
79266
79635
|
controller?.abort();
|
|
79267
79636
|
});
|
|
79268
79637
|
controllersRef.current = {};
|
|
79269
79638
|
}, []);
|
|
79270
|
-
|
|
79639
|
+
React143__default.useEffect(() => {
|
|
79271
79640
|
return () => {
|
|
79272
79641
|
abortAll();
|
|
79273
79642
|
};
|
|
79274
79643
|
}, [abortAll]);
|
|
79275
|
-
const getIsPageActive =
|
|
79644
|
+
const getIsPageActive = React143__default.useCallback(() => {
|
|
79276
79645
|
if (typeof document === "undefined") {
|
|
79277
79646
|
return true;
|
|
79278
79647
|
}
|
|
@@ -79280,7 +79649,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
79280
79649
|
const hasFocus = typeof document.hasFocus === "function" ? document.hasFocus() : true;
|
|
79281
79650
|
return isVisible && hasFocus;
|
|
79282
79651
|
}, []);
|
|
79283
|
-
const stopPolling =
|
|
79652
|
+
const stopPolling = React143__default.useCallback((reason) => {
|
|
79284
79653
|
if (intervalRef.current === null) {
|
|
79285
79654
|
return;
|
|
79286
79655
|
}
|
|
@@ -79288,7 +79657,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
79288
79657
|
intervalRef.current = null;
|
|
79289
79658
|
debugRefreshLog("poll stopped", { reason });
|
|
79290
79659
|
}, []);
|
|
79291
|
-
const runRefresh =
|
|
79660
|
+
const runRefresh = React143__default.useCallback(
|
|
79292
79661
|
async (section, begin, onSuccess, onError, request, reason) => {
|
|
79293
79662
|
if (!enabled || !supabase || !companyId || lineIds.length === 0) return;
|
|
79294
79663
|
const requestId = requestIdsRef.current[section] + 1;
|
|
@@ -79304,7 +79673,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
79304
79673
|
}
|
|
79305
79674
|
onSuccess(response, Date.now(), reason === "live_refresh" ? "transition" : "default");
|
|
79306
79675
|
} catch (error) {
|
|
79307
|
-
if (controller.signal.aborted || requestIdsRef.current[section] !== requestId ||
|
|
79676
|
+
if (controller.signal.aborted || requestIdsRef.current[section] !== requestId || isAbortError2(error)) {
|
|
79308
79677
|
return;
|
|
79309
79678
|
}
|
|
79310
79679
|
onError(error instanceof Error ? error.message : `Failed to refresh ${section}`);
|
|
@@ -79312,7 +79681,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
79312
79681
|
},
|
|
79313
79682
|
[companyId, enabled, lineIds.length, supabase]
|
|
79314
79683
|
);
|
|
79315
|
-
const refreshSnapshot =
|
|
79684
|
+
const refreshSnapshot = React143__default.useCallback(
|
|
79316
79685
|
async (reason) => {
|
|
79317
79686
|
await runRefresh(
|
|
79318
79687
|
"snapshot",
|
|
@@ -79344,7 +79713,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
79344
79713
|
},
|
|
79345
79714
|
[companyId, comparisonStrategy, endKey, lineIdsKey, runRefresh, scopeSignature, startKey, store, supabase, trendMode]
|
|
79346
79715
|
);
|
|
79347
|
-
const refreshTrend =
|
|
79716
|
+
const refreshTrend = React143__default.useCallback(
|
|
79348
79717
|
async (reason) => {
|
|
79349
79718
|
await runRefresh(
|
|
79350
79719
|
"trend",
|
|
@@ -79373,7 +79742,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
79373
79742
|
},
|
|
79374
79743
|
[companyId, endKey, lineIdsKey, runRefresh, scopeSignature, startKey, store, supabase, trendMode]
|
|
79375
79744
|
);
|
|
79376
|
-
const refreshIdle =
|
|
79745
|
+
const refreshIdle = React143__default.useCallback(
|
|
79377
79746
|
async (reason) => {
|
|
79378
79747
|
await runRefresh(
|
|
79379
79748
|
"idle",
|
|
@@ -79402,7 +79771,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
79402
79771
|
},
|
|
79403
79772
|
[companyId, endKey, lineIdsKey, runRefresh, scopeSignature, startKey, store, supabase, trendMode]
|
|
79404
79773
|
);
|
|
79405
|
-
const refreshImprovements =
|
|
79774
|
+
const refreshImprovements = React143__default.useCallback(
|
|
79406
79775
|
async (reason) => {
|
|
79407
79776
|
await runRefresh(
|
|
79408
79777
|
"improvements",
|
|
@@ -79432,7 +79801,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
79432
79801
|
},
|
|
79433
79802
|
[companyId, lineIds, lineIdsKey, runRefresh, scopeSignature, store, supabase]
|
|
79434
79803
|
);
|
|
79435
|
-
const refreshAll =
|
|
79804
|
+
const refreshAll = React143__default.useCallback(
|
|
79436
79805
|
async (reason) => {
|
|
79437
79806
|
await Promise.allSettled([
|
|
79438
79807
|
refreshSnapshot(reason),
|
|
@@ -79443,7 +79812,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
79443
79812
|
},
|
|
79444
79813
|
[refreshIdle, refreshImprovements, refreshSnapshot, refreshTrend]
|
|
79445
79814
|
);
|
|
79446
|
-
const startPolling =
|
|
79815
|
+
const startPolling = React143__default.useCallback((reason) => {
|
|
79447
79816
|
if (!isLiveScope || !supabase || !companyId || lineIds.length === 0) {
|
|
79448
79817
|
return;
|
|
79449
79818
|
}
|
|
@@ -79464,7 +79833,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
79464
79833
|
}, LIVE_REFRESH_INTERVAL_MS);
|
|
79465
79834
|
debugRefreshLog("poll started", { reason, intervalMs: LIVE_REFRESH_INTERVAL_MS });
|
|
79466
79835
|
}, [companyId, isLiveScope, lineIds.length, refreshAll, stopPolling, supabase]);
|
|
79467
|
-
const refreshFromResume =
|
|
79836
|
+
const refreshFromResume = React143__default.useCallback((reason) => {
|
|
79468
79837
|
const now4 = Date.now();
|
|
79469
79838
|
if (now4 - lastResumeRefreshAtRef.current < 1e3) {
|
|
79470
79839
|
debugRefreshLog("resume refresh suppressed", { reason });
|
|
@@ -79479,7 +79848,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
79479
79848
|
}
|
|
79480
79849
|
});
|
|
79481
79850
|
}, [refreshAll, startPolling, stopPolling]);
|
|
79482
|
-
|
|
79851
|
+
React143__default.useEffect(() => {
|
|
79483
79852
|
if (!enabled) {
|
|
79484
79853
|
stopPolling("disabled");
|
|
79485
79854
|
abortAll();
|
|
@@ -79494,7 +79863,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
79494
79863
|
}
|
|
79495
79864
|
void refreshAll("scope_change");
|
|
79496
79865
|
}, [abortAll, companyId, enabled, lineIds.length, refreshAll, scopeSignature, stopPolling, store, supabase]);
|
|
79497
|
-
|
|
79866
|
+
React143__default.useEffect(() => {
|
|
79498
79867
|
if (!enabled || !isLiveScope || !supabase || !companyId || lineIds.length === 0) {
|
|
79499
79868
|
isPageActiveRef.current = false;
|
|
79500
79869
|
stopPolling("live_scope_disabled");
|
|
@@ -79669,55 +80038,55 @@ var PlantHeadView = () => {
|
|
|
79669
80038
|
const { accessibleLineIds } = useUserLineAccess();
|
|
79670
80039
|
const mobileMenuContext = useMobileMenu();
|
|
79671
80040
|
useHideMobileHeader(!!mobileMenuContext);
|
|
79672
|
-
const storeRef =
|
|
80041
|
+
const storeRef = React143__default.useRef(createOperationsOverviewStore());
|
|
79673
80042
|
const store = storeRef.current;
|
|
79674
|
-
const fallbackOperationalDate =
|
|
80043
|
+
const fallbackOperationalDate = React143__default.useMemo(
|
|
79675
80044
|
() => getOperationalDate(appTimezone),
|
|
79676
80045
|
[appTimezone]
|
|
79677
80046
|
);
|
|
79678
|
-
const [dateRange, setDateRange] =
|
|
80047
|
+
const [dateRange, setDateRange] = React143__default.useState(() => ({
|
|
79679
80048
|
startKey: fallbackOperationalDate,
|
|
79680
80049
|
endKey: fallbackOperationalDate
|
|
79681
80050
|
}));
|
|
79682
|
-
const [usesThisWeekComparison, setUsesThisWeekComparison] =
|
|
79683
|
-
const [trendMode, setTrendMode] =
|
|
79684
|
-
const [selectedSupervisorId, setSelectedSupervisorId] =
|
|
79685
|
-
const [selectedLineIds, setSelectedLineIds] =
|
|
79686
|
-
const [isInitialScopeReady, setIsInitialScopeReady] =
|
|
79687
|
-
const [shiftResolutionTick, setShiftResolutionTick] =
|
|
79688
|
-
const hasAutoInitializedScopeRef =
|
|
79689
|
-
const hasUserAdjustedScopeRef =
|
|
79690
|
-
|
|
80051
|
+
const [usesThisWeekComparison, setUsesThisWeekComparison] = React143__default.useState(false);
|
|
80052
|
+
const [trendMode, setTrendMode] = React143__default.useState("all");
|
|
80053
|
+
const [selectedSupervisorId, setSelectedSupervisorId] = React143__default.useState("all");
|
|
80054
|
+
const [selectedLineIds, setSelectedLineIds] = React143__default.useState([]);
|
|
80055
|
+
const [isInitialScopeReady, setIsInitialScopeReady] = React143__default.useState(false);
|
|
80056
|
+
const [shiftResolutionTick, setShiftResolutionTick] = React143__default.useState(0);
|
|
80057
|
+
const hasAutoInitializedScopeRef = React143__default.useRef(false);
|
|
80058
|
+
const hasUserAdjustedScopeRef = React143__default.useRef(false);
|
|
80059
|
+
React143__default.useEffect(() => {
|
|
79691
80060
|
trackCorePageView("Operations Overview", {
|
|
79692
80061
|
dashboard_surface: "operations_overview"
|
|
79693
80062
|
});
|
|
79694
80063
|
}, []);
|
|
79695
|
-
const currentWeekRange =
|
|
80064
|
+
const currentWeekRange = React143__default.useMemo(
|
|
79696
80065
|
() => getCurrentWeekToDateRange(appTimezone),
|
|
79697
80066
|
[appTimezone]
|
|
79698
80067
|
);
|
|
79699
|
-
const currentWeekDisplayRange =
|
|
80068
|
+
const currentWeekDisplayRange = React143__default.useMemo(
|
|
79700
80069
|
() => getCurrentWeekFullRange(appTimezone),
|
|
79701
80070
|
[appTimezone]
|
|
79702
80071
|
);
|
|
79703
80072
|
const isCurrentWeekToDateRange = dateRange.startKey === currentWeekRange.startKey && dateRange.endKey === currentWeekRange.endKey;
|
|
79704
|
-
const headerDateRange =
|
|
80073
|
+
const headerDateRange = React143__default.useMemo(() => {
|
|
79705
80074
|
if (usesThisWeekComparison && isCurrentWeekToDateRange) {
|
|
79706
80075
|
return currentWeekDisplayRange;
|
|
79707
80076
|
}
|
|
79708
80077
|
return dateRange;
|
|
79709
80078
|
}, [currentWeekDisplayRange, dateRange, isCurrentWeekToDateRange, usesThisWeekComparison]);
|
|
79710
|
-
const normalizedLineIds =
|
|
80079
|
+
const normalizedLineIds = React143__default.useMemo(
|
|
79711
80080
|
() => Array.from(new Set(
|
|
79712
80081
|
(accessibleLineIds || []).filter(Boolean).filter((lineId) => lineId !== factoryViewId)
|
|
79713
80082
|
)).sort(),
|
|
79714
80083
|
[accessibleLineIds, factoryViewId]
|
|
79715
80084
|
);
|
|
79716
|
-
const lineIdsKey =
|
|
80085
|
+
const lineIdsKey = React143__default.useMemo(
|
|
79717
80086
|
() => normalizedLineIds.join(","),
|
|
79718
80087
|
[normalizedLineIds]
|
|
79719
80088
|
);
|
|
79720
|
-
const lineOptions =
|
|
80089
|
+
const lineOptions = React143__default.useMemo(
|
|
79721
80090
|
() => normalizedLineIds.map((lineId) => ({
|
|
79722
80091
|
id: lineId,
|
|
79723
80092
|
name: getLineDisplayName(entityConfig, lineId)
|
|
@@ -79729,7 +80098,7 @@ var PlantHeadView = () => {
|
|
|
79729
80098
|
companyId: entityConfig.companyId,
|
|
79730
80099
|
useBackend: true
|
|
79731
80100
|
});
|
|
79732
|
-
const supervisorOptions =
|
|
80101
|
+
const supervisorOptions = React143__default.useMemo(
|
|
79733
80102
|
() => {
|
|
79734
80103
|
const optionsById = /* @__PURE__ */ new Map();
|
|
79735
80104
|
normalizedLineIds.forEach((lineId) => {
|
|
@@ -79755,7 +80124,7 @@ var PlantHeadView = () => {
|
|
|
79755
80124
|
},
|
|
79756
80125
|
[normalizedLineIds, supervisorsByLineId]
|
|
79757
80126
|
);
|
|
79758
|
-
|
|
80127
|
+
React143__default.useEffect(() => {
|
|
79759
80128
|
if (selectedSupervisorId === "all") {
|
|
79760
80129
|
setSelectedLineIds((previous) => {
|
|
79761
80130
|
if (normalizedLineIds.length === 0) {
|
|
@@ -79781,7 +80150,7 @@ var PlantHeadView = () => {
|
|
|
79781
80150
|
const scopedSupervisorLineIds = normalizedLineIds.filter((lineId) => supervisorLineIdSet.has(lineId));
|
|
79782
80151
|
setSelectedLineIds((previous) => previous.length === scopedSupervisorLineIds.length && previous.every((lineId, index) => lineId === scopedSupervisorLineIds[index]) ? previous : scopedSupervisorLineIds);
|
|
79783
80152
|
}, [lineIdsKey, normalizedLineIds, selectedSupervisorId, supervisorOptions]);
|
|
79784
|
-
const scopedLineIds =
|
|
80153
|
+
const scopedLineIds = React143__default.useMemo(
|
|
79785
80154
|
() => selectedLineIds.length > 0 ? selectedLineIds : normalizedLineIds,
|
|
79786
80155
|
[normalizedLineIds, selectedLineIds]
|
|
79787
80156
|
);
|
|
@@ -79789,7 +80158,7 @@ var PlantHeadView = () => {
|
|
|
79789
80158
|
shiftConfigMap,
|
|
79790
80159
|
isLoading: isShiftConfigLoading
|
|
79791
80160
|
} = useMultiLineShiftConfigs(scopedLineIds, staticShiftConfig);
|
|
79792
|
-
|
|
80161
|
+
React143__default.useEffect(() => {
|
|
79793
80162
|
if (scopedLineIds.length === 0 || isShiftConfigLoading) {
|
|
79794
80163
|
return;
|
|
79795
80164
|
}
|
|
@@ -79800,11 +80169,11 @@ var PlantHeadView = () => {
|
|
|
79800
80169
|
clearInterval(intervalId);
|
|
79801
80170
|
};
|
|
79802
80171
|
}, [isShiftConfigLoading, scopedLineIds.length]);
|
|
79803
|
-
const shiftResolutionNow =
|
|
80172
|
+
const shiftResolutionNow = React143__default.useMemo(
|
|
79804
80173
|
() => /* @__PURE__ */ new Date(),
|
|
79805
80174
|
[shiftResolutionTick]
|
|
79806
80175
|
);
|
|
79807
|
-
const earliestDayShiftStartTime =
|
|
80176
|
+
const earliestDayShiftStartTime = React143__default.useMemo(() => {
|
|
79808
80177
|
const candidateStarts = [];
|
|
79809
80178
|
scopedLineIds.forEach((lineId) => {
|
|
79810
80179
|
const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
|
|
@@ -79840,11 +80209,11 @@ var PlantHeadView = () => {
|
|
|
79840
80209
|
const minutes = earliestMinutes % 60;
|
|
79841
80210
|
return `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
|
|
79842
80211
|
}, [appTimezone, scopedLineIds, shiftConfigMap, staticShiftConfig]);
|
|
79843
|
-
const resolvedOperationalToday =
|
|
80212
|
+
const resolvedOperationalToday = React143__default.useMemo(
|
|
79844
80213
|
() => getOperationalDate(appTimezone, shiftResolutionNow, earliestDayShiftStartTime),
|
|
79845
80214
|
[appTimezone, earliestDayShiftStartTime, shiftResolutionNow]
|
|
79846
80215
|
);
|
|
79847
|
-
const activeLineShiftStates =
|
|
80216
|
+
const activeLineShiftStates = React143__default.useMemo(() => {
|
|
79848
80217
|
return scopedLineIds.flatMap((lineId) => {
|
|
79849
80218
|
const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
|
|
79850
80219
|
const activeShift = getActiveShift(appTimezone, shiftConfig, shiftResolutionNow);
|
|
@@ -79871,16 +80240,16 @@ var PlantHeadView = () => {
|
|
|
79871
80240
|
}];
|
|
79872
80241
|
});
|
|
79873
80242
|
}, [appTimezone, scopedLineIds, shiftConfigMap, shiftResolutionNow, staticShiftConfig]);
|
|
79874
|
-
const hasActiveDayShiftLine =
|
|
80243
|
+
const hasActiveDayShiftLine = React143__default.useMemo(
|
|
79875
80244
|
() => activeLineShiftStates.some((shift) => shift.trendMode === "day" && shift.date === resolvedOperationalToday),
|
|
79876
80245
|
[activeLineShiftStates, resolvedOperationalToday]
|
|
79877
80246
|
);
|
|
79878
|
-
const hasActiveNightShiftLine =
|
|
80247
|
+
const hasActiveNightShiftLine = React143__default.useMemo(
|
|
79879
80248
|
() => activeLineShiftStates.some((shift) => shift.trendMode === "night" && shift.date === resolvedOperationalToday),
|
|
79880
80249
|
[activeLineShiftStates, resolvedOperationalToday]
|
|
79881
80250
|
);
|
|
79882
80251
|
const resolvedTrendMode = isInitialScopeReady ? trendMode : "all";
|
|
79883
|
-
const hourlyWindowStartTime =
|
|
80252
|
+
const hourlyWindowStartTime = React143__default.useMemo(() => {
|
|
79884
80253
|
if (scopedLineIds.length === 0) {
|
|
79885
80254
|
return null;
|
|
79886
80255
|
}
|
|
@@ -79931,12 +80300,12 @@ var PlantHeadView = () => {
|
|
|
79931
80300
|
const minutes = earliestMinutes % 60;
|
|
79932
80301
|
return `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
|
|
79933
80302
|
}, [appTimezone, resolvedTrendMode, scopedLineIds, shiftConfigMap, staticShiftConfig]);
|
|
79934
|
-
const isShiftScopeResolved =
|
|
80303
|
+
const isShiftScopeResolved = React143__default.useMemo(
|
|
79935
80304
|
() => !isShiftConfigLoading,
|
|
79936
80305
|
[isShiftConfigLoading]
|
|
79937
80306
|
);
|
|
79938
|
-
const initializedTimezoneRef =
|
|
79939
|
-
|
|
80307
|
+
const initializedTimezoneRef = React143__default.useRef(appTimezone);
|
|
80308
|
+
React143__default.useEffect(() => {
|
|
79940
80309
|
if (initializedTimezoneRef.current === appTimezone) return;
|
|
79941
80310
|
hasAutoInitializedScopeRef.current = false;
|
|
79942
80311
|
hasUserAdjustedScopeRef.current = false;
|
|
@@ -79949,7 +80318,7 @@ var PlantHeadView = () => {
|
|
|
79949
80318
|
setIsInitialScopeReady(false);
|
|
79950
80319
|
initializedTimezoneRef.current = appTimezone;
|
|
79951
80320
|
}, [appTimezone, fallbackOperationalDate]);
|
|
79952
|
-
|
|
80321
|
+
React143__default.useEffect(() => {
|
|
79953
80322
|
if (hasAutoInitializedScopeRef.current || hasUserAdjustedScopeRef.current) {
|
|
79954
80323
|
return;
|
|
79955
80324
|
}
|
|
@@ -79974,7 +80343,7 @@ var PlantHeadView = () => {
|
|
|
79974
80343
|
hasAutoInitializedScopeRef.current = true;
|
|
79975
80344
|
setIsInitialScopeReady(true);
|
|
79976
80345
|
}, [fallbackOperationalDate, isShiftScopeResolved, resolvedOperationalToday, scopedLineIds.length]);
|
|
79977
|
-
const handleDateRangeChange =
|
|
80346
|
+
const handleDateRangeChange = React143__default.useCallback((range, meta) => {
|
|
79978
80347
|
hasUserAdjustedScopeRef.current = true;
|
|
79979
80348
|
setIsInitialScopeReady(true);
|
|
79980
80349
|
trackCoreEvent("Operations Overview Date Range Changed", {
|
|
@@ -79992,12 +80361,12 @@ var PlantHeadView = () => {
|
|
|
79992
80361
|
return previous;
|
|
79993
80362
|
});
|
|
79994
80363
|
}, []);
|
|
79995
|
-
const handleTrendModeChange =
|
|
80364
|
+
const handleTrendModeChange = React143__default.useCallback((mode) => {
|
|
79996
80365
|
hasUserAdjustedScopeRef.current = true;
|
|
79997
80366
|
setIsInitialScopeReady(true);
|
|
79998
80367
|
setTrendMode(mode);
|
|
79999
80368
|
}, []);
|
|
80000
|
-
const handleSelectedLineIdsChange =
|
|
80369
|
+
const handleSelectedLineIdsChange = React143__default.useCallback((lineIds) => {
|
|
80001
80370
|
setSelectedSupervisorId("all");
|
|
80002
80371
|
if (normalizedLineIds.length === 0) {
|
|
80003
80372
|
setSelectedLineIds([]);
|
|
@@ -80008,10 +80377,10 @@ var PlantHeadView = () => {
|
|
|
80008
80377
|
const next = normalizedLineIds.filter((lineId) => selectedSet.has(lineId));
|
|
80009
80378
|
setSelectedLineIds(next.length > 0 ? next : normalizedLineIds);
|
|
80010
80379
|
}, [normalizedLineIds]);
|
|
80011
|
-
const handleSelectedSupervisorIdChange =
|
|
80380
|
+
const handleSelectedSupervisorIdChange = React143__default.useCallback((supervisorId) => {
|
|
80012
80381
|
setSelectedSupervisorId(supervisorId);
|
|
80013
80382
|
}, []);
|
|
80014
|
-
const buildLineMonthlyHistoryUrl =
|
|
80383
|
+
const buildLineMonthlyHistoryUrl = React143__default.useCallback((lineId) => {
|
|
80015
80384
|
const rangeStartDate = parseDateKeyToDate(dateRange.startKey);
|
|
80016
80385
|
const params = new URLSearchParams();
|
|
80017
80386
|
params.set("tab", "monthly_history");
|
|
@@ -80021,15 +80390,15 @@ var PlantHeadView = () => {
|
|
|
80021
80390
|
params.set("rangeEnd", dateRange.endKey);
|
|
80022
80391
|
return `/kpis/${lineId}?${params.toString()}`;
|
|
80023
80392
|
}, [dateRange.endKey, dateRange.startKey]);
|
|
80024
|
-
const handleViewAllPoorestPerformers =
|
|
80393
|
+
const handleViewAllPoorestPerformers = React143__default.useCallback(() => {
|
|
80025
80394
|
trackCoreEvent("Operations Overview View All Clicked", { section: "poorest_performers" });
|
|
80026
80395
|
navigate("/kpis?tab=leaderboard");
|
|
80027
80396
|
}, [navigate]);
|
|
80028
|
-
const handleViewAllImprovements =
|
|
80397
|
+
const handleViewAllImprovements = React143__default.useCallback(() => {
|
|
80029
80398
|
trackCoreEvent("Operations Overview View All Clicked", { section: "improvements" });
|
|
80030
80399
|
navigate("/improvement-center");
|
|
80031
80400
|
}, [navigate]);
|
|
80032
|
-
const handleOpenImprovement =
|
|
80401
|
+
const handleOpenImprovement = React143__default.useCallback((item) => {
|
|
80033
80402
|
trackCoreEvent("Operations Overview Improvement Clicked", {
|
|
80034
80403
|
issue_id: item.issueId,
|
|
80035
80404
|
issue_number: item.issueNumber,
|
|
@@ -80040,13 +80409,13 @@ var PlantHeadView = () => {
|
|
|
80040
80409
|
});
|
|
80041
80410
|
navigate(`/improvement-center?${params.toString()}`);
|
|
80042
80411
|
}, [navigate]);
|
|
80043
|
-
const comparisonStrategy =
|
|
80412
|
+
const comparisonStrategy = React143__default.useMemo(() => {
|
|
80044
80413
|
if (usesThisWeekComparison && isCurrentWeekToDateRange) {
|
|
80045
80414
|
return "previous_full_week";
|
|
80046
80415
|
}
|
|
80047
80416
|
return void 0;
|
|
80048
80417
|
}, [isCurrentWeekToDateRange, usesThisWeekComparison]);
|
|
80049
|
-
const effectiveDateRange =
|
|
80418
|
+
const effectiveDateRange = React143__default.useMemo(() => {
|
|
80050
80419
|
if (isInitialScopeReady) {
|
|
80051
80420
|
return dateRange;
|
|
80052
80421
|
}
|
|
@@ -80056,21 +80425,21 @@ var PlantHeadView = () => {
|
|
|
80056
80425
|
endKey: nextStartKey
|
|
80057
80426
|
};
|
|
80058
80427
|
}, [dateRange, fallbackOperationalDate, isInitialScopeReady, resolvedOperationalToday]);
|
|
80059
|
-
const effectiveTrendMode =
|
|
80428
|
+
const effectiveTrendMode = React143__default.useMemo(
|
|
80060
80429
|
() => resolvedTrendMode,
|
|
80061
80430
|
[resolvedTrendMode]
|
|
80062
80431
|
);
|
|
80063
|
-
const hourlyLabelStartTime =
|
|
80432
|
+
const hourlyLabelStartTime = React143__default.useMemo(() => {
|
|
80064
80433
|
if (scopedLineIds.length === 0) {
|
|
80065
80434
|
return null;
|
|
80066
80435
|
}
|
|
80067
80436
|
return hourlyWindowStartTime;
|
|
80068
80437
|
}, [hourlyWindowStartTime, scopedLineIds.length]);
|
|
80069
|
-
const isSingleDayScope =
|
|
80438
|
+
const isSingleDayScope = React143__default.useMemo(
|
|
80070
80439
|
() => effectiveDateRange.startKey === effectiveDateRange.endKey,
|
|
80071
80440
|
[effectiveDateRange.endKey, effectiveDateRange.startKey]
|
|
80072
80441
|
);
|
|
80073
|
-
const isLiveScope =
|
|
80442
|
+
const isLiveScope = React143__default.useMemo(
|
|
80074
80443
|
() => isSingleDayScope && effectiveDateRange.startKey === resolvedOperationalToday && (effectiveTrendMode === "all" || effectiveTrendMode === "day" && hasActiveDayShiftLine || effectiveTrendMode === "night" && hasActiveNightShiftLine),
|
|
80075
80444
|
[
|
|
80076
80445
|
effectiveDateRange.startKey,
|
|
@@ -80081,7 +80450,7 @@ var PlantHeadView = () => {
|
|
|
80081
80450
|
resolvedOperationalToday
|
|
80082
80451
|
]
|
|
80083
80452
|
);
|
|
80084
|
-
const handleOpenLineDetails =
|
|
80453
|
+
const handleOpenLineDetails = React143__default.useCallback((lineId, lineName) => {
|
|
80085
80454
|
trackCoreEvent("Operations Overview Line Clicked", {
|
|
80086
80455
|
line_id: lineId,
|
|
80087
80456
|
line_name: lineName,
|
|
@@ -80649,4 +81018,4 @@ var streamProxyConfig = {
|
|
|
80649
81018
|
}
|
|
80650
81019
|
};
|
|
80651
81020
|
|
|
80652
|
-
export { ACTION_FAMILIES, ACTION_NAMES, AIAgentView_default as AIAgentView, AcceptInvite, AcceptInviteView_default as AcceptInviteView, AdvancedFilterDialog, AdvancedFilterPanel, AudioService, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthService, AuthenticatedBottleneckClipsView, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedShiftsView, AuthenticatedTargetsView, AuthenticatedTicketsView, AuthenticatedWorkspaceHealthView, AvatarUpload, AxelNotificationPopup, AxelOrb, BackButton, BackButtonMinimal, BarChart, BaseHistoryCalendar, BottleneckClipsModal, BottleneckClipsView_default as BottleneckClipsView, BottlenecksContent, BreakNotificationPopup, CachePrefetchStatus, Card2 as Card, CardContent2 as CardContent, CardDescription2 as CardDescription, CardFooter2 as CardFooter, CardHeader2 as CardHeader, CardTitle2 as CardTitle, ChangeRoleDialog, ClipFilterProvider, ClipsCostView_default as ClipsCostView, CompactWorkspaceHealthCard, ConfirmRemoveUserDialog, CongratulationsOverlay, CroppedHlsVideoPlayer, CroppedVideoPlayer, CycleTimeChart, CycleTimeOverTimeChart, DEFAULT_ANALYTICS_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_CONFIG, DEFAULT_DATABASE_CONFIG, DEFAULT_DATE_TIME_CONFIG, DEFAULT_ENDPOINTS_CONFIG, DEFAULT_ENTITY_CONFIG, DEFAULT_HOME_VIEW_CONFIG, DEFAULT_MAP_VIEW_CONFIG, DEFAULT_SHIFT_CONFIG, DEFAULT_SHIFT_DATA, 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, DetailedHealthStatus, DiagnosisVideoModal, EFFICIENCY_ON_TRACK_THRESHOLD, EmptyStateMessage, EncouragementOverlay, FactoryAssignmentDropdown, FactoryView_default as FactoryView, FileManagerFilters, FilterDialogTrigger, FirstTimeLoginDebug, FirstTimeLoginHandler, FittingTitle, GaugeChart, GridComponentsPlaceholder, HamburgerButton, Header, HealthDateShiftSelector, HealthStatusGrid, HealthStatusIndicator, HelpView_default as HelpView, HlsVideoPlayer, HomeView_default as HomeView, HourlyOutputChart2 as HourlyOutputChart, HourlyUptimeChart, ISTTimer_default as ISTTimer, IdleTimeVlmConfigProvider, ImprovementCenterView_default as ImprovementCenterView, InlineEditableText, InteractiveOnboardingTour, InvitationService, InvitationsTable, InviteUserDialog, KPICard, KPIDetailView_default as KPIDetailView, KPIGrid, KPIHeader, KPISection, KPIsOverviewView_default as KPIsOverviewView, LINE_1_UUID, LINE_2_UUID, LargeOutputProgressChart, LeaderboardDetailView_default as LeaderboardDetailView, Legend5 as Legend, LineAssignmentDropdown, LineChart, LineHistoryCalendar, LineMonthlyHistory, LineMonthlyPdfGenerator, LinePdfExportButton, LinePdfGenerator, LineWhatsAppShareButton, LinesService, LiveTimer, LoadingInline, LoadingOverlay_default as LoadingOverlay, LoadingPage_default as LoadingPage, LoadingSkeleton, LoadingState, LoginPage, LoginView_default as LoginView, Logo, MainLayout, MapGridView, MetricCard_default as MetricCard, MinimalOnboardingPopup, MobileMenuProvider, NewClipsNotification, NoWorkspaceData, OnboardingDemo, OnboardingTour, OptifyeAgentClient, OptifyeLogoLoader_default as OptifyeLogoLoader, OutputProgressChart, PageHeader, PieChart4 as PieChart, PlantHeadView_default as PlantHeadView, PlayPauseIndicator, PrefetchConfigurationError, PrefetchError, PrefetchEvents, PrefetchStatus, PrefetchTimeoutError, ProfileView_default as ProfileView, ROOT_DASHBOARD_EVENT_NAMES, RegistryProvider, RoleBadge, S3ClipsSupabaseService as S3ClipsService, S3Service, SKUManagementView, SOPComplianceChart, SSEChatClient, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, SessionTracker, SessionTrackingContext, SessionTrackingProvider, SettingsPopup, ShiftDisplay_default as ShiftDisplay, ShiftsView_default as ShiftsView, SideNavBar, SignupWithInvitation, SilentErrorBoundary, SimpleOnboardingPopup, SingleVideoStream_default as SingleVideoStream, Skeleton, SubscriptionManager, SubscriptionManagerProvider, SupabaseProvider, SupervisorDropdown_default as SupervisorDropdown, SupervisorManagementView_default as SupervisorManagementView, SupervisorService, TargetWorkspaceGrid, TargetsView_default as TargetsView, TeamManagementView_default as TeamManagementView, ThreadSidebar, TicketHistory_default as TicketHistory, TicketHistoryService, TicketsView_default as TicketsView, TimeDisplay_default as TimeDisplay, TimePickerDropdown, Timer_default as Timer, TimezoneProvider, TimezoneService, UptimeDonutChart, UptimeLineChart, UptimeMetricCards, UserAvatar, UserManagementService, UserManagementTable, UserService, UserUsageDetailModal, UserUsageStats, VideoCard, VideoGridView, VideoPlayer, VideoPreloader, WORKSPACE_POSITIONS, WhatsAppShareButton, WorkspaceCard, WorkspaceCycleTimeMetricCards, WorkspaceDetailView_default as WorkspaceDetailView, WorkspaceDisplayNameExample, WorkspaceGrid, WorkspaceGridItem, WorkspaceHealthCard, WorkspaceHealthView_default as WorkspaceHealthView, WorkspaceHistoryCalendar, WorkspaceMetricCards, WorkspaceMetricCardsImpl, WorkspaceMonthlyDataFetcher, WorkspaceMonthlyHistory, WorkspaceMonthlyPdfGenerator, WorkspacePdfExportButton, WorkspacePdfGenerator, WorkspaceWhatsAppShareButton, actionService, aggregateKPIsFromLineMetricsRows, alertsService, apiUtils, areAllLinesOnSameShift, authCoreService, authOTPService, authRateLimitService, awardsService, buildDateKey, buildKPIsFromLineMetricsRow, buildShiftGroupsKey, canRoleAccessDashboardPath, canRoleAccessTeamManagement, canRoleAssignFactories, canRoleAssignLines, canRoleChangeRole, canRoleInviteRole, canRoleManageCompany, canRoleManageTargets, canRoleManageUsers, canRoleRemoveUser, canRoleViewClipsCost, canRoleViewUsageStats, captureSentryException, captureSentryMessage, checkRateLimit2 as checkRateLimit, clearAllRateLimits2 as clearAllRateLimits, clearRateLimit2 as clearRateLimit, clearS3VideoCache, clearS3VideoFromCache, clearSentryContext, clearWorkspaceDisplayNamesCache, cn, createDefaultKPIs, createInvitationService, createLinesService, createSessionTracker, createStorageService, createStreamProxyHandler, createSupabaseClient, createSupervisorService, createThrottledReload, createUserManagementService, createUserService, dashboardService, deleteThread, fetchIdleTimeReasons, filterDataByDateKeyRange, forceRefreshWorkspaceDisplayNames, formatAwardMonth, formatDateInZone, formatDateKeyForDisplay, formatDateTimeInZone, formatDuration2 as formatDuration, formatISTDate, formatIdleTime, formatRangeLabel, formatReasonLabel, formatRelativeTime, formatTimeInZone, fromUrlFriendlyName, getActionDisplayName, getActiveShift, getAllLineDisplayNames, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAllWorkspaceDisplayNamesSnapshot, getAnonClient, getAssignableRoles, getAssignmentColumnLabel, getAvailableShiftIds, getAwardBadgeType, getAwardDescription, getAwardTitle, getBrowserName, getCameraNumber, getCompanyMetricsTableName, getConfigurableShortWorkspaceDisplayName, getConfigurableWorkspaceDisplayName, getConfiguredLineIds, getCoreSessionRecordingProperties, getCoreSessionReplayUrl, getCurrentShift, getCurrentShiftForLine, getCurrentTimeInZone, getCurrentWeekFullRange, getCurrentWeekToDateRange, getDashboardHeaderTimeInZone, getDateKeyFromDate, getDaysDifferenceInZone, getDefaultCameraStreamUrl, getDefaultLineId, getDefaultTabForWorkspace, getInitials, getLineDisplayName, getManufacturingInsights, getMetricsTablePrefix, getMonthKeyBounds, getMonthWeekRanges, getNextUpdateInterval, getOperationalDate, getRoleAssignmentKind, getRoleDescription, getRoleLabel, getRoleMetadata, getRoleNavPaths, getS3SignedUrl, getS3VideoSrc, getShiftData, getShiftNameById, getShiftWorkDurationSeconds, getShortShiftName, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getSubscriptionManager, getThreadMessages, getUniformShiftGroup, getUserThreads, getUserThreadsPaginated, getVisibleRolesForCurrentUser, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, groupLinesByShift, hasAnyShiftData, identifyCoreUser, initializeCoreMixpanel, isEfficiencyOnTrack, isFactoryScopedRole, isFullMonthRange, isLegacyConfiguration, isLoopbackHostname, isPrefetchError, isRecentFlowVideoGridMetricMode, isSafari, isSupervisorRole, isTransitionPeriod, isUrlPermanentlyFailed, isValidFactoryViewConfiguration, isValidLineInfoPayload, isValidPrefetchParams, isValidPrefetchStatus, isValidWorkspaceDetailedMetricsPayload, isValidWorkspaceMetricsPayload, isWipGatedVideoGridMetricMode, isWorkspaceDisplayNamesLoaded, isWorkspaceDisplayNamesLoading, lineLeaderboardService, linesService, mergeWithDefaultConfig, migrateLegacyConfiguration, normalizeActionFamily, normalizeDateKeyRange, normalizeRoleLevel, normalizeVideoGridMetricMode, optifyeAgentClient, parseDateKeyToDate, parseS3Uri, preInitializeWorkspaceDisplayNames, preloadS3Video, preloadS3VideoUrl, preloadS3VideosUrl, preloadVideoUrl, preloadVideosUrl, qualityService, realtimeService, refreshWorkspaceDisplayNames, resetCoreMixpanel, resetFailedUrl, resetSubscriptionManager, s3VideoPreloader, setSentryUserContext, setSentryWorkspaceContext, shouldEnableLocalDevTestLogin, shuffleArray, simulateApiDelay, skuService, startCoreSessionRecording, stopCoreSessionRecording, storeWorkspaceMapping, streamProxyConfig, subscribeWorkspaceDisplayNames, throttledReloadDashboard, toUrlFriendlyName, trackCoreEvent, trackCorePageView, transformToChartData, updateThreadTitle, upsertWorkspaceDisplayNameInCache, useAccessControl, useActiveBreaks, useActiveLineId, useAllWorkspaceMetrics, useAnalyticsConfig, useAppTimezone, useAudioService, useAuth, useAuthConfig, useAxelNotifications, useCanSaveTargets, useClipFilter, useClipTypes, useClipTypesWithCounts, useClipsInit, useCompanyClipsCost, useCompanyFastSlowClipFiltersEnabled, useCompanyHasVlmEnabledLine, useCompanyUsersUsage, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useDynamicShiftConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHasLineAccess, useHideMobileHeader, useHistoricWorkspaceMetrics, useHlsStream, useHlsStreamWithCropping, useHookOverride, useHourEndTimer, useHourlyTargetAchievements, useHourlyTargetMisses, useIdleTimeClipClassifications, useIdleTimeReasons, useIdleTimeVlmConfig, useKpiTrends, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineShiftConfig, useLineSupervisor, useLineWorkspaceMetrics, useLines, useMessages, useMetrics, useMobileMenu, useMonthlyTrend, useMultiLineShiftConfigs, useNavigation, useOperationalShiftKey, useOptionalSupabase, useOverrides, usePageOverride, usePrefetchClipCounts, useRealtimeLineMetrics, useRegistry, useSKUs, useSessionKeepAlive, useSessionTracking, useSessionTrackingContext, useShiftConfig, useShiftGroups, useShifts, useSubscriptionManager, useSubscriptionManagerSafe, useSupabase, useSupabaseClient, useSupervisorsByLineIds, useTargets, useTeamManagementPermissions, useTheme, useThemeConfig, useThreads, useTicketHistory, useTimezoneContext, useUserLineAccess, useUserUsage, useVideoConfig, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceHealthById, useWorkspaceHealthLastSeen, useWorkspaceHealthStatus, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, useWorkspaceUptimeTimeline, useWorkspaceVideoStreams, userService, videoPrefetchManager, videoPreloader, weeklyTopPerformerService, whatsappService, withAccessControl, withAuth, withRegistry, withTimezone, workspaceHealthService, workspaceService };
|
|
81021
|
+
export { ACTION_FAMILIES, ACTION_NAMES, AIAgentView_default as AIAgentView, AcceptInvite, AcceptInviteView_default as AcceptInviteView, AdvancedFilterDialog, AdvancedFilterPanel, AudioService, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthService, AuthenticatedBottleneckClipsView, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedShiftsView, AuthenticatedTargetsView, AuthenticatedTicketsView, AuthenticatedWorkspaceHealthView, AvatarUpload, AxelNotificationPopup, AxelOrb, BackButton, BackButtonMinimal, BarChart, BaseHistoryCalendar, BottleneckClipsModal, BottleneckClipsView_default as BottleneckClipsView, BottlenecksContent, BreakNotificationPopup, CachePrefetchStatus, Card2 as Card, CardContent2 as CardContent, CardDescription2 as CardDescription, CardFooter2 as CardFooter, CardHeader2 as CardHeader, CardTitle2 as CardTitle, ChangeRoleDialog, ClipFilterProvider, ClipsCostView_default as ClipsCostView, CompactWorkspaceHealthCard, ConfirmRemoveUserDialog, CongratulationsOverlay, CroppedHlsVideoPlayer, CroppedVideoPlayer, CycleTimeChart, CycleTimeOverTimeChart, DEFAULT_ANALYTICS_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_CONFIG, DEFAULT_DATABASE_CONFIG, DEFAULT_DATE_TIME_CONFIG, DEFAULT_ENDPOINTS_CONFIG, DEFAULT_ENTITY_CONFIG, DEFAULT_HOME_VIEW_CONFIG, DEFAULT_MAP_VIEW_CONFIG, DEFAULT_SHIFT_CONFIG, DEFAULT_SHIFT_DATA, 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, DetailedHealthStatus, DiagnosisVideoModal, EFFICIENCY_ON_TRACK_THRESHOLD, EmptyStateMessage, EncouragementOverlay, FactoryAssignmentDropdown, FactoryView_default as FactoryView, FileManagerFilters, FilterDialogTrigger, FirstTimeLoginDebug, FirstTimeLoginHandler, FittingTitle, GaugeChart, GridComponentsPlaceholder, HamburgerButton, Header, HealthDateShiftSelector, HealthStatusGrid, HealthStatusIndicator, HelpView_default as HelpView, HlsVideoPlayer, HomeView_default as HomeView, HourlyOutputChart2 as HourlyOutputChart, HourlyUptimeChart, ISTTimer_default as ISTTimer, IdleTimeVlmConfigProvider, ImprovementCenterView_default as ImprovementCenterView, InlineEditableText, InteractiveOnboardingTour, InvitationService, InvitationsTable, InviteUserDialog, KPICard, KPIDetailView_default as KPIDetailView, KPIGrid, KPIHeader, KPISection, KPIsOverviewView_default as KPIsOverviewView, LINE_1_UUID, LINE_2_UUID, LargeOutputProgressChart, LeaderboardDetailView_default as LeaderboardDetailView, Legend5 as Legend, LineAssignmentDropdown, LineChart, LineHistoryCalendar, LineMonthlyHistory, LineMonthlyPdfGenerator, LinePdfExportButton, LinePdfGenerator, LineWhatsAppShareButton, LinesService, LiveTimer, LoadingInline, LoadingOverlay_default as LoadingOverlay, LoadingPage_default as LoadingPage, LoadingSkeleton, LoadingState, LoginPage, LoginView_default as LoginView, Logo, MainLayout, MapGridView, MetricCard_default as MetricCard, MinimalOnboardingPopup, MobileMenuProvider, NewClipsNotification, NoWorkspaceData, OnboardingDemo, OnboardingTour, OptifyeAgentClient, OptifyeLogoLoader_default as OptifyeLogoLoader, OutputProgressChart, PageHeader, PieChart4 as PieChart, PlantHeadView_default as PlantHeadView, PlayPauseIndicator, PrefetchConfigurationError, PrefetchError, PrefetchEvents, PrefetchStatus, PrefetchTimeoutError, ProfileView_default as ProfileView, ROOT_DASHBOARD_EVENT_NAMES, RegistryProvider, RoleBadge, S3ClipsSupabaseService as S3ClipsService, S3Service, SKUManagementView, SOPComplianceChart, SSEChatClient, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, SessionTracker, SessionTrackingContext, SessionTrackingProvider, SettingsPopup, ShiftDisplay_default as ShiftDisplay, ShiftsView_default as ShiftsView, SideNavBar, SignupWithInvitation, SilentErrorBoundary, SimpleOnboardingPopup, SingleVideoStream_default as SingleVideoStream, Skeleton, SubscriptionManager, SubscriptionManagerProvider, SupabaseProvider, SupervisorDropdown_default as SupervisorDropdown, SupervisorManagementView_default as SupervisorManagementView, SupervisorService, TargetWorkspaceGrid, TargetsView_default as TargetsView, TeamManagementView_default as TeamManagementView, ThreadSidebar, TicketHistory_default as TicketHistory, TicketHistoryService, TicketsView_default as TicketsView, TimeDisplay_default as TimeDisplay, TimePickerDropdown, Timer_default as Timer, TimezoneProvider, TimezoneService, UptimeDonutChart, UptimeLineChart, UptimeMetricCards, UserAvatar, UserManagementService, UserManagementTable, UserService, UserUsageDetailModal, UserUsageStats, VideoCard, VideoGridView, VideoPlayer, VideoPreloader, WORKSPACE_POSITIONS, WhatsAppShareButton, WorkspaceCard, WorkspaceCycleTimeMetricCards, WorkspaceDetailView_default as WorkspaceDetailView, WorkspaceDisplayNameExample, WorkspaceGrid, WorkspaceGridItem, WorkspaceHealthCard, WorkspaceHealthView_default as WorkspaceHealthView, WorkspaceHistoryCalendar, WorkspaceMetricCards, WorkspaceMetricCardsImpl, WorkspaceMonthlyDataFetcher, WorkspaceMonthlyHistory, WorkspaceMonthlyPdfGenerator, WorkspacePdfExportButton, WorkspacePdfGenerator, WorkspaceWhatsAppShareButton, actionService, aggregateKPIsFromLineMetricsRows, alertsService, apiUtils, areAllLinesOnSameShift, authCoreService, authOTPService, authRateLimitService, awardsService, buildDateKey, buildKPIsFromLineMetricsRow, buildShiftGroupsKey, canRoleAccessDashboardPath, canRoleAccessTeamManagement, canRoleAssignFactories, canRoleAssignLines, canRoleChangeRole, canRoleInviteRole, canRoleManageCompany, canRoleManageTargets, canRoleManageUsers, canRoleRemoveUser, canRoleViewClipsCost, canRoleViewUsageStats, captureHandledFrontendException, captureSentryException, captureSentryMessage, checkRateLimit2 as checkRateLimit, clearAllRateLimits2 as clearAllRateLimits, clearRateLimit2 as clearRateLimit, clearS3VideoCache, clearS3VideoFromCache, clearSentryContext, clearWorkspaceDisplayNamesCache, cn, createDefaultKPIs, createInvitationService, createLinesService, createSessionTracker, createStorageService, createStreamProxyHandler, createSupabaseClient, createSupervisorService, createThrottledReload, createUserManagementService, createUserService, dashboardService, deleteThread, fetchIdleTimeReasons, filterDataByDateKeyRange, forceRefreshWorkspaceDisplayNames, formatAwardMonth, formatDateInZone, formatDateKeyForDisplay, formatDateTimeInZone, formatDuration2 as formatDuration, formatISTDate, formatIdleTime, formatRangeLabel, formatReasonLabel, formatRelativeTime, formatTimeInZone, fromUrlFriendlyName, getActionDisplayName, getActiveShift, getAllLineDisplayNames, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAllWorkspaceDisplayNamesSnapshot, getAnonClient, getAssignableRoles, getAssignmentColumnLabel, getAvailableShiftIds, getAwardBadgeType, getAwardDescription, getAwardTitle, getBrowserName, getCameraNumber, getCompanyMetricsTableName, getConfigurableShortWorkspaceDisplayName, getConfigurableWorkspaceDisplayName, getConfiguredLineIds, getCoreSessionRecordingProperties, getCoreSessionReplayUrl, getCurrentShift, getCurrentShiftForLine, getCurrentTimeInZone, getCurrentWeekFullRange, getCurrentWeekToDateRange, getDashboardHeaderTimeInZone, getDateKeyFromDate, getDaysDifferenceInZone, getDefaultCameraStreamUrl, getDefaultLineId, getDefaultTabForWorkspace, getInitials, getLineDisplayName, getManufacturingInsights, getMetricsTablePrefix, getMonthKeyBounds, getMonthWeekRanges, getNextUpdateInterval, getOperationalDate, getRoleAssignmentKind, getRoleDescription, getRoleLabel, getRoleMetadata, getRoleNavPaths, getS3SignedUrl, getS3VideoSrc, getShiftData, getShiftNameById, getShiftWorkDurationSeconds, getShortShiftName, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getSubscriptionManager, getThreadMessages, getUniformShiftGroup, getUserThreads, getUserThreadsPaginated, getVisibleRolesForCurrentUser, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, groupLinesByShift, hasAnyShiftData, identifyCoreUser, initializeCoreMixpanel, isEfficiencyOnTrack, isFactoryScopedRole, isFullMonthRange, isIgnorableFrontendError, isLegacyConfiguration, isLoopbackHostname, isPrefetchError, isRecentFlowVideoGridMetricMode, isSafari, isSupervisorRole, isTransitionPeriod, isUrlPermanentlyFailed, isValidFactoryViewConfiguration, isValidLineInfoPayload, isValidPrefetchParams, isValidPrefetchStatus, isValidWorkspaceDetailedMetricsPayload, isValidWorkspaceMetricsPayload, isWipGatedVideoGridMetricMode, isWorkspaceDisplayNamesLoaded, isWorkspaceDisplayNamesLoading, lineLeaderboardService, linesService, mergeWithDefaultConfig, migrateLegacyConfiguration, normalizeActionFamily, normalizeDateKeyRange, normalizeRoleLevel, normalizeVideoGridMetricMode, optifyeAgentClient, parseDateKeyToDate, parseS3Uri, preInitializeWorkspaceDisplayNames, preloadS3Video, preloadS3VideoUrl, preloadS3VideosUrl, preloadVideoUrl, preloadVideosUrl, qualityService, realtimeService, refreshWorkspaceDisplayNames, resetCoreMixpanel, resetFailedUrl, resetSubscriptionManager, s3VideoPreloader, setSentryUserContext, setSentryWorkspaceContext, shouldEnableLocalDevTestLogin, shuffleArray, simulateApiDelay, skuService, startCoreSessionRecording, stopCoreSessionRecording, storeWorkspaceMapping, streamProxyConfig, subscribeWorkspaceDisplayNames, throttledReloadDashboard, toUrlFriendlyName, trackCoreEvent, trackCorePageView, transformToChartData, updateThreadTitle, upsertWorkspaceDisplayNameInCache, useAccessControl, useActiveBreaks, useActiveLineId, useAllWorkspaceMetrics, useAnalyticsConfig, useAppTimezone, useAudioService, useAuth, useAuthConfig, useAxelNotifications, useCanSaveTargets, useClipFilter, useClipTypes, useClipTypesWithCounts, useClipsInit, useCompanyClipsCost, useCompanyFastSlowClipFiltersEnabled, useCompanyHasVlmEnabledLine, useCompanyUsersUsage, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useDynamicShiftConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHasLineAccess, useHideMobileHeader, useHistoricWorkspaceMetrics, useHlsStream, useHlsStreamWithCropping, useHookOverride, useHourEndTimer, useHourlyTargetAchievements, useHourlyTargetMisses, useIdleTimeClipClassifications, useIdleTimeReasons, useIdleTimeVlmConfig, useKpiTrends, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineShiftConfig, useLineSupervisor, useLineWorkspaceMetrics, useLines, useMessages, useMetrics, useMobileMenu, useMonthlyTrend, useMultiLineShiftConfigs, useNavigation, useOperationalShiftKey, useOptionalSupabase, useOverrides, usePageOverride, usePrefetchClipCounts, useRealtimeLineMetrics, useRegistry, useSKUs, useSessionKeepAlive, useSessionTracking, useSessionTrackingContext, useShiftConfig, useShiftGroups, useShifts, useSubscriptionManager, useSubscriptionManagerSafe, useSupabase, useSupabaseClient, useSupervisorsByLineIds, useTargets, useTeamManagementPermissions, useTheme, useThemeConfig, useThreads, useTicketHistory, useTimezoneContext, useUserLineAccess, useUserUsage, useVideoConfig, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceHealthById, useWorkspaceHealthLastSeen, useWorkspaceHealthStatus, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, useWorkspaceUptimeTimeline, useWorkspaceVideoStreams, userService, videoPrefetchManager, videoPreloader, weeklyTopPerformerService, whatsappService, withAccessControl, withAuth, withRegistry, withTimezone, workspaceHealthService, workspaceService };
|