@optifye/dashboard-core 6.11.31 → 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 +3093 -2727
- package/dist/index.mjs +1028 -664
- 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,
|
|
@@ -39553,13 +39714,8 @@ var TimePickerDropdown = ({
|
|
|
39553
39714
|
}, [disabled, hasValue, onChange]);
|
|
39554
39715
|
const handleContainerClick = useCallback(() => {
|
|
39555
39716
|
if (disabled) return;
|
|
39556
|
-
|
|
39557
|
-
|
|
39558
|
-
if (!hasValue) {
|
|
39559
|
-
onChange(to24h(12, 0, "AM"));
|
|
39560
|
-
}
|
|
39561
|
-
}
|
|
39562
|
-
}, [disabled, activeSegment, hasValue, onChange]);
|
|
39717
|
+
togglePopover();
|
|
39718
|
+
}, [disabled, togglePopover]);
|
|
39563
39719
|
return /* @__PURE__ */ jsxs("div", { className: `relative ${className}`, ref: containerRef, children: [
|
|
39564
39720
|
/* @__PURE__ */ jsxs(
|
|
39565
39721
|
"div",
|
|
@@ -39646,7 +39802,7 @@ var TimePickerDropdown = ({
|
|
|
39646
39802
|
)
|
|
39647
39803
|
] });
|
|
39648
39804
|
};
|
|
39649
|
-
var SilentErrorBoundary = class extends
|
|
39805
|
+
var SilentErrorBoundary = class extends React143__default.Component {
|
|
39650
39806
|
constructor(props) {
|
|
39651
39807
|
super(props);
|
|
39652
39808
|
this.handleClearAndReload = () => {
|
|
@@ -39679,6 +39835,12 @@ var SilentErrorBoundary = class extends React142__default.Component {
|
|
|
39679
39835
|
componentStack: errorInfo.componentStack,
|
|
39680
39836
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
39681
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
|
+
});
|
|
39682
39844
|
this.setState((prev) => ({
|
|
39683
39845
|
errorCount: prev.errorCount + 1,
|
|
39684
39846
|
lastError: error,
|
|
@@ -46515,8 +46677,8 @@ var IdleTimeReasonChartComponent = ({
|
|
|
46515
46677
|
updateAnimation = "replay",
|
|
46516
46678
|
variant = "pie"
|
|
46517
46679
|
}) => {
|
|
46518
|
-
const [activeData, setActiveData] =
|
|
46519
|
-
|
|
46680
|
+
const [activeData, setActiveData] = React143__default.useState([]);
|
|
46681
|
+
React143__default.useEffect(() => {
|
|
46520
46682
|
if (updateAnimation === "smooth") {
|
|
46521
46683
|
setActiveData(data && data.length > 0 ? data : []);
|
|
46522
46684
|
return;
|
|
@@ -46535,7 +46697,7 @@ var IdleTimeReasonChartComponent = ({
|
|
|
46535
46697
|
setActiveData([]);
|
|
46536
46698
|
}
|
|
46537
46699
|
}, [data, updateAnimation]);
|
|
46538
|
-
|
|
46700
|
+
React143__default.useEffect(() => {
|
|
46539
46701
|
if (!data || data.length === 0) return;
|
|
46540
46702
|
data.forEach((entry, index) => {
|
|
46541
46703
|
if (entry.name.toLowerCase().includes("other")) {
|
|
@@ -46543,7 +46705,7 @@ var IdleTimeReasonChartComponent = ({
|
|
|
46543
46705
|
}
|
|
46544
46706
|
});
|
|
46545
46707
|
}, [data]);
|
|
46546
|
-
const pieKey =
|
|
46708
|
+
const pieKey = React143__default.useMemo(() => {
|
|
46547
46709
|
if (updateAnimation === "smooth") {
|
|
46548
46710
|
return "smooth";
|
|
46549
46711
|
}
|
|
@@ -46713,7 +46875,7 @@ var IdleTimeReasonChartComponent = ({
|
|
|
46713
46875
|
)
|
|
46714
46876
|
] });
|
|
46715
46877
|
};
|
|
46716
|
-
var IdleTimeReasonChart =
|
|
46878
|
+
var IdleTimeReasonChart = React143__default.memo(IdleTimeReasonChartComponent);
|
|
46717
46879
|
IdleTimeReasonChart.displayName = "IdleTimeReasonChart";
|
|
46718
46880
|
var IdleTimeReasonChart_default = IdleTimeReasonChart;
|
|
46719
46881
|
var DEFAULT_PERFORMANCE_DATA = {
|
|
@@ -51080,7 +51242,7 @@ var arePropsEqual = (prevProps, nextProps) => {
|
|
|
51080
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
|
|
51081
51243
|
prevProps.position.id === nextProps.position.id;
|
|
51082
51244
|
};
|
|
51083
|
-
var WorkspaceGridItem =
|
|
51245
|
+
var WorkspaceGridItem = React143__default.memo(({
|
|
51084
51246
|
data,
|
|
51085
51247
|
position,
|
|
51086
51248
|
isBottleneck = false,
|
|
@@ -51108,7 +51270,7 @@ var WorkspaceGridItem = React142__default.memo(({
|
|
|
51108
51270
|
const handleClick = useCallback((e) => {
|
|
51109
51271
|
e.preventDefault();
|
|
51110
51272
|
if (isInactive) return;
|
|
51111
|
-
const displayName = getWorkspaceDisplayName(data.workspace_name, data.line_id);
|
|
51273
|
+
const displayName = data.displayName || getWorkspaceDisplayName(data.workspace_name, data.line_id);
|
|
51112
51274
|
const currentPath = typeof window !== "undefined" ? `${window.location.pathname}${window.location.search}` : "/";
|
|
51113
51275
|
const navParams = getWorkspaceNavigationParams(data.workspace_id, displayName, data.line_id, currentPath);
|
|
51114
51276
|
navigate(`/workspace/${data.workspace_id}${navParams}`, {
|
|
@@ -51157,7 +51319,7 @@ var WorkspaceGridItem = React142__default.memo(({
|
|
|
51157
51319
|
onClick: handleClick,
|
|
51158
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`,
|
|
51159
51321
|
"aria-label": isInactive ? `Inactive workspace ${workspaceNumber}` : `View details for workspace ${workspaceNumber}`,
|
|
51160
|
-
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),
|
|
51161
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 })
|
|
51162
51324
|
}
|
|
51163
51325
|
),
|
|
@@ -51175,7 +51337,7 @@ var WorkspaceGridItem = React142__default.memo(({
|
|
|
51175
51337
|
);
|
|
51176
51338
|
}, arePropsEqual);
|
|
51177
51339
|
WorkspaceGridItem.displayName = "WorkspaceGridItem";
|
|
51178
|
-
var WorkspaceGrid =
|
|
51340
|
+
var WorkspaceGrid = React143__default.memo(({
|
|
51179
51341
|
workspaces,
|
|
51180
51342
|
isPdfMode = false,
|
|
51181
51343
|
customWorkspacePositions,
|
|
@@ -51439,7 +51601,7 @@ var KPICard = ({
|
|
|
51439
51601
|
}) => {
|
|
51440
51602
|
useThemeConfig();
|
|
51441
51603
|
const { formatNumber } = useFormatNumber();
|
|
51442
|
-
const trendInfo =
|
|
51604
|
+
const trendInfo = React143__default.useMemo(() => {
|
|
51443
51605
|
let trendValue = trend || "neutral";
|
|
51444
51606
|
if (change !== void 0 && trend === void 0) {
|
|
51445
51607
|
trendValue = change > 0 ? "up" : change < 0 ? "down" : "neutral";
|
|
@@ -51466,7 +51628,7 @@ var KPICard = ({
|
|
|
51466
51628
|
const shouldShowTrend = !(change === 0 && trend === void 0);
|
|
51467
51629
|
return { trendValue, Icon: Icon2, colorClass, bgClass, shouldShowTrend };
|
|
51468
51630
|
}, [trend, change]);
|
|
51469
|
-
const formattedValue =
|
|
51631
|
+
const formattedValue = React143__default.useMemo(() => {
|
|
51470
51632
|
if (title === "Quality Compliance" && typeof value === "number") {
|
|
51471
51633
|
return value.toFixed(1);
|
|
51472
51634
|
}
|
|
@@ -51480,7 +51642,7 @@ var KPICard = ({
|
|
|
51480
51642
|
}
|
|
51481
51643
|
return value;
|
|
51482
51644
|
}, [value, title]);
|
|
51483
|
-
const formattedChange =
|
|
51645
|
+
const formattedChange = React143__default.useMemo(() => {
|
|
51484
51646
|
if (change === void 0 || change === 0 && !showZeroChange) return null;
|
|
51485
51647
|
const absChange = Math.abs(change);
|
|
51486
51648
|
return formatNumber(absChange, { minimumFractionDigits: 0, maximumFractionDigits: 1 });
|
|
@@ -52987,7 +53149,7 @@ var Breadcrumbs = ({ items }) => {
|
|
|
52987
53149
|
}
|
|
52988
53150
|
}
|
|
52989
53151
|
};
|
|
52990
|
-
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: [
|
|
52991
53153
|
index > 0 && /* @__PURE__ */ jsx(ChevronRight, { className: "h-3 w-3 text-gray-400 dark:text-gray-500" }),
|
|
52992
53154
|
/* @__PURE__ */ jsxs(
|
|
52993
53155
|
"span",
|
|
@@ -54463,7 +54625,7 @@ var AwardBadge = ({
|
|
|
54463
54625
|
}) => {
|
|
54464
54626
|
const styles2 = getBadgeStyles(type);
|
|
54465
54627
|
const Icon2 = CustomIcon || getDefaultIcon(type);
|
|
54466
|
-
const randomDelay =
|
|
54628
|
+
const randomDelay = React143__default.useMemo(() => Math.random() * 2, []);
|
|
54467
54629
|
const floatingAnimation = {
|
|
54468
54630
|
animate: {
|
|
54469
54631
|
y: [0, -10, 0],
|
|
@@ -59967,67 +60129,77 @@ var NotificationService = class {
|
|
|
59967
60129
|
this.supabaseClient = supabaseClient || null;
|
|
59968
60130
|
}
|
|
59969
60131
|
async fetchWithAuth(url, options = {}) {
|
|
59970
|
-
|
|
59971
|
-
|
|
59972
|
-
|
|
59973
|
-
const { data: { session }, error: sessionError } = await this.supabaseClient.auth.getSession();
|
|
59974
|
-
if (sessionError) {
|
|
59975
|
-
console.error("Session error:", sessionError);
|
|
59976
|
-
throw new Error("Failed to get authentication session. Please log in.");
|
|
59977
|
-
}
|
|
59978
|
-
if (!session) {
|
|
59979
|
-
console.error("No session found. User must be logged in.");
|
|
59980
|
-
throw new Error("User not authenticated. Please log in.");
|
|
59981
|
-
}
|
|
59982
|
-
if (!session.access_token) {
|
|
59983
|
-
console.error("Session exists but no access_token found");
|
|
59984
|
-
throw new Error("Invalid session. Please log in again.");
|
|
59985
|
-
}
|
|
59986
|
-
const token = session.access_token;
|
|
59987
|
-
if (process.env.NODE_ENV === "development") {
|
|
59988
|
-
console.log("[NotificationService] Using JWT token for notifications API");
|
|
59989
|
-
}
|
|
59990
|
-
const headers = {
|
|
59991
|
-
"Content-Type": "application/json",
|
|
59992
|
-
...options.headers,
|
|
59993
|
-
"Authorization": `Bearer ${token}`
|
|
59994
|
-
};
|
|
59995
|
-
const response = await fetch(url, {
|
|
59996
|
-
...options,
|
|
59997
|
-
headers
|
|
59998
|
-
});
|
|
59999
|
-
if (response.status === 401) {
|
|
60000
|
-
console.error("401 Unauthorized - Token expired or invalid");
|
|
60001
|
-
throw new Error("Authentication failed. Please log in again.");
|
|
60002
|
-
}
|
|
60003
|
-
if (response.status === 403) {
|
|
60004
|
-
console.error("403 Forbidden - User does not have permission");
|
|
60005
|
-
throw new Error("Access denied. You do not have permission to access this resource.");
|
|
60006
|
-
}
|
|
60007
|
-
if (response.status === 500) {
|
|
60008
|
-
console.error("500 Internal Server Error - Backend error");
|
|
60009
|
-
let errorDetail = "Internal server error occurred.";
|
|
60010
|
-
try {
|
|
60011
|
-
const errorData = await response.text();
|
|
60012
|
-
console.error("Backend error details:", errorData);
|
|
60013
|
-
errorDetail = errorData || errorDetail;
|
|
60014
|
-
} catch (e) {
|
|
60132
|
+
try {
|
|
60133
|
+
if (!this.supabaseClient) {
|
|
60134
|
+
throw new Error("Supabase client not initialized. Please provide a Supabase client to NotificationService.");
|
|
60015
60135
|
}
|
|
60016
|
-
|
|
60017
|
-
|
|
60018
|
-
|
|
60019
|
-
|
|
60020
|
-
|
|
60021
|
-
|
|
60022
|
-
|
|
60023
|
-
|
|
60024
|
-
|
|
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) {
|
|
60025
60178
|
}
|
|
60026
|
-
|
|
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}`);
|
|
60027
60192
|
}
|
|
60028
|
-
|
|
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;
|
|
60029
60202
|
}
|
|
60030
|
-
return response;
|
|
60031
60203
|
}
|
|
60032
60204
|
/**
|
|
60033
60205
|
* Get bottleneck notifications
|
|
@@ -60101,8 +60273,6 @@ function HomeView({
|
|
|
60101
60273
|
}) {
|
|
60102
60274
|
const [isHydrated, setIsHydrated] = useState(false);
|
|
60103
60275
|
const [isChangingFilter, setIsChangingFilter] = useState(false);
|
|
60104
|
-
const [errorMessage, setErrorMessage] = useState(null);
|
|
60105
|
-
const [displayNamesInitialized, setDisplayNamesInitialized] = useState(false);
|
|
60106
60276
|
const [hasInitialDataLoaded, setHasInitialDataLoaded] = useState(false);
|
|
60107
60277
|
const [showDataLoading, setShowDataLoading] = useState(false);
|
|
60108
60278
|
const loadingStartRef = useRef(null);
|
|
@@ -60111,7 +60281,7 @@ function HomeView({
|
|
|
60111
60281
|
const dashboardConfig = useDashboardConfig();
|
|
60112
60282
|
const entityConfig = useEntityConfig();
|
|
60113
60283
|
const supabaseClient = useSupabaseClient();
|
|
60114
|
-
const { user } = useAuth();
|
|
60284
|
+
const { user, authStatus, isRecoveringSession, retrySessionHydration } = useAuth();
|
|
60115
60285
|
const { lines: dbLines } = useLines();
|
|
60116
60286
|
const mergedLineNames = useMemo(() => {
|
|
60117
60287
|
const merged = { ...lineNames };
|
|
@@ -60245,26 +60415,7 @@ function HomeView({
|
|
|
60245
60415
|
visibleLineIds,
|
|
60246
60416
|
dashboardConfig?.shiftConfig
|
|
60247
60417
|
);
|
|
60248
|
-
|
|
60249
|
-
const initDisplayNames = async () => {
|
|
60250
|
-
try {
|
|
60251
|
-
for (const lineId of selectedLineIds) {
|
|
60252
|
-
await preInitializeWorkspaceDisplayNames(lineId);
|
|
60253
|
-
}
|
|
60254
|
-
setDisplayNamesInitialized(true);
|
|
60255
|
-
} catch (error) {
|
|
60256
|
-
console.error("Failed to pre-initialize workspace display names:", error);
|
|
60257
|
-
setDisplayNamesInitialized(true);
|
|
60258
|
-
}
|
|
60259
|
-
};
|
|
60260
|
-
initDisplayNames();
|
|
60261
|
-
}, [selectedLineIdsKey]);
|
|
60262
|
-
const displayNameLineId = isMultiLineSelection ? void 0 : primarySelectedLineId;
|
|
60263
|
-
const {
|
|
60264
|
-
displayNames: workspaceDisplayNames,
|
|
60265
|
-
loading: displayNamesLoading,
|
|
60266
|
-
error: displayNamesError
|
|
60267
|
-
} = useWorkspaceDisplayNames(displayNameLineId, void 0);
|
|
60418
|
+
const shouldEnableMetricsFetch = authStatus === "ready";
|
|
60268
60419
|
const handleLineMetricsUpdate = useCallback(() => {
|
|
60269
60420
|
if (trendRefreshTimerRef.current) {
|
|
60270
60421
|
window.clearTimeout(trendRefreshTimerRef.current);
|
|
@@ -60291,9 +60442,32 @@ function HomeView({
|
|
|
60291
60442
|
lineId: metricsScopeLineId,
|
|
60292
60443
|
lineIds: selectedLineIds,
|
|
60293
60444
|
onLineMetricsUpdate: handleLineMetricsUpdate,
|
|
60294
|
-
userAccessibleLineIds: visibleLineIds
|
|
60445
|
+
userAccessibleLineIds: visibleLineIds,
|
|
60295
60446
|
// Pass user's accessible lines for supervisor filtering
|
|
60447
|
+
enabled: shouldEnableMetricsFetch
|
|
60296
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]);
|
|
60297
60471
|
const trendGroups = useMemo(() => {
|
|
60298
60472
|
const lineMetricsRows = lineMetrics || [];
|
|
60299
60473
|
if (!lineMetricsRows.length) return null;
|
|
@@ -60734,13 +60908,13 @@ function HomeView({
|
|
|
60734
60908
|
dashboard_surface: "monitor"
|
|
60735
60909
|
});
|
|
60736
60910
|
}, []);
|
|
60737
|
-
|
|
60738
|
-
|
|
60739
|
-
|
|
60740
|
-
|
|
60741
|
-
setErrorMessage(null);
|
|
60911
|
+
const metricsErrorMessage = metricsError?.message || null;
|
|
60912
|
+
const handleRetryDashboardData = useCallback(async () => {
|
|
60913
|
+
if (isRecoveringSession) {
|
|
60914
|
+
await retrySessionHydration();
|
|
60742
60915
|
}
|
|
60743
|
-
|
|
60916
|
+
refetchMetrics();
|
|
60917
|
+
}, [isRecoveringSession, refetchMetrics, retrySessionHydration]);
|
|
60744
60918
|
const getTrackedLineScope = useCallback((lineIdsForScope) => {
|
|
60745
60919
|
if (isAllLinesSelection(lineIdsForScope)) {
|
|
60746
60920
|
return factoryViewId;
|
|
@@ -60798,7 +60972,7 @@ function HomeView({
|
|
|
60798
60972
|
}
|
|
60799
60973
|
}, [metricsLoading, isChangingFilter]);
|
|
60800
60974
|
useEffect(() => {
|
|
60801
|
-
if (!metricsLoading && !hasInitialDataLoaded) {
|
|
60975
|
+
if (shouldEnableMetricsFetch && !metricsLoading && !metricsError && !hasInitialDataLoaded) {
|
|
60802
60976
|
setHasInitialDataLoaded(true);
|
|
60803
60977
|
trackCoreEvent("monitor page loaded", {
|
|
60804
60978
|
default_line_id: defaultLineId,
|
|
@@ -60807,7 +60981,7 @@ function HomeView({
|
|
|
60807
60981
|
dashboard_surface: "monitor"
|
|
60808
60982
|
});
|
|
60809
60983
|
}
|
|
60810
|
-
}, [metricsLoading, hasInitialDataLoaded, defaultLineId, factoryViewId, isSupervisor]);
|
|
60984
|
+
}, [shouldEnableMetricsFetch, metricsLoading, metricsError, hasInitialDataLoaded, defaultLineId, factoryViewId, isSupervisor]);
|
|
60811
60985
|
const lineTitle = useMemo(() => {
|
|
60812
60986
|
return factoryName;
|
|
60813
60987
|
}, [factoryName]);
|
|
@@ -60957,8 +61131,9 @@ function HomeView({
|
|
|
60957
61131
|
}, [isLoading, minDuration]);
|
|
60958
61132
|
return showLoading;
|
|
60959
61133
|
};
|
|
60960
|
-
const
|
|
60961
|
-
const
|
|
61134
|
+
const isAuthBootstrapping = authStatus === "loading";
|
|
61135
|
+
const isInitialLoading = !isHydrated || !hasInitialDataLoaded && (isAuthBootstrapping || shouldEnableMetricsFetch && metricsLoading);
|
|
61136
|
+
const isDataLoading = metricsLoading;
|
|
60962
61137
|
const hasKpiDataReady = useMemo(() => {
|
|
60963
61138
|
const lineMetricsRows = lineMetrics || [];
|
|
60964
61139
|
if (selectedLineIds.length > 1) {
|
|
@@ -60967,6 +61142,10 @@ function HomeView({
|
|
|
60967
61142
|
return lineMetricsRows.some((row) => row?.line_id === primarySelectedLineId);
|
|
60968
61143
|
}, [lineMetrics, primarySelectedLineId, selectedLineIdSet, selectedLineIds.length]);
|
|
60969
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;
|
|
60970
61149
|
useEffect(() => {
|
|
60971
61150
|
const minLoadingDurationMs = 250;
|
|
60972
61151
|
if (isDataLoading) {
|
|
@@ -61006,14 +61185,41 @@ function HomeView({
|
|
|
61006
61185
|
if (isInitialLoading) {
|
|
61007
61186
|
return /* @__PURE__ */ jsx(LoadingPageCmp, { message: "Loading Dashboard..." });
|
|
61008
61187
|
}
|
|
61009
|
-
if (
|
|
61010
|
-
return /* @__PURE__ */ jsx("div", { className: "flex h-screen items-center justify-center
|
|
61011
|
-
/* @__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: "
|
|
61012
|
-
/* @__PURE__ */
|
|
61013
|
-
|
|
61014
|
-
|
|
61015
|
-
|
|
61016
|
-
|
|
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
|
+
] }) });
|
|
61017
61223
|
}
|
|
61018
61224
|
return /* @__PURE__ */ jsx(
|
|
61019
61225
|
motion.div,
|
|
@@ -61032,6 +61238,20 @@ function HomeView({
|
|
|
61032
61238
|
headerControls: kpiSectionControl
|
|
61033
61239
|
}
|
|
61034
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,
|
|
61035
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(
|
|
61036
61256
|
motion.div,
|
|
61037
61257
|
{
|
|
@@ -61039,7 +61259,7 @@ function HomeView({
|
|
|
61039
61259
|
animate: { opacity: 1, scale: 1 },
|
|
61040
61260
|
transition: { duration: 0.3 },
|
|
61041
61261
|
className: "h-full",
|
|
61042
|
-
children:
|
|
61262
|
+
children: React143__default.createElement(WorkspaceGrid, {
|
|
61043
61263
|
workspaces: workspaceMetricsWithBreakState,
|
|
61044
61264
|
lineNames: mergedLineNames,
|
|
61045
61265
|
lineOrder: selectedLineIds,
|
|
@@ -61048,7 +61268,7 @@ function HomeView({
|
|
|
61048
61268
|
videoSources,
|
|
61049
61269
|
videoStreamsByWorkspaceId,
|
|
61050
61270
|
videoStreamsLoading,
|
|
61051
|
-
displayNames:
|
|
61271
|
+
displayNames: metricsDisplayNames,
|
|
61052
61272
|
hasFlowBuffers,
|
|
61053
61273
|
className: "h-full",
|
|
61054
61274
|
toolbarRightContent: lineSelectorComponent,
|
|
@@ -61072,7 +61292,7 @@ function HomeView({
|
|
|
61072
61292
|
animate: { opacity: 1, scale: 1 },
|
|
61073
61293
|
transition: { duration: 0.3 },
|
|
61074
61294
|
className: "h-full",
|
|
61075
|
-
children:
|
|
61295
|
+
children: React143__default.createElement(WorkspaceGrid, {
|
|
61076
61296
|
workspaces: [],
|
|
61077
61297
|
// Show empty grid while loading
|
|
61078
61298
|
lineNames: mergedLineNames,
|
|
@@ -61082,7 +61302,7 @@ function HomeView({
|
|
|
61082
61302
|
videoSources,
|
|
61083
61303
|
videoStreamsByWorkspaceId,
|
|
61084
61304
|
videoStreamsLoading,
|
|
61085
|
-
displayNames:
|
|
61305
|
+
displayNames: metricsDisplayNames,
|
|
61086
61306
|
hasFlowBuffers,
|
|
61087
61307
|
className: "h-full",
|
|
61088
61308
|
toolbarRightContent: lineSelectorComponent,
|
|
@@ -61140,7 +61360,7 @@ function HomeView({
|
|
|
61140
61360
|
}
|
|
61141
61361
|
);
|
|
61142
61362
|
}
|
|
61143
|
-
var AuthenticatedHomeView = withAuth(
|
|
61363
|
+
var AuthenticatedHomeView = withAuth(React143__default.memo(HomeView));
|
|
61144
61364
|
var HomeView_default = HomeView;
|
|
61145
61365
|
function withWorkspaceDisplayNames(Component3, options = {}) {
|
|
61146
61366
|
const {
|
|
@@ -61338,6 +61558,7 @@ var buildLineInfoSnapshot = (lineDetails, metrics2) => {
|
|
|
61338
61558
|
shift_id: metrics2.shift_id ?? 0,
|
|
61339
61559
|
date: metrics2.date || "",
|
|
61340
61560
|
monitoring_mode: lineDetails.monitoring_mode ?? void 0,
|
|
61561
|
+
assembly: lineDetails.assembly ?? null,
|
|
61341
61562
|
metrics: {
|
|
61342
61563
|
avg_efficiency: metrics2.avg_efficiency ?? 0,
|
|
61343
61564
|
avg_cycle_time: metrics2.avg_cycle_time ?? 0,
|
|
@@ -61370,6 +61591,7 @@ var transformWorkspaceMetrics = (workspaceData, lineId, companyId, queryDate, qu
|
|
|
61370
61591
|
pph: item.avg_pph || 0,
|
|
61371
61592
|
performance_score: item.performance_score || 0,
|
|
61372
61593
|
avg_cycle_time: item.avg_cycle_time || 0,
|
|
61594
|
+
ideal_cycle_time: item.ideal_cycle_time ?? void 0,
|
|
61373
61595
|
trend: item.trend_score === 1 ? 2 : 0,
|
|
61374
61596
|
predicted_output: item.ideal_output || 0,
|
|
61375
61597
|
efficiency: item.efficiency || 0,
|
|
@@ -61405,7 +61627,8 @@ var transformLineDetails = (lineId, detailResponse) => {
|
|
|
61405
61627
|
id: detailResponse.line_details.factory_id || "",
|
|
61406
61628
|
factory_name: detailResponse.line_details.factory_name || ""
|
|
61407
61629
|
},
|
|
61408
|
-
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
|
|
61409
61632
|
};
|
|
61410
61633
|
};
|
|
61411
61634
|
var transformLineMetrics = (lineId, detailResponse, queryDate, queryShiftId) => {
|
|
@@ -61806,6 +62029,56 @@ function useEfficiencyLegend(companyId) {
|
|
|
61806
62029
|
refetch: fetchLegend
|
|
61807
62030
|
};
|
|
61808
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
|
+
};
|
|
61809
62082
|
var WEEKDAYS4 = ["S", "M", "T", "W", "T", "F", "S"];
|
|
61810
62083
|
var MonthlyRangeFilter = ({
|
|
61811
62084
|
month,
|
|
@@ -62405,7 +62678,13 @@ var BottomSection = memo$1(({
|
|
|
62405
62678
|
}) => {
|
|
62406
62679
|
const navigation = useNavigation();
|
|
62407
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
|
+
);
|
|
62408
62686
|
const handleWorkspaceClick = useCallback((ws, index) => {
|
|
62687
|
+
const cycleRatio = getCycleRatio(ws);
|
|
62409
62688
|
trackCoreEvent("Workspace from KPI Clicked", {
|
|
62410
62689
|
workspace_name: ws.workspace_name,
|
|
62411
62690
|
workspace_id: ws.workspace_uuid,
|
|
@@ -62414,9 +62693,13 @@ var BottomSection = memo$1(({
|
|
|
62414
62693
|
efficiency: ws.efficiency,
|
|
62415
62694
|
action_count: ws.action_count,
|
|
62416
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",
|
|
62417
62700
|
section: "Poorest Performing Workspaces"
|
|
62418
62701
|
});
|
|
62419
|
-
}, [workspaceData.length]);
|
|
62702
|
+
}, [isAssemblyLine, workspaceData.length]);
|
|
62420
62703
|
return /* @__PURE__ */ jsxs(
|
|
62421
62704
|
motion.div,
|
|
62422
62705
|
{
|
|
@@ -62438,14 +62721,42 @@ var BottomSection = memo$1(({
|
|
|
62438
62721
|
)
|
|
62439
62722
|
] }),
|
|
62440
62723
|
/* @__PURE__ */ jsxs("div", { className: "divide-y overflow-auto flex-1 pr-1 sm:pr-2", children: [
|
|
62441
|
-
/* @__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: [
|
|
62442
62728
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 sm:gap-3 md:gap-6", children: [
|
|
62443
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" }),
|
|
62444
62730
|
/* @__PURE__ */ jsx("div", { className: "text-xs md:text-sm font-medium text-gray-500", children: "Current/Ideal" })
|
|
62445
62731
|
] }),
|
|
62446
62732
|
/* @__PURE__ */ jsx("div", { className: "text-xs md:text-sm font-medium text-gray-500 pr-1 sm:pr-2", children: "Efficiency" })
|
|
62447
|
-
] }),
|
|
62448
|
-
|
|
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) => {
|
|
62449
62760
|
const wsMetrics = workspaceData.find((w) => w.workspace_name === ws.workspace_name);
|
|
62450
62761
|
const wsUuid = wsMetrics?.workspace_uuid;
|
|
62451
62762
|
if (!wsUuid) {
|
|
@@ -62541,10 +62852,63 @@ var BottomSection = memo$1(({
|
|
|
62541
62852
|
const prevPoorest = prevProps.lineInfo.metrics.poorest_performing_workspaces || [];
|
|
62542
62853
|
const nextPoorest = nextProps.lineInfo.metrics.poorest_performing_workspaces || [];
|
|
62543
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;
|
|
62544
62860
|
if (prevProps.hourlyOutputData.length !== nextProps.hourlyOutputData.length) return false;
|
|
62545
62861
|
const hourlyDataChanged = prevProps.hourlyOutputData.some((value, index) => value !== nextProps.hourlyOutputData[index]);
|
|
62546
62862
|
if (hourlyDataChanged) return false;
|
|
62547
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;
|
|
62548
62912
|
if (prevProps.lineInfo.metrics.shift_start !== nextProps.lineInfo.metrics.shift_start) return false;
|
|
62549
62913
|
if (prevProps.hourlyThreshold !== nextProps.hourlyThreshold) return false;
|
|
62550
62914
|
if (prevProps.urlDate !== nextProps.urlDate || prevProps.urlShift !== nextProps.urlShift) return false;
|
|
@@ -63019,6 +63383,7 @@ var KPIDetailView = ({
|
|
|
63019
63383
|
shift_id: metrics2.shift_id ?? 0,
|
|
63020
63384
|
date: metrics2.date || getOperationalDate(timezone || "UTC"),
|
|
63021
63385
|
monitoring_mode: lineDetails.monitoring_mode ?? void 0,
|
|
63386
|
+
assembly: lineDetails.assembly ?? null,
|
|
63022
63387
|
metrics: {
|
|
63023
63388
|
avg_efficiency: metrics2.avg_efficiency ?? 0,
|
|
63024
63389
|
avg_cycle_time: metrics2.avg_cycle_time ?? 0,
|
|
@@ -64110,18 +64475,18 @@ var LinesLeaderboard = ({
|
|
|
64110
64475
|
isHistoricalDaily
|
|
64111
64476
|
}) => {
|
|
64112
64477
|
const formatEfficiency = (value) => typeof value === "number" && Number.isFinite(value) ? `${value.toFixed(1)}%` : "--";
|
|
64113
|
-
const assignedLineIdSet =
|
|
64478
|
+
const assignedLineIdSet = React143__default.useMemo(
|
|
64114
64479
|
() => new Set(assignedLineIds || []),
|
|
64115
64480
|
[assignedLineIds]
|
|
64116
64481
|
);
|
|
64117
|
-
const canClickLine =
|
|
64482
|
+
const canClickLine = React143__default.useCallback(
|
|
64118
64483
|
(lineId) => {
|
|
64119
64484
|
if (!assignedLineIds) return true;
|
|
64120
64485
|
return assignedLineIdSet.has(lineId);
|
|
64121
64486
|
},
|
|
64122
64487
|
[assignedLineIds, assignedLineIdSet]
|
|
64123
64488
|
);
|
|
64124
|
-
const handleTimeRangeChange =
|
|
64489
|
+
const handleTimeRangeChange = React143__default.useCallback((newRange) => {
|
|
64125
64490
|
if (newRange === timeRange) return;
|
|
64126
64491
|
trackCoreEvent("Leaderboard Time Range Changed", {
|
|
64127
64492
|
from_range: timeRange,
|
|
@@ -64132,7 +64497,7 @@ var LinesLeaderboard = ({
|
|
|
64132
64497
|
});
|
|
64133
64498
|
setTimeRange(newRange);
|
|
64134
64499
|
}, [timeRange, lines.length, monthlyEfficiencyByLineId, setTimeRange]);
|
|
64135
|
-
const handleLeaderboardLineClick =
|
|
64500
|
+
const handleLeaderboardLineClick = React143__default.useCallback((item, clickSource) => {
|
|
64136
64501
|
if (!canClickLine(item.line.id)) return;
|
|
64137
64502
|
trackCoreEvent("Leaderboard Line Clicked", {
|
|
64138
64503
|
line_id: item.line.id,
|
|
@@ -64146,8 +64511,8 @@ var LinesLeaderboard = ({
|
|
|
64146
64511
|
});
|
|
64147
64512
|
onLineClick(item.line);
|
|
64148
64513
|
}, [canClickLine, onLineClick, timeRange]);
|
|
64149
|
-
const viewLoadedTrackedRef =
|
|
64150
|
-
const leaderboardData =
|
|
64514
|
+
const viewLoadedTrackedRef = React143__default.useRef(null);
|
|
64515
|
+
const leaderboardData = React143__default.useMemo(() => {
|
|
64151
64516
|
const loading = timeRange === "today" ? isLoadingToday : isLoadingMonthly;
|
|
64152
64517
|
const efficiencyMap = timeRange === "today" ? todayEfficiencyByLineId : monthlyEfficiencyByLineId;
|
|
64153
64518
|
return lines.map((line) => {
|
|
@@ -64178,7 +64543,7 @@ var LinesLeaderboard = ({
|
|
|
64178
64543
|
isLoadingToday,
|
|
64179
64544
|
isLoadingMonthly
|
|
64180
64545
|
]);
|
|
64181
|
-
|
|
64546
|
+
React143__default.useEffect(() => {
|
|
64182
64547
|
const isLoading = timeRange === "today" ? isLoadingToday : isLoadingMonthly;
|
|
64183
64548
|
const trackingKey = `${timeRange}-${leaderboardData.length}`;
|
|
64184
64549
|
if (leaderboardData.length > 0 && !isLoading && viewLoadedTrackedRef.current !== trackingKey) {
|
|
@@ -64204,7 +64569,7 @@ var LinesLeaderboard = ({
|
|
|
64204
64569
|
const countdownFormat = timeRange === "monthly" ? "days" : "clock";
|
|
64205
64570
|
const countdownFinishedLabel = timeRange === "monthly" ? "Finished" : "Shift Ended";
|
|
64206
64571
|
const showCountdown = timeRange === "monthly" || !isHistoricalDaily;
|
|
64207
|
-
const handleCountdownFinished =
|
|
64572
|
+
const handleCountdownFinished = React143__default.useCallback(() => {
|
|
64208
64573
|
trackCoreEvent("Leaderboard Countdown Finished", {
|
|
64209
64574
|
countdown_type: timeRange === "monthly" ? "month_end" : "shift_end",
|
|
64210
64575
|
time_range: timeRange,
|
|
@@ -64231,7 +64596,7 @@ var LinesLeaderboard = ({
|
|
|
64231
64596
|
return "bg-white border-gray-100";
|
|
64232
64597
|
}
|
|
64233
64598
|
};
|
|
64234
|
-
|
|
64599
|
+
React143__default.useEffect(() => {
|
|
64235
64600
|
const style = document.createElement("style");
|
|
64236
64601
|
style.innerHTML = `
|
|
64237
64602
|
@keyframes float {
|
|
@@ -64418,7 +64783,7 @@ var LineCard = ({
|
|
|
64418
64783
|
supervisors
|
|
64419
64784
|
}) => {
|
|
64420
64785
|
const isUptimeLine = (line.monitoring_mode ?? "output") === "uptime";
|
|
64421
|
-
const isOnTrack =
|
|
64786
|
+
const isOnTrack = React143__default.useMemo(() => {
|
|
64422
64787
|
if (!kpis) return null;
|
|
64423
64788
|
return isEfficiencyOnTrack(kpis.efficiency.value);
|
|
64424
64789
|
}, [kpis]);
|
|
@@ -64616,46 +64981,46 @@ var KPIsOverviewView = ({
|
|
|
64616
64981
|
const configuredTimezone = dbTimezone || dateTimeConfig.defaultTimezone || "UTC";
|
|
64617
64982
|
const { startDate: monthStartDate, endDate: monthEndDateKey, monthEndDate } = getMonthDateInfo(configuredTimezone);
|
|
64618
64983
|
const isSuperAdmin = user?.scope_mode === "SUPER_ADMIN" || !!user?.access_scope?.is_super_admin;
|
|
64619
|
-
const scopedLineIds =
|
|
64984
|
+
const scopedLineIds = React143__default.useMemo(
|
|
64620
64985
|
() => Array.isArray(user?.access_scope?.line_ids) ? user.access_scope.line_ids.filter((lineId) => typeof lineId === "string" && lineId.length > 0) : [],
|
|
64621
64986
|
[user?.access_scope?.line_ids]
|
|
64622
64987
|
);
|
|
64623
64988
|
const hasCanonicalScope = !!user?.scope_mode || !!user?.access_scope;
|
|
64624
64989
|
const scopeRole = (user?.role_level || user?.role || "").toLowerCase();
|
|
64625
64990
|
const isStrictLineScopedRole = scopeRole === "supervisor" || isFactoryScopedRole(scopeRole);
|
|
64626
|
-
const resolvedAssignedLineIds =
|
|
64991
|
+
const resolvedAssignedLineIds = React143__default.useMemo(() => {
|
|
64627
64992
|
if (isSuperAdmin) return [];
|
|
64628
64993
|
if (scopedLineIds.length > 0) return scopedLineIds;
|
|
64629
64994
|
if (lineIds && lineIds.length > 0) return lineIds;
|
|
64630
64995
|
if (isStrictLineScopedRole && hasCanonicalScope) return [];
|
|
64631
64996
|
return [];
|
|
64632
64997
|
}, [isSuperAdmin, scopedLineIds, lineIds, isStrictLineScopedRole, hasCanonicalScope]);
|
|
64633
|
-
const assignedLineIdSet =
|
|
64998
|
+
const assignedLineIdSet = React143__default.useMemo(
|
|
64634
64999
|
() => new Set(resolvedAssignedLineIds),
|
|
64635
65000
|
[resolvedAssignedLineIds]
|
|
64636
65001
|
);
|
|
64637
|
-
const metricsLineIds =
|
|
65002
|
+
const metricsLineIds = React143__default.useMemo(() => {
|
|
64638
65003
|
if (isSuperAdmin) {
|
|
64639
65004
|
return lineIds ?? [];
|
|
64640
65005
|
}
|
|
64641
65006
|
return resolvedAssignedLineIds;
|
|
64642
65007
|
}, [isSuperAdmin, lineIds, resolvedAssignedLineIds]);
|
|
64643
65008
|
const assignedLineIdsForLeaderboard = isSuperAdmin ? void 0 : resolvedAssignedLineIds;
|
|
64644
|
-
const leaderboardLinesForView =
|
|
65009
|
+
const leaderboardLinesForView = React143__default.useMemo(() => {
|
|
64645
65010
|
const targetMode = viewType === "machine" ? "uptime" : "output";
|
|
64646
65011
|
return leaderboardLines.filter((line) => (line.monitoring_mode ?? "output") === targetMode);
|
|
64647
65012
|
}, [leaderboardLines, viewType]);
|
|
64648
|
-
const linesForView =
|
|
65013
|
+
const linesForView = React143__default.useMemo(() => {
|
|
64649
65014
|
const targetMode = viewType === "machine" ? "uptime" : "output";
|
|
64650
65015
|
return lines.filter((line) => (line.monitoring_mode ?? "output") === targetMode);
|
|
64651
65016
|
}, [lines, viewType]);
|
|
64652
|
-
const relevantLinesForMode =
|
|
65017
|
+
const relevantLinesForMode = React143__default.useMemo(() => {
|
|
64653
65018
|
if (activeTab === "leaderboard") {
|
|
64654
65019
|
return leaderboardLines.length > 0 ? leaderboardLines : lines;
|
|
64655
65020
|
}
|
|
64656
65021
|
return lines;
|
|
64657
65022
|
}, [activeTab, leaderboardLines, lines]);
|
|
64658
|
-
const { hasUptime, hasOutput } =
|
|
65023
|
+
const { hasUptime, hasOutput } = React143__default.useMemo(() => {
|
|
64659
65024
|
let uptime = false;
|
|
64660
65025
|
let output = false;
|
|
64661
65026
|
for (const line of relevantLinesForMode) {
|
|
@@ -64680,14 +65045,14 @@ var KPIsOverviewView = ({
|
|
|
64680
65045
|
const currentShiftDetails = getCurrentShift(configuredTimezone, shiftConfig);
|
|
64681
65046
|
const currentShiftDate = currentShiftDetails.date;
|
|
64682
65047
|
const currentShiftId = currentShiftDetails.shiftId;
|
|
64683
|
-
const activeFiltersCount =
|
|
65048
|
+
const activeFiltersCount = React143__default.useMemo(() => {
|
|
64684
65049
|
let count = 0;
|
|
64685
65050
|
if (selectedLeaderboardShiftId !== currentShiftId) {
|
|
64686
65051
|
count++;
|
|
64687
65052
|
}
|
|
64688
65053
|
return count;
|
|
64689
65054
|
}, [selectedLeaderboardShiftId, currentShiftId]);
|
|
64690
|
-
const clearFilters =
|
|
65055
|
+
const clearFilters = React143__default.useCallback(() => {
|
|
64691
65056
|
setSelectedLeaderboardShiftId(currentShiftId);
|
|
64692
65057
|
}, [currentShiftId]);
|
|
64693
65058
|
useEffect(() => {
|
|
@@ -64701,11 +65066,11 @@ var KPIsOverviewView = ({
|
|
|
64701
65066
|
document.addEventListener("mousedown", handleClickOutside);
|
|
64702
65067
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
64703
65068
|
}, []);
|
|
64704
|
-
const shiftEndDate =
|
|
65069
|
+
const shiftEndDate = React143__default.useMemo(
|
|
64705
65070
|
() => getShiftEndDate(currentShiftDetails, configuredTimezone),
|
|
64706
65071
|
[currentShiftDetails, configuredTimezone]
|
|
64707
65072
|
);
|
|
64708
|
-
const leaderboardShiftOptions =
|
|
65073
|
+
const leaderboardShiftOptions = React143__default.useMemo(() => {
|
|
64709
65074
|
if (shiftConfig?.shifts && shiftConfig.shifts.length > 0) {
|
|
64710
65075
|
return shiftConfig.shifts.map((shift) => ({
|
|
64711
65076
|
id: shift.shiftId,
|
|
@@ -64785,15 +65150,15 @@ var KPIsOverviewView = ({
|
|
|
64785
65150
|
lineId: factoryViewId,
|
|
64786
65151
|
userAccessibleLineIds: metricsLineIds
|
|
64787
65152
|
});
|
|
64788
|
-
const defaultKPIs =
|
|
64789
|
-
const kpisByLineId =
|
|
65153
|
+
const defaultKPIs = React143__default.useMemo(() => createDefaultKPIs(), []);
|
|
65154
|
+
const kpisByLineId = React143__default.useMemo(() => {
|
|
64790
65155
|
const map = /* @__PURE__ */ new Map();
|
|
64791
65156
|
lineMetrics.forEach((row) => {
|
|
64792
65157
|
if (row?.line_id) map.set(row.line_id, buildKPIsFromLineMetricsRow(row));
|
|
64793
65158
|
});
|
|
64794
65159
|
return map;
|
|
64795
65160
|
}, [lineMetrics]);
|
|
64796
|
-
const supervisorLineIds =
|
|
65161
|
+
const supervisorLineIds = React143__default.useMemo(
|
|
64797
65162
|
() => (leaderboardLines.length > 0 ? leaderboardLines : lines).map((l) => l.id),
|
|
64798
65163
|
[leaderboardLines, lines]
|
|
64799
65164
|
);
|
|
@@ -65633,39 +65998,6 @@ var KPIsOverviewView = ({
|
|
|
65633
65998
|
] });
|
|
65634
65999
|
};
|
|
65635
66000
|
var KPIsOverviewView_default = KPIsOverviewView;
|
|
65636
|
-
var toFiniteNumber = (value) => {
|
|
65637
|
-
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
65638
|
-
if (typeof value === "string" && value.trim() !== "") {
|
|
65639
|
-
const parsed = Number(value);
|
|
65640
|
-
return Number.isFinite(parsed) ? parsed : null;
|
|
65641
|
-
}
|
|
65642
|
-
return null;
|
|
65643
|
-
};
|
|
65644
|
-
var getCycleRatio = (workspace) => {
|
|
65645
|
-
const idealCycleTime = toFiniteNumber(workspace.ideal_cycle_time);
|
|
65646
|
-
const avgCycleTime = toFiniteNumber(workspace.avg_cycle_time);
|
|
65647
|
-
if (idealCycleTime === null || avgCycleTime === null || idealCycleTime <= 0 || avgCycleTime <= 0) {
|
|
65648
|
-
return null;
|
|
65649
|
-
}
|
|
65650
|
-
return idealCycleTime / avgCycleTime;
|
|
65651
|
-
};
|
|
65652
|
-
var formatCycleTimeValue = (value) => {
|
|
65653
|
-
const numericValue = toFiniteNumber(value);
|
|
65654
|
-
if (numericValue === null || numericValue <= 0) return "--";
|
|
65655
|
-
return `${numericValue.toFixed(1)}s`;
|
|
65656
|
-
};
|
|
65657
|
-
var CycleTimeComparison = memo$1(({
|
|
65658
|
-
workspace
|
|
65659
|
-
}) => {
|
|
65660
|
-
const averageValue = formatCycleTimeValue(workspace.avg_cycle_time);
|
|
65661
|
-
const standardValue = formatCycleTimeValue(workspace.ideal_cycle_time);
|
|
65662
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 tabular-nums", children: [
|
|
65663
|
-
/* @__PURE__ */ jsx("span", { className: "font-semibold text-gray-900", children: averageValue }),
|
|
65664
|
-
/* @__PURE__ */ jsx("span", { className: "text-gray-400 font-normal", children: "/" }),
|
|
65665
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium text-gray-500", children: standardValue })
|
|
65666
|
-
] });
|
|
65667
|
-
}, (prevProps, nextProps) => prevProps.workspace.avg_cycle_time === nextProps.workspace.avg_cycle_time && prevProps.workspace.ideal_cycle_time === nextProps.workspace.ideal_cycle_time);
|
|
65668
|
-
CycleTimeComparison.displayName = "CycleTimeComparison";
|
|
65669
66001
|
var IsolatedTimer = memo$1(() => {
|
|
65670
66002
|
return /* @__PURE__ */ jsx(ISTTimer_default, {});
|
|
65671
66003
|
});
|
|
@@ -65917,7 +66249,7 @@ var LeaderboardDetailView = memo$1(({
|
|
|
65917
66249
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
65918
66250
|
}, []);
|
|
65919
66251
|
const [isMobile, setIsMobile] = useState(false);
|
|
65920
|
-
|
|
66252
|
+
React143__default.useEffect(() => {
|
|
65921
66253
|
const checkMobile = () => setIsMobile(window.innerWidth < 640);
|
|
65922
66254
|
checkMobile();
|
|
65923
66255
|
window.addEventListener("resize", checkMobile);
|
|
@@ -66207,10 +66539,25 @@ var LeaderboardDetailView = memo$1(({
|
|
|
66207
66539
|
setTodayLoading(true);
|
|
66208
66540
|
setTodayError(null);
|
|
66209
66541
|
try {
|
|
66210
|
-
|
|
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,
|
|
66211
66550
|
date: todayDate,
|
|
66212
|
-
|
|
66551
|
+
shift_id: todayShiftId.toString()
|
|
66213
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 || [];
|
|
66214
66561
|
if (todayRequestKeyRef.current !== requestKey) {
|
|
66215
66562
|
return;
|
|
66216
66563
|
}
|
|
@@ -66227,7 +66574,15 @@ var LeaderboardDetailView = memo$1(({
|
|
|
66227
66574
|
setTodayLoading(false);
|
|
66228
66575
|
}
|
|
66229
66576
|
}
|
|
66230
|
-
}, [
|
|
66577
|
+
}, [
|
|
66578
|
+
configuredLineIds,
|
|
66579
|
+
entityConfig.companyId,
|
|
66580
|
+
mapEntriesToWorkspaces,
|
|
66581
|
+
supabase,
|
|
66582
|
+
todayDate,
|
|
66583
|
+
todayShiftId,
|
|
66584
|
+
lineKey
|
|
66585
|
+
]);
|
|
66231
66586
|
const queueTodayLeaderboardRefresh = useCallback(() => {
|
|
66232
66587
|
if (leaderboardUpdateQueuedRef.current) return;
|
|
66233
66588
|
leaderboardUpdateQueuedRef.current = true;
|
|
@@ -68313,7 +68668,7 @@ var ShiftsView = ({
|
|
|
68313
68668
|
] })
|
|
68314
68669
|
] });
|
|
68315
68670
|
};
|
|
68316
|
-
var AuthenticatedShiftsView = withAuth(
|
|
68671
|
+
var AuthenticatedShiftsView = withAuth(React143__default.memo(ShiftsView));
|
|
68317
68672
|
var ShiftsView_default = ShiftsView;
|
|
68318
68673
|
|
|
68319
68674
|
// src/views/TargetsView.utils.ts
|
|
@@ -70015,7 +70370,7 @@ var TargetsView = ({
|
|
|
70015
70370
|
};
|
|
70016
70371
|
var TargetsViewWithDisplayNames = withAllWorkspaceDisplayNames(TargetsView);
|
|
70017
70372
|
var TargetsView_default = TargetsViewWithDisplayNames;
|
|
70018
|
-
var AuthenticatedTargetsView = withAuth(
|
|
70373
|
+
var AuthenticatedTargetsView = withAuth(React143__default.memo(TargetsViewWithDisplayNames));
|
|
70019
70374
|
function useTimezone(options = {}) {
|
|
70020
70375
|
const dashboardConfig = useDashboardConfig();
|
|
70021
70376
|
const workspaceConfig = useWorkspaceConfig();
|
|
@@ -73434,7 +73789,7 @@ function BottleneckClipsView({
|
|
|
73434
73789
|
) })
|
|
73435
73790
|
] }) });
|
|
73436
73791
|
}
|
|
73437
|
-
var AuthenticatedBottleneckClipsView = withAuth(
|
|
73792
|
+
var AuthenticatedBottleneckClipsView = withAuth(React143__default.memo(BottleneckClipsView));
|
|
73438
73793
|
var BottleneckClipsView_default = BottleneckClipsView;
|
|
73439
73794
|
|
|
73440
73795
|
// src/lib/services/ticketService.ts
|
|
@@ -73464,8 +73819,8 @@ var TicketService = class {
|
|
|
73464
73819
|
return response;
|
|
73465
73820
|
} catch (error) {
|
|
73466
73821
|
lastError = error instanceof Error ? error : new Error(String(error));
|
|
73467
|
-
const
|
|
73468
|
-
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) {
|
|
73469
73824
|
throw lastError;
|
|
73470
73825
|
}
|
|
73471
73826
|
const delay2 = 1e3 * Math.pow(2, attempt);
|
|
@@ -73480,69 +73835,78 @@ var TicketService = class {
|
|
|
73480
73835
|
* Uses the user's JWT access token from Supabase session (NOT the anon key)
|
|
73481
73836
|
*/
|
|
73482
73837
|
async fetchWithAuth(url, options = {}) {
|
|
73483
|
-
|
|
73484
|
-
|
|
73485
|
-
|
|
73486
|
-
const { data: { session }, error: sessionError } = await this.supabaseClient.auth.getSession();
|
|
73487
|
-
if (sessionError) {
|
|
73488
|
-
console.error("Session error:", sessionError);
|
|
73489
|
-
throw new Error("Failed to get authentication session. Please log in.");
|
|
73490
|
-
}
|
|
73491
|
-
if (!session) {
|
|
73492
|
-
console.error("No session found. User must be logged in.");
|
|
73493
|
-
throw new Error("User not authenticated. Please log in.");
|
|
73494
|
-
}
|
|
73495
|
-
if (!session.access_token) {
|
|
73496
|
-
console.error("Session exists but no access_token found");
|
|
73497
|
-
throw new Error("Invalid session. Please log in again.");
|
|
73498
|
-
}
|
|
73499
|
-
const token = session.access_token;
|
|
73500
|
-
if (process.env.NODE_ENV === "development") {
|
|
73501
|
-
console.log("[TicketService] Using JWT token (first 20 chars):", token.substring(0, 20) + "...");
|
|
73502
|
-
console.log("[TicketService] Token is NOT the anon key - it is the user JWT from session.access_token");
|
|
73503
|
-
}
|
|
73504
|
-
const headers = {
|
|
73505
|
-
"Content-Type": "application/json",
|
|
73506
|
-
...options.headers,
|
|
73507
|
-
"Authorization": `Bearer ${token}`
|
|
73508
|
-
// This is the USER's JWT, not the anon key
|
|
73509
|
-
};
|
|
73510
|
-
const response = await this.fetchWithRetry(url, {
|
|
73511
|
-
...options,
|
|
73512
|
-
headers
|
|
73513
|
-
});
|
|
73514
|
-
if (response.status === 401) {
|
|
73515
|
-
console.error("401 Unauthorized - Token expired or invalid");
|
|
73516
|
-
throw new Error("Authentication failed. Token expired or invalid. Please log in again.");
|
|
73517
|
-
}
|
|
73518
|
-
if (response.status === 403) {
|
|
73519
|
-
console.error("403 Forbidden - User does not have permission");
|
|
73520
|
-
throw new Error("Access denied. You do not have permission to access this resource.");
|
|
73521
|
-
}
|
|
73522
|
-
if (response.status === 500) {
|
|
73523
|
-
console.error("500 Internal Server Error - Backend error");
|
|
73524
|
-
let errorDetail = "Internal server error occurred.";
|
|
73525
|
-
try {
|
|
73526
|
-
const errorData = await response.text();
|
|
73527
|
-
console.error("Backend error details:", errorData);
|
|
73528
|
-
errorDetail = errorData || errorDetail;
|
|
73529
|
-
} catch (e) {
|
|
73838
|
+
try {
|
|
73839
|
+
if (!this.supabaseClient) {
|
|
73840
|
+
throw new Error("Supabase client not initialized. Please provide a Supabase client to TicketService.");
|
|
73530
73841
|
}
|
|
73531
|
-
|
|
73532
|
-
|
|
73533
|
-
|
|
73534
|
-
|
|
73535
|
-
|
|
73536
|
-
|
|
73537
|
-
|
|
73538
|
-
|
|
73539
|
-
|
|
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) {
|
|
73540
73885
|
}
|
|
73541
|
-
|
|
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}`);
|
|
73542
73899
|
}
|
|
73543
|
-
|
|
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;
|
|
73544
73909
|
}
|
|
73545
|
-
return response;
|
|
73546
73910
|
}
|
|
73547
73911
|
/**
|
|
73548
73912
|
* Get tickets with filters and pagination
|
|
@@ -74265,7 +74629,7 @@ Please ensure:
|
|
|
74265
74629
|
)
|
|
74266
74630
|
] });
|
|
74267
74631
|
}
|
|
74268
|
-
var AuthenticatedTicketsView = withAuth(
|
|
74632
|
+
var AuthenticatedTicketsView = withAuth(React143__default.memo(TicketsView));
|
|
74269
74633
|
var TicketsView_default = TicketsView;
|
|
74270
74634
|
|
|
74271
74635
|
// src/lib/utils/improvementDisplay.ts
|
|
@@ -75236,7 +75600,7 @@ var ImprovementCenterView = () => {
|
|
|
75236
75600
|
setSelectedMemberId("all");
|
|
75237
75601
|
}
|
|
75238
75602
|
}, [memberOptions, selectedMemberId]);
|
|
75239
|
-
const getRecommendationDisplayMetadata =
|
|
75603
|
+
const getRecommendationDisplayMetadata = React143__default.useCallback((rec) => {
|
|
75240
75604
|
const supervisors = rec.line_id ? supervisorsByLineId.get(rec.line_id) || [] : [];
|
|
75241
75605
|
return getImprovementDisplayMetadata({
|
|
75242
75606
|
location: rec.location,
|
|
@@ -75710,7 +76074,7 @@ var ThreadSidebar = ({
|
|
|
75710
76074
|
] }) })
|
|
75711
76075
|
] });
|
|
75712
76076
|
};
|
|
75713
|
-
var ProfilePicture =
|
|
76077
|
+
var ProfilePicture = React143__default.memo(({
|
|
75714
76078
|
alt = "Axel",
|
|
75715
76079
|
className = "",
|
|
75716
76080
|
size = "md",
|
|
@@ -78235,7 +78599,7 @@ var OverviewImprovementsSkeleton = () => /* @__PURE__ */ jsx("div", { className:
|
|
|
78235
78599
|
] }),
|
|
78236
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" }) })
|
|
78237
78601
|
] }, index)) });
|
|
78238
|
-
var OperationsOverviewHeader =
|
|
78602
|
+
var OperationsOverviewHeader = React143__default.memo(({
|
|
78239
78603
|
dateRange,
|
|
78240
78604
|
displayDateRange,
|
|
78241
78605
|
trendMode,
|
|
@@ -78255,65 +78619,65 @@ var OperationsOverviewHeader = React142__default.memo(({
|
|
|
78255
78619
|
bumpRenderCounter();
|
|
78256
78620
|
const subtitleRange = displayDateRange || dateRange;
|
|
78257
78621
|
const showLiveShiftMeta = isLiveScope && trendMode !== "all";
|
|
78258
|
-
const liveShiftLabel =
|
|
78622
|
+
const liveShiftLabel = React143__default.useMemo(
|
|
78259
78623
|
() => normalizeShiftLabel(liveShiftName, trendMode),
|
|
78260
78624
|
[liveShiftName, trendMode]
|
|
78261
78625
|
);
|
|
78262
|
-
const liveShiftIcon =
|
|
78626
|
+
const liveShiftIcon = React143__default.useMemo(
|
|
78263
78627
|
() => getShiftIcon(liveShiftName, trendMode),
|
|
78264
78628
|
[liveShiftName, trendMode]
|
|
78265
78629
|
);
|
|
78266
|
-
const [isFilterOpen, setIsFilterOpen] =
|
|
78267
|
-
const [isLinesDropdownOpen, setIsLinesDropdownOpen] =
|
|
78268
|
-
const filterRef =
|
|
78269
|
-
const filterButtonRef =
|
|
78270
|
-
const mobileFilterButtonRef =
|
|
78271
|
-
const linesDropdownRef =
|
|
78272
|
-
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(() => {
|
|
78273
78637
|
if (subtitleRange.startKey === subtitleRange.endKey) {
|
|
78274
78638
|
return format(parseDateKeyToDate(subtitleRange.startKey), "do MMM, yyyy");
|
|
78275
78639
|
}
|
|
78276
78640
|
return `${format(parseDateKeyToDate(subtitleRange.startKey), "do MMM")} - ${format(parseDateKeyToDate(subtitleRange.endKey), "do MMM, yyyy")}`;
|
|
78277
78641
|
}, [subtitleRange.endKey, subtitleRange.startKey]);
|
|
78278
|
-
const desktopSubtitle =
|
|
78642
|
+
const desktopSubtitle = React143__default.useMemo(() => {
|
|
78279
78643
|
if (subtitleRange.startKey === subtitleRange.endKey) {
|
|
78280
78644
|
return format(parseDateKeyToDate(subtitleRange.startKey), "do MMMM, yyyy");
|
|
78281
78645
|
}
|
|
78282
78646
|
return `${format(parseDateKeyToDate(subtitleRange.startKey), "do MMMM, yyyy")} - ${format(parseDateKeyToDate(subtitleRange.endKey), "do MMMM, yyyy")}`;
|
|
78283
78647
|
}, [subtitleRange.endKey, subtitleRange.startKey]);
|
|
78284
|
-
const availableLineIds =
|
|
78648
|
+
const availableLineIds = React143__default.useMemo(
|
|
78285
78649
|
() => lineOptions.map((line) => line.id),
|
|
78286
78650
|
[lineOptions]
|
|
78287
78651
|
);
|
|
78288
|
-
const selectedLineIdSet =
|
|
78652
|
+
const selectedLineIdSet = React143__default.useMemo(
|
|
78289
78653
|
() => new Set(selectedLineIds),
|
|
78290
78654
|
[selectedLineIds]
|
|
78291
78655
|
);
|
|
78292
|
-
const isAllLinesSelected =
|
|
78656
|
+
const isAllLinesSelected = React143__default.useMemo(() => {
|
|
78293
78657
|
if (availableLineIds.length === 0) return true;
|
|
78294
78658
|
return availableLineIds.every((lineId) => selectedLineIdSet.has(lineId));
|
|
78295
78659
|
}, [availableLineIds, selectedLineIdSet]);
|
|
78296
|
-
const activeFilterCount =
|
|
78660
|
+
const activeFilterCount = React143__default.useMemo(() => {
|
|
78297
78661
|
let count = 0;
|
|
78298
78662
|
if (trendMode !== "all") count += 1;
|
|
78299
78663
|
if (selectedSupervisorId !== "all") count += 1;
|
|
78300
78664
|
if (!isAllLinesSelected) count += 1;
|
|
78301
78665
|
return count;
|
|
78302
78666
|
}, [isAllLinesSelected, selectedSupervisorId, trendMode]);
|
|
78303
|
-
const handleFilterToggle =
|
|
78667
|
+
const handleFilterToggle = React143__default.useCallback(() => {
|
|
78304
78668
|
trackCoreEvent("Operations Overview Filter Toggled", {
|
|
78305
78669
|
action: !isFilterOpen ? "open" : "close"
|
|
78306
78670
|
});
|
|
78307
78671
|
setIsFilterOpen((previous) => !previous);
|
|
78308
78672
|
}, [isFilterOpen]);
|
|
78309
|
-
const handleTrendModeChange =
|
|
78673
|
+
const handleTrendModeChange = React143__default.useCallback((event) => {
|
|
78310
78674
|
const nextMode = event.target.value;
|
|
78311
78675
|
trackCoreEvent("Operations Overview Shift Filter Changed", {
|
|
78312
78676
|
shift_mode: nextMode
|
|
78313
78677
|
});
|
|
78314
78678
|
onTrendModeChange(nextMode);
|
|
78315
78679
|
}, [onTrendModeChange]);
|
|
78316
|
-
const handleAllLinesToggle =
|
|
78680
|
+
const handleAllLinesToggle = React143__default.useCallback(() => {
|
|
78317
78681
|
trackCoreEvent("Operations Overview Line Filter Changed", {
|
|
78318
78682
|
selected_line_ids: availableLineIds,
|
|
78319
78683
|
selected_line_count: availableLineIds.length,
|
|
@@ -78321,7 +78685,7 @@ var OperationsOverviewHeader = React142__default.memo(({
|
|
|
78321
78685
|
});
|
|
78322
78686
|
onSelectedLineIdsChange(availableLineIds);
|
|
78323
78687
|
}, [availableLineIds, onSelectedLineIdsChange]);
|
|
78324
|
-
const handleSupervisorChange =
|
|
78688
|
+
const handleSupervisorChange = React143__default.useCallback((event) => {
|
|
78325
78689
|
const supervisorId = event.target.value;
|
|
78326
78690
|
const selectedSupervisor = supervisorOptions.find((option) => option.id === supervisorId);
|
|
78327
78691
|
trackCoreEvent("Operations Overview Supervisor Filter Changed", {
|
|
@@ -78332,7 +78696,7 @@ var OperationsOverviewHeader = React142__default.memo(({
|
|
|
78332
78696
|
});
|
|
78333
78697
|
onSelectedSupervisorIdChange(supervisorId);
|
|
78334
78698
|
}, [availableLineIds, onSelectedSupervisorIdChange, supervisorOptions]);
|
|
78335
|
-
const handleLineToggle =
|
|
78699
|
+
const handleLineToggle = React143__default.useCallback((lineId) => {
|
|
78336
78700
|
const current = new Set(selectedLineIds);
|
|
78337
78701
|
if (current.has(lineId)) {
|
|
78338
78702
|
if (current.size <= 1) return;
|
|
@@ -78348,13 +78712,13 @@ var OperationsOverviewHeader = React142__default.memo(({
|
|
|
78348
78712
|
});
|
|
78349
78713
|
onSelectedLineIdsChange(next);
|
|
78350
78714
|
}, [availableLineIds, onSelectedLineIdsChange, selectedLineIds]);
|
|
78351
|
-
const handleClearAllFilters =
|
|
78715
|
+
const handleClearAllFilters = React143__default.useCallback(() => {
|
|
78352
78716
|
onTrendModeChange("all");
|
|
78353
78717
|
onSelectedSupervisorIdChange("all");
|
|
78354
78718
|
onSelectedLineIdsChange(availableLineIds);
|
|
78355
78719
|
setIsFilterOpen(false);
|
|
78356
78720
|
}, [availableLineIds, onSelectedLineIdsChange, onSelectedSupervisorIdChange, onTrendModeChange]);
|
|
78357
|
-
|
|
78721
|
+
React143__default.useEffect(() => {
|
|
78358
78722
|
const handleClickOutside = (event) => {
|
|
78359
78723
|
const target = event.target;
|
|
78360
78724
|
if (filterRef.current && !filterRef.current.contains(target) && filterButtonRef.current && !filterButtonRef.current.contains(target) && mobileFilterButtonRef.current && !mobileFilterButtonRef.current.contains(target)) {
|
|
@@ -78593,12 +78957,12 @@ var OperationsOverviewHeader = React142__default.memo(({
|
|
|
78593
78957
|
] }) });
|
|
78594
78958
|
});
|
|
78595
78959
|
OperationsOverviewHeader.displayName = "OperationsOverviewHeader";
|
|
78596
|
-
var OverviewSummaryCards =
|
|
78960
|
+
var OverviewSummaryCards = React143__default.memo(({ store }) => {
|
|
78597
78961
|
bumpRenderCounter();
|
|
78598
78962
|
const scope = useOperationsOverviewScope(store);
|
|
78599
78963
|
const snapshot = useOperationsOverviewSnapshot(store);
|
|
78600
78964
|
const showSnapshotSkeleton = snapshot.loading && !snapshot.hasLoadedOnce;
|
|
78601
|
-
const comparisonLabel =
|
|
78965
|
+
const comparisonLabel = React143__default.useMemo(() => {
|
|
78602
78966
|
return formatComparisonWindow({
|
|
78603
78967
|
currentDayCount: scope.current_range?.day_count ?? null,
|
|
78604
78968
|
previousDayCount: scope.previous_range?.day_count ?? null,
|
|
@@ -78611,27 +78975,27 @@ var OverviewSummaryCards = React142__default.memo(({ store }) => {
|
|
|
78611
78975
|
scope.previous_range?.day_count,
|
|
78612
78976
|
scope.shift_mode
|
|
78613
78977
|
]);
|
|
78614
|
-
const [isIdleContributorsOpen, setIsIdleContributorsOpen] =
|
|
78615
|
-
const [isIdleContributorsPinned, setIsIdleContributorsPinned] =
|
|
78616
|
-
const idleContributorsRef =
|
|
78617
|
-
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(() => {
|
|
78618
78982
|
return buildDeltaBadge(snapshot.data.summary.plant_efficiency?.delta_pp, {
|
|
78619
78983
|
positiveIsGood: true,
|
|
78620
78984
|
formatter: (value) => `${value >= 0 ? "+" : ""}${roundOne(value)}%`,
|
|
78621
78985
|
comparisonLabel
|
|
78622
78986
|
});
|
|
78623
78987
|
}, [comparisonLabel, snapshot.data.summary.plant_efficiency?.delta_pp]);
|
|
78624
|
-
const idleBadge =
|
|
78988
|
+
const idleBadge = React143__default.useMemo(() => {
|
|
78625
78989
|
return buildDeltaBadge(snapshot.data.summary.avg_idle_per_workstation?.delta_seconds, {
|
|
78626
78990
|
positiveIsGood: false,
|
|
78627
78991
|
formatter: (value) => formatSignedIdleDuration(value),
|
|
78628
78992
|
comparisonLabel
|
|
78629
78993
|
});
|
|
78630
78994
|
}, [comparisonLabel, snapshot.data.summary.avg_idle_per_workstation?.delta_seconds]);
|
|
78631
|
-
const canInspectIdleContributors =
|
|
78995
|
+
const canInspectIdleContributors = React143__default.useMemo(() => {
|
|
78632
78996
|
return !showSnapshotSkeleton && snapshot.data.summary.avg_idle_per_workstation?.current_seconds !== null && snapshot.data.summary.avg_idle_per_workstation?.current_seconds !== void 0;
|
|
78633
78997
|
}, [showSnapshotSkeleton, snapshot.data.summary.avg_idle_per_workstation?.current_seconds]);
|
|
78634
|
-
const idleTopContributors =
|
|
78998
|
+
const idleTopContributors = React143__default.useMemo(() => {
|
|
78635
78999
|
return (snapshot.data.summary.avg_idle_per_workstation?.top_contributors || []).map((item) => ({
|
|
78636
79000
|
workspaceId: item.workspace_id || "",
|
|
78637
79001
|
workspaceName: item.workspace_name?.trim() || item.workspace_id || "Unknown",
|
|
@@ -78639,14 +79003,14 @@ var OverviewSummaryCards = React142__default.memo(({ store }) => {
|
|
|
78639
79003
|
avgIdleSeconds: toNumber3(item.avg_idle_seconds)
|
|
78640
79004
|
})).slice(0, 5);
|
|
78641
79005
|
}, [snapshot.data.summary.avg_idle_per_workstation?.top_contributors]);
|
|
78642
|
-
const showIdleContributorLineNames =
|
|
79006
|
+
const showIdleContributorLineNames = React143__default.useMemo(() => {
|
|
78643
79007
|
return (scope.line_count ?? 0) > 1;
|
|
78644
79008
|
}, [scope.line_count]);
|
|
78645
|
-
const closeIdleContributors =
|
|
79009
|
+
const closeIdleContributors = React143__default.useCallback(() => {
|
|
78646
79010
|
setIsIdleContributorsOpen(false);
|
|
78647
79011
|
setIsIdleContributorsPinned(false);
|
|
78648
79012
|
}, []);
|
|
78649
|
-
const handleIdleContributorsToggle =
|
|
79013
|
+
const handleIdleContributorsToggle = React143__default.useCallback(() => {
|
|
78650
79014
|
if (!canInspectIdleContributors) return;
|
|
78651
79015
|
setIsIdleContributorsPinned((previous) => {
|
|
78652
79016
|
const next = !previous;
|
|
@@ -78654,7 +79018,7 @@ var OverviewSummaryCards = React142__default.memo(({ store }) => {
|
|
|
78654
79018
|
return next;
|
|
78655
79019
|
});
|
|
78656
79020
|
}, [canInspectIdleContributors]);
|
|
78657
|
-
const handleIdleContributorsKeyDown =
|
|
79021
|
+
const handleIdleContributorsKeyDown = React143__default.useCallback((event) => {
|
|
78658
79022
|
if (!canInspectIdleContributors) return;
|
|
78659
79023
|
if (event.key === "Enter" || event.key === " ") {
|
|
78660
79024
|
event.preventDefault();
|
|
@@ -78666,11 +79030,11 @@ var OverviewSummaryCards = React142__default.memo(({ store }) => {
|
|
|
78666
79030
|
closeIdleContributors();
|
|
78667
79031
|
}
|
|
78668
79032
|
}, [canInspectIdleContributors, closeIdleContributors, handleIdleContributorsToggle]);
|
|
78669
|
-
|
|
79033
|
+
React143__default.useEffect(() => {
|
|
78670
79034
|
setIsIdleContributorsOpen(false);
|
|
78671
79035
|
setIsIdleContributorsPinned(false);
|
|
78672
79036
|
}, [scope.comparison_strategy, scope.current_range?.start_date, scope.current_range?.end_date, scope.line_count, scope.shift_mode]);
|
|
78673
|
-
|
|
79037
|
+
React143__default.useEffect(() => {
|
|
78674
79038
|
if (!isIdleContributorsOpen) return void 0;
|
|
78675
79039
|
const handleClickOutside = (event) => {
|
|
78676
79040
|
if (!isIdleContributorsPinned) return;
|
|
@@ -78808,7 +79172,7 @@ var OverviewSummaryCards = React142__default.memo(({ store }) => {
|
|
|
78808
79172
|
] });
|
|
78809
79173
|
});
|
|
78810
79174
|
OverviewSummaryCards.displayName = "OverviewSummaryCards";
|
|
78811
|
-
var PoorestPerformersCard =
|
|
79175
|
+
var PoorestPerformersCard = React143__default.memo(({
|
|
78812
79176
|
store,
|
|
78813
79177
|
supervisorsByLineId,
|
|
78814
79178
|
onViewAll,
|
|
@@ -78817,9 +79181,9 @@ var PoorestPerformersCard = React142__default.memo(({
|
|
|
78817
79181
|
bumpRenderCounter();
|
|
78818
79182
|
const scope = useOperationsOverviewScope(store);
|
|
78819
79183
|
const snapshot = useOperationsOverviewSnapshot(store);
|
|
78820
|
-
const [poorestLineMode, setPoorestLineMode] =
|
|
79184
|
+
const [poorestLineMode, setPoorestLineMode] = React143__default.useState("output");
|
|
78821
79185
|
const availableLineModes = scope.available_line_modes;
|
|
78822
|
-
|
|
79186
|
+
React143__default.useEffect(() => {
|
|
78823
79187
|
const hasOutput = !!availableLineModes?.has_output;
|
|
78824
79188
|
const hasUptime = !!availableLineModes?.has_uptime;
|
|
78825
79189
|
if (hasOutput && !hasUptime && poorestLineMode !== "output") {
|
|
@@ -78828,7 +79192,7 @@ var PoorestPerformersCard = React142__default.memo(({
|
|
|
78828
79192
|
setPoorestLineMode("uptime");
|
|
78829
79193
|
}
|
|
78830
79194
|
}, [availableLineModes?.has_output, availableLineModes?.has_uptime, poorestLineMode]);
|
|
78831
|
-
const comparisonLabel =
|
|
79195
|
+
const comparisonLabel = React143__default.useMemo(() => {
|
|
78832
79196
|
return formatComparisonWindow({
|
|
78833
79197
|
currentDayCount: scope.current_range?.day_count ?? null,
|
|
78834
79198
|
previousDayCount: scope.previous_range?.day_count ?? null,
|
|
@@ -78842,7 +79206,7 @@ var PoorestPerformersCard = React142__default.memo(({
|
|
|
78842
79206
|
scope.shift_mode
|
|
78843
79207
|
]);
|
|
78844
79208
|
const showSnapshotSkeleton = snapshot.loading && !snapshot.hasLoadedOnce;
|
|
78845
|
-
const mergedPoorestLines =
|
|
79209
|
+
const mergedPoorestLines = React143__default.useMemo(() => {
|
|
78846
79210
|
const rows = snapshot.data.poorest_lines?.[poorestLineMode] || [];
|
|
78847
79211
|
return rows.slice(0, 3).map((line) => {
|
|
78848
79212
|
const lineId = line.line_id || "";
|
|
@@ -78861,7 +79225,7 @@ var PoorestPerformersCard = React142__default.memo(({
|
|
|
78861
79225
|
}, [poorestLineMode, snapshot.data.poorest_lines, supervisorsByLineId]);
|
|
78862
79226
|
const showPoorestModeToggle = !!availableLineModes?.has_output && !!availableLineModes?.has_uptime;
|
|
78863
79227
|
const poorestMetricLabel = poorestLineMode === "uptime" ? "Uptime" : "Efficiency";
|
|
78864
|
-
const handlePoorestLineModeChange =
|
|
79228
|
+
const handlePoorestLineModeChange = React143__default.useCallback((mode) => {
|
|
78865
79229
|
trackCoreEvent("Operations Overview Poorest Line Mode Changed", { mode });
|
|
78866
79230
|
setPoorestLineMode(mode);
|
|
78867
79231
|
}, []);
|
|
@@ -78947,14 +79311,14 @@ var PoorestPerformersCard = React142__default.memo(({
|
|
|
78947
79311
|
] });
|
|
78948
79312
|
});
|
|
78949
79313
|
PoorestPerformersCard.displayName = "PoorestPerformersCard";
|
|
78950
|
-
var IdleBreakdownCard =
|
|
79314
|
+
var IdleBreakdownCard = React143__default.memo(({
|
|
78951
79315
|
store,
|
|
78952
79316
|
scopedLineCount
|
|
78953
79317
|
}) => {
|
|
78954
79318
|
bumpRenderCounter();
|
|
78955
79319
|
const idle = useOperationsOverviewIdle(store);
|
|
78956
79320
|
const showInitialSkeleton = idle.loading && idle.lastUpdated === null;
|
|
78957
|
-
const idleBreakdown =
|
|
79321
|
+
const idleBreakdown = React143__default.useMemo(() => {
|
|
78958
79322
|
return idle.data.map((item) => ({
|
|
78959
79323
|
name: item.display_name?.trim() || item.reason?.trim() || "Unknown",
|
|
78960
79324
|
reasonKey: item.reason_key?.trim() || item.reason?.trim() || "unknown",
|
|
@@ -78973,7 +79337,7 @@ var IdleBreakdownCard = React142__default.memo(({
|
|
|
78973
79337
|
}))
|
|
78974
79338
|
})).filter((item) => item.value > 0);
|
|
78975
79339
|
}, [idle.data]);
|
|
78976
|
-
const showIdleModuleNotEnabledState =
|
|
79340
|
+
const showIdleModuleNotEnabledState = React143__default.useMemo(() => {
|
|
78977
79341
|
const enabledLineCount = idle.scope.idle_time_vlm_enabled_line_count;
|
|
78978
79342
|
return !showInitialSkeleton && scopedLineCount > 0 && typeof enabledLineCount === "number" && enabledLineCount === 0;
|
|
78979
79343
|
}, [idle.scope.idle_time_vlm_enabled_line_count, scopedLineCount, showInitialSkeleton]);
|
|
@@ -78994,7 +79358,7 @@ var IdleBreakdownCard = React142__default.memo(({
|
|
|
78994
79358
|
] });
|
|
78995
79359
|
});
|
|
78996
79360
|
IdleBreakdownCard.displayName = "IdleBreakdownCard";
|
|
78997
|
-
var EfficiencyTrendCard =
|
|
79361
|
+
var EfficiencyTrendCard = React143__default.memo(({
|
|
78998
79362
|
store,
|
|
78999
79363
|
dateRange,
|
|
79000
79364
|
appTimezone,
|
|
@@ -79002,14 +79366,14 @@ var EfficiencyTrendCard = React142__default.memo(({
|
|
|
79002
79366
|
}) => {
|
|
79003
79367
|
bumpRenderCounter();
|
|
79004
79368
|
const trend = useOperationsOverviewTrend(store);
|
|
79005
|
-
const currentWeekRange =
|
|
79369
|
+
const currentWeekRange = React143__default.useMemo(
|
|
79006
79370
|
() => getCurrentWeekToDateRange(appTimezone),
|
|
79007
79371
|
[appTimezone]
|
|
79008
79372
|
);
|
|
79009
79373
|
const isCurrentWeekToDateRange = dateRange.startKey === currentWeekRange.startKey && dateRange.endKey === currentWeekRange.endKey;
|
|
79010
79374
|
const showInitialSkeleton = trend.loading && trend.lastUpdated === null;
|
|
79011
79375
|
const isHourlyTrend = trend.data.granularity === "hour";
|
|
79012
|
-
const trendData =
|
|
79376
|
+
const trendData = React143__default.useMemo(() => {
|
|
79013
79377
|
if (isHourlyTrend) {
|
|
79014
79378
|
return (trend.data.points || []).map((point, index) => ({
|
|
79015
79379
|
name: (() => {
|
|
@@ -79081,13 +79445,13 @@ var EfficiencyTrendCard = React142__default.memo(({
|
|
|
79081
79445
|
};
|
|
79082
79446
|
});
|
|
79083
79447
|
}, [currentWeekRange.startKey, hourlyLabelStartTime, isCurrentWeekToDateRange, isHourlyTrend, trend.data.points]);
|
|
79084
|
-
const trendTooltipLabelFormatter =
|
|
79448
|
+
const trendTooltipLabelFormatter = React143__default.useCallback((label, payload) => {
|
|
79085
79449
|
if (isHourlyTrend) return label;
|
|
79086
79450
|
const dayOfWeek = payload?.[0]?.payload?.dayOfWeek;
|
|
79087
79451
|
if (!dayOfWeek || typeof label !== "string") return label;
|
|
79088
79452
|
return `${label} (${dayOfWeek})`;
|
|
79089
79453
|
}, [isHourlyTrend]);
|
|
79090
|
-
const trendXAxisTickFormatter =
|
|
79454
|
+
const trendXAxisTickFormatter = React143__default.useCallback((value, index) => {
|
|
79091
79455
|
if (!isHourlyTrend) {
|
|
79092
79456
|
return typeof value === "string" ? value : String(value ?? "");
|
|
79093
79457
|
}
|
|
@@ -79114,7 +79478,7 @@ var EfficiencyTrendCard = React142__default.memo(({
|
|
|
79114
79478
|
] });
|
|
79115
79479
|
});
|
|
79116
79480
|
EfficiencyTrendCard.displayName = "EfficiencyTrendCard";
|
|
79117
|
-
var TopImprovementsCard =
|
|
79481
|
+
var TopImprovementsCard = React143__default.memo(({
|
|
79118
79482
|
store,
|
|
79119
79483
|
supervisorsByLineId,
|
|
79120
79484
|
onViewAll,
|
|
@@ -79123,7 +79487,7 @@ var TopImprovementsCard = React142__default.memo(({
|
|
|
79123
79487
|
bumpRenderCounter();
|
|
79124
79488
|
const improvements = useOperationsOverviewImprovements(store);
|
|
79125
79489
|
const showInitialSkeleton = improvements.loading && improvements.lastUpdated === null;
|
|
79126
|
-
const displayImprovements =
|
|
79490
|
+
const displayImprovements = React143__default.useMemo(() => {
|
|
79127
79491
|
return improvements.data.map((item) => {
|
|
79128
79492
|
const supervisors = item.lineId ? supervisorsByLineId.get(item.lineId) || [] : [];
|
|
79129
79493
|
return {
|
|
@@ -79196,7 +79560,7 @@ var debugRefreshLog = (message, payload) => {
|
|
|
79196
79560
|
}
|
|
79197
79561
|
console.log(`[OperationsOverviewRefresh] ${message}`);
|
|
79198
79562
|
};
|
|
79199
|
-
var
|
|
79563
|
+
var isAbortError2 = (error) => {
|
|
79200
79564
|
return error instanceof DOMException && error.name === "AbortError";
|
|
79201
79565
|
};
|
|
79202
79566
|
var toNumber4 = (value) => {
|
|
@@ -79251,33 +79615,33 @@ var useOperationsOverviewRefresh = ({
|
|
|
79251
79615
|
isLiveScope,
|
|
79252
79616
|
enabled = true
|
|
79253
79617
|
}) => {
|
|
79254
|
-
const lineIdsKey =
|
|
79255
|
-
const scopeSignature =
|
|
79618
|
+
const lineIdsKey = React143__default.useMemo(() => lineIds.join(","), [lineIds]);
|
|
79619
|
+
const scopeSignature = React143__default.useMemo(
|
|
79256
79620
|
() => [companyId || "", startKey, endKey, trendMode, comparisonStrategy || "", lineIdsKey].join("::"),
|
|
79257
79621
|
[companyId, comparisonStrategy, endKey, lineIdsKey, startKey, trendMode]
|
|
79258
79622
|
);
|
|
79259
|
-
const controllersRef =
|
|
79260
|
-
const requestIdsRef =
|
|
79623
|
+
const controllersRef = React143__default.useRef({});
|
|
79624
|
+
const requestIdsRef = React143__default.useRef({
|
|
79261
79625
|
snapshot: 0,
|
|
79262
79626
|
trend: 0,
|
|
79263
79627
|
idle: 0,
|
|
79264
79628
|
improvements: 0
|
|
79265
79629
|
});
|
|
79266
|
-
const intervalRef =
|
|
79267
|
-
const isPageActiveRef =
|
|
79268
|
-
const lastResumeRefreshAtRef =
|
|
79269
|
-
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(() => {
|
|
79270
79634
|
Object.values(controllersRef.current).forEach((controller) => {
|
|
79271
79635
|
controller?.abort();
|
|
79272
79636
|
});
|
|
79273
79637
|
controllersRef.current = {};
|
|
79274
79638
|
}, []);
|
|
79275
|
-
|
|
79639
|
+
React143__default.useEffect(() => {
|
|
79276
79640
|
return () => {
|
|
79277
79641
|
abortAll();
|
|
79278
79642
|
};
|
|
79279
79643
|
}, [abortAll]);
|
|
79280
|
-
const getIsPageActive =
|
|
79644
|
+
const getIsPageActive = React143__default.useCallback(() => {
|
|
79281
79645
|
if (typeof document === "undefined") {
|
|
79282
79646
|
return true;
|
|
79283
79647
|
}
|
|
@@ -79285,7 +79649,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
79285
79649
|
const hasFocus = typeof document.hasFocus === "function" ? document.hasFocus() : true;
|
|
79286
79650
|
return isVisible && hasFocus;
|
|
79287
79651
|
}, []);
|
|
79288
|
-
const stopPolling =
|
|
79652
|
+
const stopPolling = React143__default.useCallback((reason) => {
|
|
79289
79653
|
if (intervalRef.current === null) {
|
|
79290
79654
|
return;
|
|
79291
79655
|
}
|
|
@@ -79293,7 +79657,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
79293
79657
|
intervalRef.current = null;
|
|
79294
79658
|
debugRefreshLog("poll stopped", { reason });
|
|
79295
79659
|
}, []);
|
|
79296
|
-
const runRefresh =
|
|
79660
|
+
const runRefresh = React143__default.useCallback(
|
|
79297
79661
|
async (section, begin, onSuccess, onError, request, reason) => {
|
|
79298
79662
|
if (!enabled || !supabase || !companyId || lineIds.length === 0) return;
|
|
79299
79663
|
const requestId = requestIdsRef.current[section] + 1;
|
|
@@ -79309,7 +79673,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
79309
79673
|
}
|
|
79310
79674
|
onSuccess(response, Date.now(), reason === "live_refresh" ? "transition" : "default");
|
|
79311
79675
|
} catch (error) {
|
|
79312
|
-
if (controller.signal.aborted || requestIdsRef.current[section] !== requestId ||
|
|
79676
|
+
if (controller.signal.aborted || requestIdsRef.current[section] !== requestId || isAbortError2(error)) {
|
|
79313
79677
|
return;
|
|
79314
79678
|
}
|
|
79315
79679
|
onError(error instanceof Error ? error.message : `Failed to refresh ${section}`);
|
|
@@ -79317,7 +79681,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
79317
79681
|
},
|
|
79318
79682
|
[companyId, enabled, lineIds.length, supabase]
|
|
79319
79683
|
);
|
|
79320
|
-
const refreshSnapshot =
|
|
79684
|
+
const refreshSnapshot = React143__default.useCallback(
|
|
79321
79685
|
async (reason) => {
|
|
79322
79686
|
await runRefresh(
|
|
79323
79687
|
"snapshot",
|
|
@@ -79349,7 +79713,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
79349
79713
|
},
|
|
79350
79714
|
[companyId, comparisonStrategy, endKey, lineIdsKey, runRefresh, scopeSignature, startKey, store, supabase, trendMode]
|
|
79351
79715
|
);
|
|
79352
|
-
const refreshTrend =
|
|
79716
|
+
const refreshTrend = React143__default.useCallback(
|
|
79353
79717
|
async (reason) => {
|
|
79354
79718
|
await runRefresh(
|
|
79355
79719
|
"trend",
|
|
@@ -79378,7 +79742,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
79378
79742
|
},
|
|
79379
79743
|
[companyId, endKey, lineIdsKey, runRefresh, scopeSignature, startKey, store, supabase, trendMode]
|
|
79380
79744
|
);
|
|
79381
|
-
const refreshIdle =
|
|
79745
|
+
const refreshIdle = React143__default.useCallback(
|
|
79382
79746
|
async (reason) => {
|
|
79383
79747
|
await runRefresh(
|
|
79384
79748
|
"idle",
|
|
@@ -79407,7 +79771,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
79407
79771
|
},
|
|
79408
79772
|
[companyId, endKey, lineIdsKey, runRefresh, scopeSignature, startKey, store, supabase, trendMode]
|
|
79409
79773
|
);
|
|
79410
|
-
const refreshImprovements =
|
|
79774
|
+
const refreshImprovements = React143__default.useCallback(
|
|
79411
79775
|
async (reason) => {
|
|
79412
79776
|
await runRefresh(
|
|
79413
79777
|
"improvements",
|
|
@@ -79437,7 +79801,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
79437
79801
|
},
|
|
79438
79802
|
[companyId, lineIds, lineIdsKey, runRefresh, scopeSignature, store, supabase]
|
|
79439
79803
|
);
|
|
79440
|
-
const refreshAll =
|
|
79804
|
+
const refreshAll = React143__default.useCallback(
|
|
79441
79805
|
async (reason) => {
|
|
79442
79806
|
await Promise.allSettled([
|
|
79443
79807
|
refreshSnapshot(reason),
|
|
@@ -79448,7 +79812,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
79448
79812
|
},
|
|
79449
79813
|
[refreshIdle, refreshImprovements, refreshSnapshot, refreshTrend]
|
|
79450
79814
|
);
|
|
79451
|
-
const startPolling =
|
|
79815
|
+
const startPolling = React143__default.useCallback((reason) => {
|
|
79452
79816
|
if (!isLiveScope || !supabase || !companyId || lineIds.length === 0) {
|
|
79453
79817
|
return;
|
|
79454
79818
|
}
|
|
@@ -79469,7 +79833,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
79469
79833
|
}, LIVE_REFRESH_INTERVAL_MS);
|
|
79470
79834
|
debugRefreshLog("poll started", { reason, intervalMs: LIVE_REFRESH_INTERVAL_MS });
|
|
79471
79835
|
}, [companyId, isLiveScope, lineIds.length, refreshAll, stopPolling, supabase]);
|
|
79472
|
-
const refreshFromResume =
|
|
79836
|
+
const refreshFromResume = React143__default.useCallback((reason) => {
|
|
79473
79837
|
const now4 = Date.now();
|
|
79474
79838
|
if (now4 - lastResumeRefreshAtRef.current < 1e3) {
|
|
79475
79839
|
debugRefreshLog("resume refresh suppressed", { reason });
|
|
@@ -79484,7 +79848,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
79484
79848
|
}
|
|
79485
79849
|
});
|
|
79486
79850
|
}, [refreshAll, startPolling, stopPolling]);
|
|
79487
|
-
|
|
79851
|
+
React143__default.useEffect(() => {
|
|
79488
79852
|
if (!enabled) {
|
|
79489
79853
|
stopPolling("disabled");
|
|
79490
79854
|
abortAll();
|
|
@@ -79499,7 +79863,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
79499
79863
|
}
|
|
79500
79864
|
void refreshAll("scope_change");
|
|
79501
79865
|
}, [abortAll, companyId, enabled, lineIds.length, refreshAll, scopeSignature, stopPolling, store, supabase]);
|
|
79502
|
-
|
|
79866
|
+
React143__default.useEffect(() => {
|
|
79503
79867
|
if (!enabled || !isLiveScope || !supabase || !companyId || lineIds.length === 0) {
|
|
79504
79868
|
isPageActiveRef.current = false;
|
|
79505
79869
|
stopPolling("live_scope_disabled");
|
|
@@ -79674,55 +80038,55 @@ var PlantHeadView = () => {
|
|
|
79674
80038
|
const { accessibleLineIds } = useUserLineAccess();
|
|
79675
80039
|
const mobileMenuContext = useMobileMenu();
|
|
79676
80040
|
useHideMobileHeader(!!mobileMenuContext);
|
|
79677
|
-
const storeRef =
|
|
80041
|
+
const storeRef = React143__default.useRef(createOperationsOverviewStore());
|
|
79678
80042
|
const store = storeRef.current;
|
|
79679
|
-
const fallbackOperationalDate =
|
|
80043
|
+
const fallbackOperationalDate = React143__default.useMemo(
|
|
79680
80044
|
() => getOperationalDate(appTimezone),
|
|
79681
80045
|
[appTimezone]
|
|
79682
80046
|
);
|
|
79683
|
-
const [dateRange, setDateRange] =
|
|
80047
|
+
const [dateRange, setDateRange] = React143__default.useState(() => ({
|
|
79684
80048
|
startKey: fallbackOperationalDate,
|
|
79685
80049
|
endKey: fallbackOperationalDate
|
|
79686
80050
|
}));
|
|
79687
|
-
const [usesThisWeekComparison, setUsesThisWeekComparison] =
|
|
79688
|
-
const [trendMode, setTrendMode] =
|
|
79689
|
-
const [selectedSupervisorId, setSelectedSupervisorId] =
|
|
79690
|
-
const [selectedLineIds, setSelectedLineIds] =
|
|
79691
|
-
const [isInitialScopeReady, setIsInitialScopeReady] =
|
|
79692
|
-
const [shiftResolutionTick, setShiftResolutionTick] =
|
|
79693
|
-
const hasAutoInitializedScopeRef =
|
|
79694
|
-
const hasUserAdjustedScopeRef =
|
|
79695
|
-
|
|
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(() => {
|
|
79696
80060
|
trackCorePageView("Operations Overview", {
|
|
79697
80061
|
dashboard_surface: "operations_overview"
|
|
79698
80062
|
});
|
|
79699
80063
|
}, []);
|
|
79700
|
-
const currentWeekRange =
|
|
80064
|
+
const currentWeekRange = React143__default.useMemo(
|
|
79701
80065
|
() => getCurrentWeekToDateRange(appTimezone),
|
|
79702
80066
|
[appTimezone]
|
|
79703
80067
|
);
|
|
79704
|
-
const currentWeekDisplayRange =
|
|
80068
|
+
const currentWeekDisplayRange = React143__default.useMemo(
|
|
79705
80069
|
() => getCurrentWeekFullRange(appTimezone),
|
|
79706
80070
|
[appTimezone]
|
|
79707
80071
|
);
|
|
79708
80072
|
const isCurrentWeekToDateRange = dateRange.startKey === currentWeekRange.startKey && dateRange.endKey === currentWeekRange.endKey;
|
|
79709
|
-
const headerDateRange =
|
|
80073
|
+
const headerDateRange = React143__default.useMemo(() => {
|
|
79710
80074
|
if (usesThisWeekComparison && isCurrentWeekToDateRange) {
|
|
79711
80075
|
return currentWeekDisplayRange;
|
|
79712
80076
|
}
|
|
79713
80077
|
return dateRange;
|
|
79714
80078
|
}, [currentWeekDisplayRange, dateRange, isCurrentWeekToDateRange, usesThisWeekComparison]);
|
|
79715
|
-
const normalizedLineIds =
|
|
80079
|
+
const normalizedLineIds = React143__default.useMemo(
|
|
79716
80080
|
() => Array.from(new Set(
|
|
79717
80081
|
(accessibleLineIds || []).filter(Boolean).filter((lineId) => lineId !== factoryViewId)
|
|
79718
80082
|
)).sort(),
|
|
79719
80083
|
[accessibleLineIds, factoryViewId]
|
|
79720
80084
|
);
|
|
79721
|
-
const lineIdsKey =
|
|
80085
|
+
const lineIdsKey = React143__default.useMemo(
|
|
79722
80086
|
() => normalizedLineIds.join(","),
|
|
79723
80087
|
[normalizedLineIds]
|
|
79724
80088
|
);
|
|
79725
|
-
const lineOptions =
|
|
80089
|
+
const lineOptions = React143__default.useMemo(
|
|
79726
80090
|
() => normalizedLineIds.map((lineId) => ({
|
|
79727
80091
|
id: lineId,
|
|
79728
80092
|
name: getLineDisplayName(entityConfig, lineId)
|
|
@@ -79734,7 +80098,7 @@ var PlantHeadView = () => {
|
|
|
79734
80098
|
companyId: entityConfig.companyId,
|
|
79735
80099
|
useBackend: true
|
|
79736
80100
|
});
|
|
79737
|
-
const supervisorOptions =
|
|
80101
|
+
const supervisorOptions = React143__default.useMemo(
|
|
79738
80102
|
() => {
|
|
79739
80103
|
const optionsById = /* @__PURE__ */ new Map();
|
|
79740
80104
|
normalizedLineIds.forEach((lineId) => {
|
|
@@ -79760,7 +80124,7 @@ var PlantHeadView = () => {
|
|
|
79760
80124
|
},
|
|
79761
80125
|
[normalizedLineIds, supervisorsByLineId]
|
|
79762
80126
|
);
|
|
79763
|
-
|
|
80127
|
+
React143__default.useEffect(() => {
|
|
79764
80128
|
if (selectedSupervisorId === "all") {
|
|
79765
80129
|
setSelectedLineIds((previous) => {
|
|
79766
80130
|
if (normalizedLineIds.length === 0) {
|
|
@@ -79786,7 +80150,7 @@ var PlantHeadView = () => {
|
|
|
79786
80150
|
const scopedSupervisorLineIds = normalizedLineIds.filter((lineId) => supervisorLineIdSet.has(lineId));
|
|
79787
80151
|
setSelectedLineIds((previous) => previous.length === scopedSupervisorLineIds.length && previous.every((lineId, index) => lineId === scopedSupervisorLineIds[index]) ? previous : scopedSupervisorLineIds);
|
|
79788
80152
|
}, [lineIdsKey, normalizedLineIds, selectedSupervisorId, supervisorOptions]);
|
|
79789
|
-
const scopedLineIds =
|
|
80153
|
+
const scopedLineIds = React143__default.useMemo(
|
|
79790
80154
|
() => selectedLineIds.length > 0 ? selectedLineIds : normalizedLineIds,
|
|
79791
80155
|
[normalizedLineIds, selectedLineIds]
|
|
79792
80156
|
);
|
|
@@ -79794,7 +80158,7 @@ var PlantHeadView = () => {
|
|
|
79794
80158
|
shiftConfigMap,
|
|
79795
80159
|
isLoading: isShiftConfigLoading
|
|
79796
80160
|
} = useMultiLineShiftConfigs(scopedLineIds, staticShiftConfig);
|
|
79797
|
-
|
|
80161
|
+
React143__default.useEffect(() => {
|
|
79798
80162
|
if (scopedLineIds.length === 0 || isShiftConfigLoading) {
|
|
79799
80163
|
return;
|
|
79800
80164
|
}
|
|
@@ -79805,11 +80169,11 @@ var PlantHeadView = () => {
|
|
|
79805
80169
|
clearInterval(intervalId);
|
|
79806
80170
|
};
|
|
79807
80171
|
}, [isShiftConfigLoading, scopedLineIds.length]);
|
|
79808
|
-
const shiftResolutionNow =
|
|
80172
|
+
const shiftResolutionNow = React143__default.useMemo(
|
|
79809
80173
|
() => /* @__PURE__ */ new Date(),
|
|
79810
80174
|
[shiftResolutionTick]
|
|
79811
80175
|
);
|
|
79812
|
-
const earliestDayShiftStartTime =
|
|
80176
|
+
const earliestDayShiftStartTime = React143__default.useMemo(() => {
|
|
79813
80177
|
const candidateStarts = [];
|
|
79814
80178
|
scopedLineIds.forEach((lineId) => {
|
|
79815
80179
|
const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
|
|
@@ -79845,11 +80209,11 @@ var PlantHeadView = () => {
|
|
|
79845
80209
|
const minutes = earliestMinutes % 60;
|
|
79846
80210
|
return `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
|
|
79847
80211
|
}, [appTimezone, scopedLineIds, shiftConfigMap, staticShiftConfig]);
|
|
79848
|
-
const resolvedOperationalToday =
|
|
80212
|
+
const resolvedOperationalToday = React143__default.useMemo(
|
|
79849
80213
|
() => getOperationalDate(appTimezone, shiftResolutionNow, earliestDayShiftStartTime),
|
|
79850
80214
|
[appTimezone, earliestDayShiftStartTime, shiftResolutionNow]
|
|
79851
80215
|
);
|
|
79852
|
-
const activeLineShiftStates =
|
|
80216
|
+
const activeLineShiftStates = React143__default.useMemo(() => {
|
|
79853
80217
|
return scopedLineIds.flatMap((lineId) => {
|
|
79854
80218
|
const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
|
|
79855
80219
|
const activeShift = getActiveShift(appTimezone, shiftConfig, shiftResolutionNow);
|
|
@@ -79876,16 +80240,16 @@ var PlantHeadView = () => {
|
|
|
79876
80240
|
}];
|
|
79877
80241
|
});
|
|
79878
80242
|
}, [appTimezone, scopedLineIds, shiftConfigMap, shiftResolutionNow, staticShiftConfig]);
|
|
79879
|
-
const hasActiveDayShiftLine =
|
|
80243
|
+
const hasActiveDayShiftLine = React143__default.useMemo(
|
|
79880
80244
|
() => activeLineShiftStates.some((shift) => shift.trendMode === "day" && shift.date === resolvedOperationalToday),
|
|
79881
80245
|
[activeLineShiftStates, resolvedOperationalToday]
|
|
79882
80246
|
);
|
|
79883
|
-
const hasActiveNightShiftLine =
|
|
80247
|
+
const hasActiveNightShiftLine = React143__default.useMemo(
|
|
79884
80248
|
() => activeLineShiftStates.some((shift) => shift.trendMode === "night" && shift.date === resolvedOperationalToday),
|
|
79885
80249
|
[activeLineShiftStates, resolvedOperationalToday]
|
|
79886
80250
|
);
|
|
79887
80251
|
const resolvedTrendMode = isInitialScopeReady ? trendMode : "all";
|
|
79888
|
-
const hourlyWindowStartTime =
|
|
80252
|
+
const hourlyWindowStartTime = React143__default.useMemo(() => {
|
|
79889
80253
|
if (scopedLineIds.length === 0) {
|
|
79890
80254
|
return null;
|
|
79891
80255
|
}
|
|
@@ -79936,12 +80300,12 @@ var PlantHeadView = () => {
|
|
|
79936
80300
|
const minutes = earliestMinutes % 60;
|
|
79937
80301
|
return `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
|
|
79938
80302
|
}, [appTimezone, resolvedTrendMode, scopedLineIds, shiftConfigMap, staticShiftConfig]);
|
|
79939
|
-
const isShiftScopeResolved =
|
|
80303
|
+
const isShiftScopeResolved = React143__default.useMemo(
|
|
79940
80304
|
() => !isShiftConfigLoading,
|
|
79941
80305
|
[isShiftConfigLoading]
|
|
79942
80306
|
);
|
|
79943
|
-
const initializedTimezoneRef =
|
|
79944
|
-
|
|
80307
|
+
const initializedTimezoneRef = React143__default.useRef(appTimezone);
|
|
80308
|
+
React143__default.useEffect(() => {
|
|
79945
80309
|
if (initializedTimezoneRef.current === appTimezone) return;
|
|
79946
80310
|
hasAutoInitializedScopeRef.current = false;
|
|
79947
80311
|
hasUserAdjustedScopeRef.current = false;
|
|
@@ -79954,7 +80318,7 @@ var PlantHeadView = () => {
|
|
|
79954
80318
|
setIsInitialScopeReady(false);
|
|
79955
80319
|
initializedTimezoneRef.current = appTimezone;
|
|
79956
80320
|
}, [appTimezone, fallbackOperationalDate]);
|
|
79957
|
-
|
|
80321
|
+
React143__default.useEffect(() => {
|
|
79958
80322
|
if (hasAutoInitializedScopeRef.current || hasUserAdjustedScopeRef.current) {
|
|
79959
80323
|
return;
|
|
79960
80324
|
}
|
|
@@ -79979,7 +80343,7 @@ var PlantHeadView = () => {
|
|
|
79979
80343
|
hasAutoInitializedScopeRef.current = true;
|
|
79980
80344
|
setIsInitialScopeReady(true);
|
|
79981
80345
|
}, [fallbackOperationalDate, isShiftScopeResolved, resolvedOperationalToday, scopedLineIds.length]);
|
|
79982
|
-
const handleDateRangeChange =
|
|
80346
|
+
const handleDateRangeChange = React143__default.useCallback((range, meta) => {
|
|
79983
80347
|
hasUserAdjustedScopeRef.current = true;
|
|
79984
80348
|
setIsInitialScopeReady(true);
|
|
79985
80349
|
trackCoreEvent("Operations Overview Date Range Changed", {
|
|
@@ -79997,12 +80361,12 @@ var PlantHeadView = () => {
|
|
|
79997
80361
|
return previous;
|
|
79998
80362
|
});
|
|
79999
80363
|
}, []);
|
|
80000
|
-
const handleTrendModeChange =
|
|
80364
|
+
const handleTrendModeChange = React143__default.useCallback((mode) => {
|
|
80001
80365
|
hasUserAdjustedScopeRef.current = true;
|
|
80002
80366
|
setIsInitialScopeReady(true);
|
|
80003
80367
|
setTrendMode(mode);
|
|
80004
80368
|
}, []);
|
|
80005
|
-
const handleSelectedLineIdsChange =
|
|
80369
|
+
const handleSelectedLineIdsChange = React143__default.useCallback((lineIds) => {
|
|
80006
80370
|
setSelectedSupervisorId("all");
|
|
80007
80371
|
if (normalizedLineIds.length === 0) {
|
|
80008
80372
|
setSelectedLineIds([]);
|
|
@@ -80013,10 +80377,10 @@ var PlantHeadView = () => {
|
|
|
80013
80377
|
const next = normalizedLineIds.filter((lineId) => selectedSet.has(lineId));
|
|
80014
80378
|
setSelectedLineIds(next.length > 0 ? next : normalizedLineIds);
|
|
80015
80379
|
}, [normalizedLineIds]);
|
|
80016
|
-
const handleSelectedSupervisorIdChange =
|
|
80380
|
+
const handleSelectedSupervisorIdChange = React143__default.useCallback((supervisorId) => {
|
|
80017
80381
|
setSelectedSupervisorId(supervisorId);
|
|
80018
80382
|
}, []);
|
|
80019
|
-
const buildLineMonthlyHistoryUrl =
|
|
80383
|
+
const buildLineMonthlyHistoryUrl = React143__default.useCallback((lineId) => {
|
|
80020
80384
|
const rangeStartDate = parseDateKeyToDate(dateRange.startKey);
|
|
80021
80385
|
const params = new URLSearchParams();
|
|
80022
80386
|
params.set("tab", "monthly_history");
|
|
@@ -80026,15 +80390,15 @@ var PlantHeadView = () => {
|
|
|
80026
80390
|
params.set("rangeEnd", dateRange.endKey);
|
|
80027
80391
|
return `/kpis/${lineId}?${params.toString()}`;
|
|
80028
80392
|
}, [dateRange.endKey, dateRange.startKey]);
|
|
80029
|
-
const handleViewAllPoorestPerformers =
|
|
80393
|
+
const handleViewAllPoorestPerformers = React143__default.useCallback(() => {
|
|
80030
80394
|
trackCoreEvent("Operations Overview View All Clicked", { section: "poorest_performers" });
|
|
80031
80395
|
navigate("/kpis?tab=leaderboard");
|
|
80032
80396
|
}, [navigate]);
|
|
80033
|
-
const handleViewAllImprovements =
|
|
80397
|
+
const handleViewAllImprovements = React143__default.useCallback(() => {
|
|
80034
80398
|
trackCoreEvent("Operations Overview View All Clicked", { section: "improvements" });
|
|
80035
80399
|
navigate("/improvement-center");
|
|
80036
80400
|
}, [navigate]);
|
|
80037
|
-
const handleOpenImprovement =
|
|
80401
|
+
const handleOpenImprovement = React143__default.useCallback((item) => {
|
|
80038
80402
|
trackCoreEvent("Operations Overview Improvement Clicked", {
|
|
80039
80403
|
issue_id: item.issueId,
|
|
80040
80404
|
issue_number: item.issueNumber,
|
|
@@ -80045,13 +80409,13 @@ var PlantHeadView = () => {
|
|
|
80045
80409
|
});
|
|
80046
80410
|
navigate(`/improvement-center?${params.toString()}`);
|
|
80047
80411
|
}, [navigate]);
|
|
80048
|
-
const comparisonStrategy =
|
|
80412
|
+
const comparisonStrategy = React143__default.useMemo(() => {
|
|
80049
80413
|
if (usesThisWeekComparison && isCurrentWeekToDateRange) {
|
|
80050
80414
|
return "previous_full_week";
|
|
80051
80415
|
}
|
|
80052
80416
|
return void 0;
|
|
80053
80417
|
}, [isCurrentWeekToDateRange, usesThisWeekComparison]);
|
|
80054
|
-
const effectiveDateRange =
|
|
80418
|
+
const effectiveDateRange = React143__default.useMemo(() => {
|
|
80055
80419
|
if (isInitialScopeReady) {
|
|
80056
80420
|
return dateRange;
|
|
80057
80421
|
}
|
|
@@ -80061,21 +80425,21 @@ var PlantHeadView = () => {
|
|
|
80061
80425
|
endKey: nextStartKey
|
|
80062
80426
|
};
|
|
80063
80427
|
}, [dateRange, fallbackOperationalDate, isInitialScopeReady, resolvedOperationalToday]);
|
|
80064
|
-
const effectiveTrendMode =
|
|
80428
|
+
const effectiveTrendMode = React143__default.useMemo(
|
|
80065
80429
|
() => resolvedTrendMode,
|
|
80066
80430
|
[resolvedTrendMode]
|
|
80067
80431
|
);
|
|
80068
|
-
const hourlyLabelStartTime =
|
|
80432
|
+
const hourlyLabelStartTime = React143__default.useMemo(() => {
|
|
80069
80433
|
if (scopedLineIds.length === 0) {
|
|
80070
80434
|
return null;
|
|
80071
80435
|
}
|
|
80072
80436
|
return hourlyWindowStartTime;
|
|
80073
80437
|
}, [hourlyWindowStartTime, scopedLineIds.length]);
|
|
80074
|
-
const isSingleDayScope =
|
|
80438
|
+
const isSingleDayScope = React143__default.useMemo(
|
|
80075
80439
|
() => effectiveDateRange.startKey === effectiveDateRange.endKey,
|
|
80076
80440
|
[effectiveDateRange.endKey, effectiveDateRange.startKey]
|
|
80077
80441
|
);
|
|
80078
|
-
const isLiveScope =
|
|
80442
|
+
const isLiveScope = React143__default.useMemo(
|
|
80079
80443
|
() => isSingleDayScope && effectiveDateRange.startKey === resolvedOperationalToday && (effectiveTrendMode === "all" || effectiveTrendMode === "day" && hasActiveDayShiftLine || effectiveTrendMode === "night" && hasActiveNightShiftLine),
|
|
80080
80444
|
[
|
|
80081
80445
|
effectiveDateRange.startKey,
|
|
@@ -80086,7 +80450,7 @@ var PlantHeadView = () => {
|
|
|
80086
80450
|
resolvedOperationalToday
|
|
80087
80451
|
]
|
|
80088
80452
|
);
|
|
80089
|
-
const handleOpenLineDetails =
|
|
80453
|
+
const handleOpenLineDetails = React143__default.useCallback((lineId, lineName) => {
|
|
80090
80454
|
trackCoreEvent("Operations Overview Line Clicked", {
|
|
80091
80455
|
line_id: lineId,
|
|
80092
80456
|
line_name: lineName,
|
|
@@ -80654,4 +81018,4 @@ var streamProxyConfig = {
|
|
|
80654
81018
|
}
|
|
80655
81019
|
};
|
|
80656
81020
|
|
|
80657
|
-
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 };
|