@optifye/dashboard-core 6.11.32 → 6.11.34
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 -3
- package/dist/index.d.mts +36 -3
- package/dist/index.d.ts +36 -3
- package/dist/index.js +3334 -2809
- package/dist/index.mjs +1269 -746
- 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
|
}
|
|
@@ -4355,6 +4545,49 @@ var dashboardService = {
|
|
|
4355
4545
|
throw err;
|
|
4356
4546
|
}
|
|
4357
4547
|
},
|
|
4548
|
+
async getAssemblyMonthlyPoorestPerformers(lineIdInput, month, year, options) {
|
|
4549
|
+
const supabase = _getSupabaseInstance();
|
|
4550
|
+
const config = _getDashboardConfigInstance();
|
|
4551
|
+
const entityConfig = config.entityConfig ?? DEFAULT_ENTITY_CONFIG;
|
|
4552
|
+
const configuredLineIds = getConfiguredLineIds(entityConfig);
|
|
4553
|
+
const factoryViewId = entityConfig.factoryViewId ?? "factory";
|
|
4554
|
+
const startDate = options?.startDate ? new Date(options.startDate) : new Date(year, month, 1);
|
|
4555
|
+
const endDate = options?.endDate ? new Date(options.endDate) : new Date(year, month + 1, 0);
|
|
4556
|
+
const formatDate2 = (date) => {
|
|
4557
|
+
const year2 = date.getFullYear();
|
|
4558
|
+
const month2 = String(date.getMonth() + 1).padStart(2, "0");
|
|
4559
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
4560
|
+
return `${year2}-${month2}-${day}`;
|
|
4561
|
+
};
|
|
4562
|
+
const formattedStartDate = formatDate2(startDate);
|
|
4563
|
+
const formattedEndDate = formatDate2(endDate);
|
|
4564
|
+
const params = new URLSearchParams({
|
|
4565
|
+
start_date: formattedStartDate,
|
|
4566
|
+
end_date: formattedEndDate,
|
|
4567
|
+
company_id: entityConfig.companyId || ""
|
|
4568
|
+
});
|
|
4569
|
+
if (lineIdInput === factoryViewId) {
|
|
4570
|
+
if (!isValidFactoryViewConfiguration(entityConfig)) {
|
|
4571
|
+
throw new Error("Factory View requires at least one configured line for monthly data.");
|
|
4572
|
+
}
|
|
4573
|
+
params.set("line_ids", configuredLineIds.join(","));
|
|
4574
|
+
} else {
|
|
4575
|
+
params.set("line_id", lineIdInput);
|
|
4576
|
+
}
|
|
4577
|
+
if (options?.shiftIds && options.shiftIds.length > 0) {
|
|
4578
|
+
params.set("shift_ids", options.shiftIds.join(","));
|
|
4579
|
+
}
|
|
4580
|
+
try {
|
|
4581
|
+
const response = await fetchBackendJson(
|
|
4582
|
+
supabase,
|
|
4583
|
+
`/api/dashboard/line-monthly-assembly-poorest-performers?${params.toString()}`
|
|
4584
|
+
);
|
|
4585
|
+
return response || {};
|
|
4586
|
+
} catch (err) {
|
|
4587
|
+
console.error("Exception in getAssemblyMonthlyPoorestPerformers:", err);
|
|
4588
|
+
throw err;
|
|
4589
|
+
}
|
|
4590
|
+
},
|
|
4358
4591
|
async getUnderperformingWorkspaces(lineIdInput, monthInput, yearInput, shiftIds, startDate, endDate) {
|
|
4359
4592
|
_getSupabaseInstance();
|
|
4360
4593
|
const config = _getDashboardConfigInstance();
|
|
@@ -4919,6 +5152,13 @@ var workspaceService = {
|
|
|
4919
5152
|
return displayNamesMap;
|
|
4920
5153
|
} catch (error) {
|
|
4921
5154
|
console.error("Error fetching workspace display names:", error);
|
|
5155
|
+
captureSentryException(error, {
|
|
5156
|
+
surface: "workspace_display_names",
|
|
5157
|
+
route: "/api/workspaces/display-names",
|
|
5158
|
+
company_id: companyId || null,
|
|
5159
|
+
line_id: lineId || null,
|
|
5160
|
+
pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
|
|
5161
|
+
});
|
|
4922
5162
|
throw error;
|
|
4923
5163
|
}
|
|
4924
5164
|
},
|
|
@@ -6573,95 +6813,6 @@ function clearAllRateLimits2() {
|
|
|
6573
6813
|
rateLimitMap2.clear();
|
|
6574
6814
|
}
|
|
6575
6815
|
|
|
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
6816
|
// src/lib/services/mixpanelService.ts
|
|
6666
6817
|
var ROOT_DASHBOARD_EVENT_NAMES = {
|
|
6667
6818
|
operations_overview: "Operations Overview Page Clicked",
|
|
@@ -8716,6 +8867,12 @@ var LinesService = class {
|
|
|
8716
8867
|
}));
|
|
8717
8868
|
} catch (error) {
|
|
8718
8869
|
console.error("Error fetching lines:", error);
|
|
8870
|
+
captureHandledFrontendException(error, {
|
|
8871
|
+
surface: "lines_service",
|
|
8872
|
+
operation: "getLinesByCompanyId",
|
|
8873
|
+
company_id: companyId,
|
|
8874
|
+
pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
|
|
8875
|
+
});
|
|
8719
8876
|
throw new Error(`Failed to fetch lines: ${error.message}`);
|
|
8720
8877
|
}
|
|
8721
8878
|
}
|
|
@@ -8765,6 +8922,11 @@ var LinesService = class {
|
|
|
8765
8922
|
}));
|
|
8766
8923
|
} catch (error) {
|
|
8767
8924
|
console.error("Error fetching all lines:", error);
|
|
8925
|
+
captureHandledFrontendException(error, {
|
|
8926
|
+
surface: "lines_service",
|
|
8927
|
+
operation: "getAllLines",
|
|
8928
|
+
pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
|
|
8929
|
+
});
|
|
8768
8930
|
throw new Error(`Failed to fetch lines: ${error.message}`);
|
|
8769
8931
|
}
|
|
8770
8932
|
}
|
|
@@ -8823,6 +8985,12 @@ var LinesService = class {
|
|
|
8823
8985
|
};
|
|
8824
8986
|
} catch (error) {
|
|
8825
8987
|
console.error("Error fetching line:", error);
|
|
8988
|
+
captureHandledFrontendException(error, {
|
|
8989
|
+
surface: "lines_service",
|
|
8990
|
+
operation: "getLineById",
|
|
8991
|
+
line_id: lineId,
|
|
8992
|
+
pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
|
|
8993
|
+
});
|
|
8826
8994
|
throw new Error(`Failed to fetch line: ${error.message}`);
|
|
8827
8995
|
}
|
|
8828
8996
|
}
|
|
@@ -10541,6 +10709,17 @@ var AuthProvider = ({ children }) => {
|
|
|
10541
10709
|
const isRecoveringSession = authStatus === "recovering";
|
|
10542
10710
|
useEffect(() => {
|
|
10543
10711
|
currentUserRef.current = user;
|
|
10712
|
+
if (user) {
|
|
10713
|
+
setSentryUserContext({
|
|
10714
|
+
id: user.id,
|
|
10715
|
+
email: user.email,
|
|
10716
|
+
role: user.role,
|
|
10717
|
+
role_level: user.role_level,
|
|
10718
|
+
company_id: user.company_id
|
|
10719
|
+
});
|
|
10720
|
+
return;
|
|
10721
|
+
}
|
|
10722
|
+
clearSentryContext();
|
|
10544
10723
|
}, [user]);
|
|
10545
10724
|
const setTrackedSession = useCallback((nextSession) => {
|
|
10546
10725
|
latestSessionRef.current = nextSession;
|
|
@@ -10701,6 +10880,17 @@ var AuthProvider = ({ children }) => {
|
|
|
10701
10880
|
}
|
|
10702
10881
|
if (isRetryableSessionError(err)) {
|
|
10703
10882
|
console.warn("[AuthContext] Retryable session hydration error, entering recovery mode");
|
|
10883
|
+
if (recoveryAttemptRef.current === 0) {
|
|
10884
|
+
captureSentryException(err, {
|
|
10885
|
+
surface: "auth_session_hydration",
|
|
10886
|
+
phase: isReauth ? "reauth" : "initial",
|
|
10887
|
+
retryable: true,
|
|
10888
|
+
auth_status: authStatus,
|
|
10889
|
+
pathname: typeof window !== "undefined" ? window.location.pathname : "unknown",
|
|
10890
|
+
visibility_state: typeof document !== "undefined" ? document.visibilityState : "unknown",
|
|
10891
|
+
online_state: typeof navigator !== "undefined" ? navigator.onLine : "unknown"
|
|
10892
|
+
});
|
|
10893
|
+
}
|
|
10704
10894
|
enterRecoveryMode(supabaseSession);
|
|
10705
10895
|
return;
|
|
10706
10896
|
}
|
|
@@ -10720,6 +10910,13 @@ var AuthProvider = ({ children }) => {
|
|
|
10720
10910
|
}
|
|
10721
10911
|
resetRecoveryState();
|
|
10722
10912
|
clearAuthSnapshot();
|
|
10913
|
+
captureSentryException(fatalError, {
|
|
10914
|
+
surface: "auth_session_hydration",
|
|
10915
|
+
phase: isReauth ? "reauth" : "initial",
|
|
10916
|
+
retryable: false,
|
|
10917
|
+
auth_status: authStatus,
|
|
10918
|
+
pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
|
|
10919
|
+
});
|
|
10723
10920
|
setError(fatalError);
|
|
10724
10921
|
setAuthStatus("failed");
|
|
10725
10922
|
setUser(null);
|
|
@@ -11414,7 +11611,7 @@ var useMobileMenu = () => {
|
|
|
11414
11611
|
};
|
|
11415
11612
|
var useHideMobileHeader = (shouldHide = true) => {
|
|
11416
11613
|
const context = useMobileMenu();
|
|
11417
|
-
|
|
11614
|
+
React143__default.useEffect(() => {
|
|
11418
11615
|
if (context && shouldHide) {
|
|
11419
11616
|
context.setHideMobileHeader(true);
|
|
11420
11617
|
return () => {
|
|
@@ -13256,7 +13453,13 @@ var parseEfficiencyLegend = (legend) => {
|
|
|
13256
13453
|
critical_threshold: coerce(legend.critical_threshold, DEFAULT_EFFICIENCY_LEGEND.critical_threshold)
|
|
13257
13454
|
};
|
|
13258
13455
|
};
|
|
13259
|
-
var useDashboardMetrics = ({
|
|
13456
|
+
var useDashboardMetrics = ({
|
|
13457
|
+
onLineMetricsUpdate,
|
|
13458
|
+
lineId,
|
|
13459
|
+
lineIds,
|
|
13460
|
+
userAccessibleLineIds,
|
|
13461
|
+
enabled = true
|
|
13462
|
+
}) => {
|
|
13260
13463
|
const { supabaseUrl, supabaseKey } = useDashboardConfig();
|
|
13261
13464
|
const entityConfig = useEntityConfig();
|
|
13262
13465
|
const databaseConfig = useDatabaseConfig();
|
|
@@ -13371,7 +13574,7 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, lineIds, userAccessibl
|
|
|
13371
13574
|
isTimezoneLoading,
|
|
13372
13575
|
companySpecificMetricsTable
|
|
13373
13576
|
});
|
|
13374
|
-
if (!currentLineIdToUse || !supabase || shiftLoading || isTimezoneLoading || companySpecificMetricsTable.includes("unknown_company")) {
|
|
13577
|
+
if (!currentLineIdToUse || !supabase || !enabled || shiftLoading || isTimezoneLoading || companySpecificMetricsTable.includes("unknown_company")) {
|
|
13375
13578
|
updateQueueRef.current = false;
|
|
13376
13579
|
if (!metrics2?.workspaceMetrics?.length && !metrics2?.lineMetrics?.length && !shiftLoading) setIsLoading(false);
|
|
13377
13580
|
if (companySpecificMetricsTable.includes("unknown_company") && !error) {
|
|
@@ -13415,19 +13618,6 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, lineIds, userAccessibl
|
|
|
13415
13618
|
abortControllerRef.current = abortController;
|
|
13416
13619
|
inFlightFetchKeyRef.current = fetchKey;
|
|
13417
13620
|
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
13621
|
if (targetLineIds.length === 0) {
|
|
13432
13622
|
logDebug("[useDashboardMetrics] Skipping fetch: no target line IDs after scope filtering");
|
|
13433
13623
|
setMetrics({
|
|
@@ -13446,6 +13636,10 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, lineIds, userAccessibl
|
|
|
13446
13636
|
let idleTimeVlmByLine = {};
|
|
13447
13637
|
let efficiencyLegend;
|
|
13448
13638
|
const forceParam = force ? "&force_refresh=true" : "";
|
|
13639
|
+
const buildMetricsEndpoint = (params) => {
|
|
13640
|
+
const lineIdsParam = isFactory ? `line_ids=${params.groupLineIds.join(",")}` : `line_id=${params.groupLineIds[0]}`;
|
|
13641
|
+
return `/api/dashboard/metrics?${lineIdsParam}&date=${params.date}&shift_id=${params.shiftId}&company_id=${companyId}${forceParam}`;
|
|
13642
|
+
};
|
|
13449
13643
|
if (usesShiftGroups) {
|
|
13450
13644
|
logDebug("[useDashboardMetrics] Factory view shift groups fetch:", {
|
|
13451
13645
|
groupCount: shiftGroups.length,
|
|
@@ -13462,32 +13656,23 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, lineIds, userAccessibl
|
|
|
13462
13656
|
if (groupLineIds.length === 0) {
|
|
13463
13657
|
return null;
|
|
13464
13658
|
}
|
|
13465
|
-
const
|
|
13466
|
-
|
|
13659
|
+
const endpoint = buildMetricsEndpoint({
|
|
13660
|
+
groupLineIds,
|
|
13661
|
+
date: group.date,
|
|
13662
|
+
shiftId: group.shiftId
|
|
13663
|
+
});
|
|
13467
13664
|
logDebug(`[useDashboardMetrics] \u{1F4CA} Fetching for shift ${group.shiftId} (${group.shiftName}):`, {
|
|
13468
13665
|
lineIds: groupLineIds,
|
|
13469
|
-
date: group.date
|
|
13666
|
+
date: group.date,
|
|
13667
|
+
endpoint
|
|
13470
13668
|
});
|
|
13471
|
-
|
|
13669
|
+
return await fetchBackendJson(supabase, endpoint, {
|
|
13472
13670
|
method: "GET",
|
|
13473
|
-
|
|
13474
|
-
|
|
13475
|
-
|
|
13476
|
-
},
|
|
13477
|
-
signal: abortController.signal
|
|
13671
|
+
signal: abortController.signal,
|
|
13672
|
+
timeoutMs: 1e4,
|
|
13673
|
+
retries: 1,
|
|
13674
|
+
dedupeKey: `dashboard-metrics::${requestLineId}::${group.date}::${group.shiftId}::${groupLineIds.join(",")}::${force ? "force" : "cached"}`
|
|
13478
13675
|
});
|
|
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
13676
|
});
|
|
13492
13677
|
const results = (await Promise.all(metricsPromises)).filter((result) => !!result);
|
|
13493
13678
|
hasFlowBuffers = results.some((result) => result?.metadata?.has_flow_buffers);
|
|
@@ -13522,39 +13707,23 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, lineIds, userAccessibl
|
|
|
13522
13707
|
if (!currentShiftDetails) {
|
|
13523
13708
|
throw new Error("Shift details not available for metrics fetch.");
|
|
13524
13709
|
}
|
|
13525
|
-
const
|
|
13526
|
-
|
|
13527
|
-
|
|
13710
|
+
const endpoint = buildMetricsEndpoint({
|
|
13711
|
+
groupLineIds: targetLineIds,
|
|
13712
|
+
date: currentShiftDetails.date,
|
|
13713
|
+
shiftId: currentShiftDetails.shiftId
|
|
13714
|
+
});
|
|
13528
13715
|
logDebug("[useDashboardMetrics] Calling backend API:", {
|
|
13529
|
-
|
|
13530
|
-
apiUrl,
|
|
13531
|
-
lineIdsParam,
|
|
13532
|
-
operationalDate,
|
|
13716
|
+
endpoint,
|
|
13533
13717
|
shiftId: currentShiftDetails.shiftId,
|
|
13534
13718
|
companyId
|
|
13535
13719
|
});
|
|
13536
|
-
const
|
|
13720
|
+
const backendData = await fetchBackendJson(supabase, endpoint, {
|
|
13537
13721
|
method: "GET",
|
|
13538
|
-
|
|
13539
|
-
|
|
13540
|
-
|
|
13541
|
-
},
|
|
13542
|
-
signal: abortController.signal
|
|
13722
|
+
signal: abortController.signal,
|
|
13723
|
+
timeoutMs: 1e4,
|
|
13724
|
+
retries: 1,
|
|
13725
|
+
dedupeKey: `dashboard-metrics::${requestLineId}::${currentShiftDetails.date}::${currentShiftDetails.shiftId}::${targetLineIds.join(",")}::${force ? "force" : "cached"}`
|
|
13543
13726
|
});
|
|
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
13727
|
logDebug("[useDashboardMetrics] Backend response:", {
|
|
13559
13728
|
workspaceCount: backendData.workspace_metrics?.length || 0,
|
|
13560
13729
|
lineCount: backendData.line_metrics?.length || 0
|
|
@@ -13609,6 +13778,7 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, lineIds, userAccessibl
|
|
|
13609
13778
|
date: item.date,
|
|
13610
13779
|
workspace_uuid: item.workspace_id,
|
|
13611
13780
|
workspace_name: item.workspace_name,
|
|
13781
|
+
displayName: item.workspace_display_name || item.display_name || void 0,
|
|
13612
13782
|
action_count: item.total_output || 0,
|
|
13613
13783
|
pph: item.avg_pph || 0,
|
|
13614
13784
|
performance_score: item.performance_score || 0,
|
|
@@ -13672,6 +13842,17 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, lineIds, userAccessibl
|
|
|
13672
13842
|
return;
|
|
13673
13843
|
}
|
|
13674
13844
|
console.error("[useDashboardMetrics] Error fetching dashboard metrics:", err);
|
|
13845
|
+
captureSentryException(err, {
|
|
13846
|
+
surface: "home_live_monitor_metrics",
|
|
13847
|
+
route: "/api/dashboard/metrics",
|
|
13848
|
+
line_id: requestLineId,
|
|
13849
|
+
selected_line_ids: targetLineIds,
|
|
13850
|
+
is_factory_view: isFactory,
|
|
13851
|
+
reason: options.reason || "unknown",
|
|
13852
|
+
auth_deferred: !enabled,
|
|
13853
|
+
visibility_state: typeof document !== "undefined" ? document.visibilityState : "unknown",
|
|
13854
|
+
online_state: typeof navigator !== "undefined" ? navigator.onLine : "unknown"
|
|
13855
|
+
});
|
|
13675
13856
|
setError({ message: err.message, code: err.code || "FETCH_ERROR" });
|
|
13676
13857
|
} finally {
|
|
13677
13858
|
if (requestId === activeRequestIdRef.current) {
|
|
@@ -13685,6 +13866,7 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, lineIds, userAccessibl
|
|
|
13685
13866
|
}, [
|
|
13686
13867
|
supabase,
|
|
13687
13868
|
companySpecificMetricsTable,
|
|
13869
|
+
enabled,
|
|
13688
13870
|
companyId,
|
|
13689
13871
|
factoryViewId,
|
|
13690
13872
|
defaultTimezone,
|
|
@@ -13721,24 +13903,24 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, lineIds, userAccessibl
|
|
|
13721
13903
|
logDebug("[useDashboardMetrics] queueUpdate triggered from realtime");
|
|
13722
13904
|
updateQueueRef.current = true;
|
|
13723
13905
|
fetchAllMetricsRef.current({ force: true, reason: "subscription" });
|
|
13724
|
-
}, [supabase]);
|
|
13906
|
+
}, [supabase, enabled]);
|
|
13725
13907
|
useEffect(() => {
|
|
13726
|
-
if (lineId && supabase && !shiftLoading && !isTimezoneLoading) {
|
|
13908
|
+
if (enabled && lineId && supabase && !shiftLoading && !isTimezoneLoading) {
|
|
13727
13909
|
fetchAllMetrics({ reason: "line-change" });
|
|
13728
13910
|
}
|
|
13729
|
-
}, [lineId, supabase, fetchAllMetrics, shiftLoading, isTimezoneLoading]);
|
|
13911
|
+
}, [enabled, lineId, supabase, fetchAllMetrics, shiftLoading, isTimezoneLoading]);
|
|
13730
13912
|
useEffect(() => {
|
|
13731
|
-
if (isFactoryView || !operationalShiftKey) return;
|
|
13913
|
+
if (!enabled || isFactoryView || !operationalShiftKey) return;
|
|
13732
13914
|
if (!supabase || shiftLoading || isTimezoneLoading) return;
|
|
13733
13915
|
fetchAllMetrics({ force: true, reason: "shift-change" });
|
|
13734
|
-
}, [isFactoryView, operationalShiftKey, supabase, shiftLoading, isTimezoneLoading, fetchAllMetrics]);
|
|
13916
|
+
}, [enabled, isFactoryView, operationalShiftKey, supabase, shiftLoading, isTimezoneLoading, fetchAllMetrics]);
|
|
13735
13917
|
useEffect(() => {
|
|
13736
|
-
if (!isFactoryView || !shiftGroupsKey) return;
|
|
13918
|
+
if (!enabled || !isFactoryView || !shiftGroupsKey) return;
|
|
13737
13919
|
if (!supabase || shiftLoading || isTimezoneLoading) return;
|
|
13738
13920
|
fetchAllMetrics({ force: true, reason: "shift-change" });
|
|
13739
|
-
}, [isFactoryView, shiftGroupsKey, supabase, shiftLoading, isTimezoneLoading, fetchAllMetrics]);
|
|
13921
|
+
}, [enabled, isFactoryView, shiftGroupsKey, supabase, shiftLoading, isTimezoneLoading, fetchAllMetrics]);
|
|
13740
13922
|
useEffect(() => {
|
|
13741
|
-
if (!lineId || !supabase || shiftLoading || isTimezoneLoading) {
|
|
13923
|
+
if (!enabled || !lineId || !supabase || shiftLoading || isTimezoneLoading) {
|
|
13742
13924
|
return;
|
|
13743
13925
|
}
|
|
13744
13926
|
let intervalId = null;
|
|
@@ -13764,15 +13946,16 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, lineIds, userAccessibl
|
|
|
13764
13946
|
window.clearInterval(intervalId);
|
|
13765
13947
|
}
|
|
13766
13948
|
};
|
|
13767
|
-
}, [lineId, supabase, shiftLoading, isTimezoneLoading]);
|
|
13949
|
+
}, [enabled, lineId, supabase, shiftLoading, isTimezoneLoading]);
|
|
13768
13950
|
const subscriptionKey = useMemo(() => {
|
|
13769
|
-
if (!supabase || !entityConfig?.companyId) return null;
|
|
13951
|
+
if (!enabled || !supabase || !entityConfig?.companyId) return null;
|
|
13770
13952
|
if (shiftLoading || isTimezoneLoading) return null;
|
|
13771
13953
|
const isFactory = lineId === (entityConfig.factoryViewId || "factory");
|
|
13772
13954
|
if (isFactory && shiftGroups.length === 0) return null;
|
|
13773
13955
|
const shiftGroupsKeyPart = isFactory ? shiftGroups.map((g) => `${g.date}-${g.shiftId}-${g.lineIds.join("_")}`).join("|") : operationalShiftKey;
|
|
13774
13956
|
return `${lineId}|${entityConfig.companyId}|${shiftGroupsKeyPart}`;
|
|
13775
13957
|
}, [
|
|
13958
|
+
enabled,
|
|
13776
13959
|
supabase,
|
|
13777
13960
|
entityConfig?.companyId,
|
|
13778
13961
|
entityConfig?.factoryViewId,
|
|
@@ -14098,9 +14281,14 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, lineIds, userAccessibl
|
|
|
14098
14281
|
lineMetrics: safeMetrics?.lineMetrics || [],
|
|
14099
14282
|
efficiencyLegend: safeMetrics?.efficiencyLegend || DEFAULT_EFFICIENCY_LEGEND,
|
|
14100
14283
|
metadata: safeMetrics?.metadata,
|
|
14101
|
-
isLoading: isLoading || !isMetricsForActiveLine,
|
|
14284
|
+
isLoading: enabled ? isLoading || !isMetricsForActiveLine : false,
|
|
14102
14285
|
error,
|
|
14103
|
-
refetch: () =>
|
|
14286
|
+
refetch: () => {
|
|
14287
|
+
if (!enabled) {
|
|
14288
|
+
return;
|
|
14289
|
+
}
|
|
14290
|
+
fetchAllMetrics({ force: true, reason: "manual" });
|
|
14291
|
+
}
|
|
14104
14292
|
};
|
|
14105
14293
|
};
|
|
14106
14294
|
var useLineKPIs = ({ lineId, enabled }) => {
|
|
@@ -16540,6 +16728,7 @@ var runtimeWorkspaceDisplayNames = {};
|
|
|
16540
16728
|
var isInitialized = false;
|
|
16541
16729
|
var isInitializing = false;
|
|
16542
16730
|
var initializedWithLineIds = [];
|
|
16731
|
+
var missingLineContextWarnings = /* @__PURE__ */ new Set();
|
|
16543
16732
|
var initializationPromise = null;
|
|
16544
16733
|
var workspaceDisplayNamesListeners = /* @__PURE__ */ new Set();
|
|
16545
16734
|
var notifyWorkspaceDisplayNamesListeners = (changedLineId) => {
|
|
@@ -16709,6 +16898,9 @@ var forceRefreshWorkspaceDisplayNames = async (lineId) => {
|
|
|
16709
16898
|
};
|
|
16710
16899
|
console.log("\u{1F504} Module loaded, will initialize lazily when first function is called");
|
|
16711
16900
|
var getWorkspaceDisplayName = (workspaceId, lineId) => {
|
|
16901
|
+
if (!workspaceId) {
|
|
16902
|
+
return workspaceId;
|
|
16903
|
+
}
|
|
16712
16904
|
if (!isInitialized && !isInitializing) {
|
|
16713
16905
|
console.log(`\u{1F504} [DEBUG] getWorkspaceDisplayName(${workspaceId}, lineId: ${lineId}) - Not initialized, triggering lazy init...`);
|
|
16714
16906
|
} else if (isInitializing) {
|
|
@@ -16740,7 +16932,11 @@ var getWorkspaceDisplayName = (workspaceId, lineId) => {
|
|
|
16740
16932
|
for (const cachedLineId of Object.keys(runtimeWorkspaceDisplayNames)) {
|
|
16741
16933
|
if (runtimeWorkspaceDisplayNames[cachedLineId][workspaceId]) {
|
|
16742
16934
|
displayName = runtimeWorkspaceDisplayNames[cachedLineId][workspaceId];
|
|
16743
|
-
|
|
16935
|
+
const warningKey = `${workspaceId}:${cachedLineId}:full`;
|
|
16936
|
+
if (!missingLineContextWarnings.has(warningKey)) {
|
|
16937
|
+
missingLineContextWarnings.add(warningKey);
|
|
16938
|
+
console.warn(`\u26A0\uFE0F No lineId provided for ${workspaceId}, found in line ${cachedLineId}`);
|
|
16939
|
+
}
|
|
16744
16940
|
break;
|
|
16745
16941
|
}
|
|
16746
16942
|
}
|
|
@@ -16755,6 +16951,9 @@ var getWorkspaceDisplayName = (workspaceId, lineId) => {
|
|
|
16755
16951
|
}
|
|
16756
16952
|
};
|
|
16757
16953
|
var getShortWorkspaceDisplayName = (workspaceId, lineId) => {
|
|
16954
|
+
if (!workspaceId) {
|
|
16955
|
+
return workspaceId;
|
|
16956
|
+
}
|
|
16758
16957
|
if (!isInitialized && !isInitializing) {
|
|
16759
16958
|
console.log("\u{1F504} Lazy initialization triggered by getShortWorkspaceDisplayName with lineId:", lineId);
|
|
16760
16959
|
initializeWorkspaceDisplayNames(lineId).catch((error) => {
|
|
@@ -16781,7 +16980,11 @@ var getShortWorkspaceDisplayName = (workspaceId, lineId) => {
|
|
|
16781
16980
|
for (const cachedLineId of Object.keys(runtimeWorkspaceDisplayNames)) {
|
|
16782
16981
|
if (runtimeWorkspaceDisplayNames[cachedLineId][workspaceId]) {
|
|
16783
16982
|
displayName = runtimeWorkspaceDisplayNames[cachedLineId][workspaceId];
|
|
16784
|
-
|
|
16983
|
+
const warningKey = `${workspaceId}:${cachedLineId}:short`;
|
|
16984
|
+
if (!missingLineContextWarnings.has(warningKey)) {
|
|
16985
|
+
missingLineContextWarnings.add(warningKey);
|
|
16986
|
+
console.warn(`\u26A0\uFE0F No lineId provided for ${workspaceId}, found in line ${cachedLineId}`);
|
|
16987
|
+
}
|
|
16785
16988
|
break;
|
|
16786
16989
|
}
|
|
16787
16990
|
}
|
|
@@ -17653,7 +17856,6 @@ var usePrefetchClipCounts = ({
|
|
|
17653
17856
|
subscriberId
|
|
17654
17857
|
}) => {
|
|
17655
17858
|
const [status] = useState("idle" /* IDLE */);
|
|
17656
|
-
console.log("[usePrefetchClipCounts] DISABLED - Returning empty state");
|
|
17657
17859
|
return {
|
|
17658
17860
|
status,
|
|
17659
17861
|
data: null,
|
|
@@ -17662,7 +17864,6 @@ var usePrefetchClipCounts = ({
|
|
|
17662
17864
|
isFullyIndexed: false,
|
|
17663
17865
|
isLoading: false,
|
|
17664
17866
|
prefetchClipCounts: async () => {
|
|
17665
|
-
console.log("[usePrefetchClipCounts] DISABLED - Not prefetching");
|
|
17666
17867
|
return null;
|
|
17667
17868
|
},
|
|
17668
17869
|
cacheKey: `disabled:${workspaceId}:${date}:${shift}`
|
|
@@ -20256,11 +20457,21 @@ var apiUtils = {
|
|
|
20256
20457
|
const token = sessionResponse.data.session?.access_token;
|
|
20257
20458
|
if (!token) {
|
|
20258
20459
|
console.error("API Util: No authentication token available.");
|
|
20460
|
+
captureHandledFrontendException(new Error("Authentication required."), {
|
|
20461
|
+
surface: "api_utils",
|
|
20462
|
+
endpoint: relativeEndpoint,
|
|
20463
|
+
reason: "missing_auth_token"
|
|
20464
|
+
});
|
|
20259
20465
|
throw new Error("Authentication required.");
|
|
20260
20466
|
}
|
|
20261
20467
|
const baseUrl = config.apiBaseUrl;
|
|
20262
20468
|
if (!baseUrl) {
|
|
20263
20469
|
console.error("API Util: apiBaseUrl is not configured.");
|
|
20470
|
+
captureHandledFrontendException(new Error("API base URL is not configured."), {
|
|
20471
|
+
surface: "api_utils",
|
|
20472
|
+
endpoint: relativeEndpoint,
|
|
20473
|
+
reason: "missing_api_base_url"
|
|
20474
|
+
});
|
|
20264
20475
|
throw new Error("API base URL is not configured.");
|
|
20265
20476
|
}
|
|
20266
20477
|
const endpoint = `${baseUrl.replace(/\/$/, "")}/${relativeEndpoint.replace(/^\//, "")}`;
|
|
@@ -20289,6 +20500,12 @@ var apiUtils = {
|
|
|
20289
20500
|
return await response.json();
|
|
20290
20501
|
} catch (error) {
|
|
20291
20502
|
console.error(`Network or fetch error calling ${endpoint}:`, error);
|
|
20503
|
+
captureHandledFrontendException(error, {
|
|
20504
|
+
surface: "api_utils",
|
|
20505
|
+
endpoint,
|
|
20506
|
+
method: options.method || "GET",
|
|
20507
|
+
pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
|
|
20508
|
+
});
|
|
20292
20509
|
if (error instanceof Error) {
|
|
20293
20510
|
throw error;
|
|
20294
20511
|
} else {
|
|
@@ -23472,7 +23689,7 @@ var MotionConfigContext = createContext({
|
|
|
23472
23689
|
});
|
|
23473
23690
|
|
|
23474
23691
|
// ../../node_modules/framer-motion/dist/es/components/AnimatePresence/PopChild.mjs
|
|
23475
|
-
var PopChildMeasure = class extends
|
|
23692
|
+
var PopChildMeasure = class extends React143.Component {
|
|
23476
23693
|
getSnapshotBeforeUpdate(prevProps) {
|
|
23477
23694
|
const element = this.props.childRef.current;
|
|
23478
23695
|
if (element && prevProps.isPresent && !this.props.isPresent) {
|
|
@@ -23527,7 +23744,7 @@ function PopChild({ children, isPresent }) {
|
|
|
23527
23744
|
document.head.removeChild(style);
|
|
23528
23745
|
};
|
|
23529
23746
|
}, [isPresent]);
|
|
23530
|
-
return jsx(PopChildMeasure, { isPresent, childRef: ref, sizeRef: size, children:
|
|
23747
|
+
return jsx(PopChildMeasure, { isPresent, childRef: ref, sizeRef: size, children: React143.cloneElement(children, { ref }) });
|
|
23531
23748
|
}
|
|
23532
23749
|
|
|
23533
23750
|
// ../../node_modules/framer-motion/dist/es/components/AnimatePresence/PresenceChild.mjs
|
|
@@ -23564,7 +23781,7 @@ var PresenceChild = ({ children, initial, isPresent, onExitComplete, custom, pre
|
|
|
23564
23781
|
useMemo(() => {
|
|
23565
23782
|
presenceChildren.forEach((_, key) => presenceChildren.set(key, false));
|
|
23566
23783
|
}, [isPresent]);
|
|
23567
|
-
|
|
23784
|
+
React143.useEffect(() => {
|
|
23568
23785
|
!isPresent && !presenceChildren.size && onExitComplete && onExitComplete();
|
|
23569
23786
|
}, [isPresent]);
|
|
23570
23787
|
if (mode === "popLayout") {
|
|
@@ -31349,7 +31566,7 @@ var withAuth = (WrappedComponent2, options) => {
|
|
|
31349
31566
|
requireAuth: true,
|
|
31350
31567
|
...options
|
|
31351
31568
|
};
|
|
31352
|
-
const WithAuthComponent =
|
|
31569
|
+
const WithAuthComponent = React143.memo(function WithAuthComponent2(props) {
|
|
31353
31570
|
const {
|
|
31354
31571
|
session,
|
|
31355
31572
|
user,
|
|
@@ -31360,9 +31577,9 @@ var withAuth = (WrappedComponent2, options) => {
|
|
|
31360
31577
|
retrySessionHydration
|
|
31361
31578
|
} = useAuth();
|
|
31362
31579
|
const router = useRouter();
|
|
31363
|
-
const [localLoading, setLocalLoading] =
|
|
31364
|
-
const [loadingTimeoutReached, setLoadingTimeoutReached] =
|
|
31365
|
-
|
|
31580
|
+
const [localLoading, setLocalLoading] = React143.useState(loading);
|
|
31581
|
+
const [loadingTimeoutReached, setLoadingTimeoutReached] = React143.useState(false);
|
|
31582
|
+
React143.useEffect(() => {
|
|
31366
31583
|
if (process.env.NODE_ENV === "development" && process.env.DEBUG_AUTH === "true") {
|
|
31367
31584
|
console.log("withAuth state:", {
|
|
31368
31585
|
loading,
|
|
@@ -31374,7 +31591,7 @@ var withAuth = (WrappedComponent2, options) => {
|
|
|
31374
31591
|
});
|
|
31375
31592
|
}
|
|
31376
31593
|
}, [authStatus, error, loading, session, user]);
|
|
31377
|
-
const handleLoadingTimeout =
|
|
31594
|
+
const handleLoadingTimeout = React143.useCallback(() => {
|
|
31378
31595
|
console.warn("[withAuth] Loading timeout reached");
|
|
31379
31596
|
setLoadingTimeoutReached(true);
|
|
31380
31597
|
if (hasStoredSupabaseSession()) {
|
|
@@ -31386,13 +31603,13 @@ var withAuth = (WrappedComponent2, options) => {
|
|
|
31386
31603
|
router.replace(defaultOptions.redirectTo);
|
|
31387
31604
|
}
|
|
31388
31605
|
}, [retrySessionHydration, router]);
|
|
31389
|
-
|
|
31606
|
+
React143.useEffect(() => {
|
|
31390
31607
|
if (!loading && authStatus !== "recovering" && defaultOptions.requireAuth && !session && !error) {
|
|
31391
31608
|
console.log("[withAuth] No session found, redirecting to login");
|
|
31392
31609
|
router.replace(defaultOptions.redirectTo);
|
|
31393
31610
|
}
|
|
31394
31611
|
}, [authStatus, defaultOptions.requireAuth, error, loading, router, session]);
|
|
31395
|
-
|
|
31612
|
+
React143.useEffect(() => {
|
|
31396
31613
|
setLocalLoading(loading);
|
|
31397
31614
|
}, [loading]);
|
|
31398
31615
|
if (loading || localLoading) {
|
|
@@ -32391,11 +32608,11 @@ var BarChartComponent = ({
|
|
|
32391
32608
|
aspect = 2,
|
|
32392
32609
|
...restOfChartProps
|
|
32393
32610
|
}) => {
|
|
32394
|
-
const containerRef =
|
|
32395
|
-
const [containerReady, setContainerReady] =
|
|
32611
|
+
const containerRef = React143__default.useRef(null);
|
|
32612
|
+
const [containerReady, setContainerReady] = React143__default.useState(false);
|
|
32396
32613
|
const themeConfig = useThemeConfig();
|
|
32397
32614
|
const { formatNumber } = useFormatNumber();
|
|
32398
|
-
|
|
32615
|
+
React143__default.useEffect(() => {
|
|
32399
32616
|
const checkContainerDimensions = () => {
|
|
32400
32617
|
if (containerRef.current) {
|
|
32401
32618
|
const rect = containerRef.current.getBoundingClientRect();
|
|
@@ -32509,7 +32726,7 @@ var BarChartComponent = ({
|
|
|
32509
32726
|
}
|
|
32510
32727
|
return /* @__PURE__ */ jsx("div", { className: clsx("w-full", className), children: chartContent });
|
|
32511
32728
|
};
|
|
32512
|
-
var BarChart =
|
|
32729
|
+
var BarChart = React143__default.memo(BarChartComponent, (prevProps, nextProps) => {
|
|
32513
32730
|
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
32731
|
return false;
|
|
32515
32732
|
}
|
|
@@ -32560,10 +32777,10 @@ var LineChartComponent = ({
|
|
|
32560
32777
|
fillContainer = false,
|
|
32561
32778
|
...restOfChartProps
|
|
32562
32779
|
}) => {
|
|
32563
|
-
const containerRef =
|
|
32564
|
-
const [dimensions, setDimensions] =
|
|
32565
|
-
const [hasValidData, setHasValidData] =
|
|
32566
|
-
|
|
32780
|
+
const containerRef = React143__default.useRef(null);
|
|
32781
|
+
const [dimensions, setDimensions] = React143__default.useState({ width: 0, height: 0 });
|
|
32782
|
+
const [hasValidData, setHasValidData] = React143__default.useState(false);
|
|
32783
|
+
React143__default.useEffect(() => {
|
|
32567
32784
|
const currentHasValidData = data && lines && lines.length > 0 && data.some(
|
|
32568
32785
|
(item) => lines.some((line) => {
|
|
32569
32786
|
const val = item[line.dataKey];
|
|
@@ -32574,7 +32791,7 @@ var LineChartComponent = ({
|
|
|
32574
32791
|
setHasValidData(true);
|
|
32575
32792
|
}
|
|
32576
32793
|
}, [data, lines, hasValidData]);
|
|
32577
|
-
|
|
32794
|
+
React143__default.useEffect(() => {
|
|
32578
32795
|
if (!containerRef.current) return;
|
|
32579
32796
|
const observer = new ResizeObserver((entries) => {
|
|
32580
32797
|
const entry = entries[0];
|
|
@@ -32699,7 +32916,7 @@ var LineChartComponent = ({
|
|
|
32699
32916
|
}
|
|
32700
32917
|
return /* @__PURE__ */ jsx("div", { className: clsx("w-full", className), children: renderChartContent(restOfChartProps.width, restOfChartProps.height) });
|
|
32701
32918
|
};
|
|
32702
|
-
var LineChart =
|
|
32919
|
+
var LineChart = React143__default.memo(LineChartComponent, (prevProps, nextProps) => {
|
|
32703
32920
|
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
32921
|
return false;
|
|
32705
32922
|
}
|
|
@@ -32793,7 +33010,7 @@ var OutputProgressChartComponent = ({
|
|
|
32793
33010
|
] }) })
|
|
32794
33011
|
] }) });
|
|
32795
33012
|
};
|
|
32796
|
-
var OutputProgressChart =
|
|
33013
|
+
var OutputProgressChart = React143__default.memo(OutputProgressChartComponent);
|
|
32797
33014
|
OutputProgressChart.displayName = "OutputProgressChart";
|
|
32798
33015
|
var LargeOutputProgressChart = ({
|
|
32799
33016
|
currentOutput,
|
|
@@ -32933,7 +33150,7 @@ var CycleTimeChartComponent = ({
|
|
|
32933
33150
|
}
|
|
32934
33151
|
) }) });
|
|
32935
33152
|
};
|
|
32936
|
-
var CycleTimeChart =
|
|
33153
|
+
var CycleTimeChart = React143__default.memo(CycleTimeChartComponent, (prevProps, nextProps) => {
|
|
32937
33154
|
if (prevProps.className !== nextProps.className) {
|
|
32938
33155
|
return false;
|
|
32939
33156
|
}
|
|
@@ -33171,16 +33388,16 @@ var CycleTimeOverTimeChart = ({
|
|
|
33171
33388
|
idleTimeSlots = []
|
|
33172
33389
|
}) => {
|
|
33173
33390
|
const MAX_DATA_POINTS = 40;
|
|
33174
|
-
const containerRef =
|
|
33175
|
-
const [dimensions, setDimensions] =
|
|
33176
|
-
const [hasValidData, setHasValidData] =
|
|
33177
|
-
|
|
33391
|
+
const containerRef = React143__default.useRef(null);
|
|
33392
|
+
const [dimensions, setDimensions] = React143__default.useState({ width: 0, height: 0 });
|
|
33393
|
+
const [hasValidData, setHasValidData] = React143__default.useState(false);
|
|
33394
|
+
React143__default.useEffect(() => {
|
|
33178
33395
|
const currentHasValidData = data && data.some((val) => val !== null && val > 0);
|
|
33179
33396
|
if (currentHasValidData && !hasValidData) {
|
|
33180
33397
|
setHasValidData(true);
|
|
33181
33398
|
}
|
|
33182
33399
|
}, [data, hasValidData]);
|
|
33183
|
-
|
|
33400
|
+
React143__default.useEffect(() => {
|
|
33184
33401
|
if (!containerRef.current) return;
|
|
33185
33402
|
const observer = new ResizeObserver((entries) => {
|
|
33186
33403
|
const entry = entries[0];
|
|
@@ -33212,7 +33429,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
33212
33429
|
const endLabel = shiftEnd && slotIndex === DURATION - 1 ? formatHourLabel(slotIndex + 1) : formatHourLabel(slotIndex + 1);
|
|
33213
33430
|
return `${startLabel} - ${endLabel}`;
|
|
33214
33431
|
};
|
|
33215
|
-
const getDisplayData =
|
|
33432
|
+
const getDisplayData = React143__default.useCallback((rawData) => {
|
|
33216
33433
|
if (xAxisMode === "hourly") return rawData;
|
|
33217
33434
|
return rawData.slice(Math.max(0, rawData.length - MAX_DATA_POINTS));
|
|
33218
33435
|
}, [xAxisMode]);
|
|
@@ -33220,7 +33437,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
33220
33437
|
const DURATION = displayData.length;
|
|
33221
33438
|
const effectiveDatasetKey = datasetKey || `cycle-time:${xAxisMode}`;
|
|
33222
33439
|
const finalData = displayData;
|
|
33223
|
-
const labelInterval =
|
|
33440
|
+
const labelInterval = React143__default.useMemo(() => {
|
|
33224
33441
|
if (xAxisMode === "hourly") {
|
|
33225
33442
|
return Math.max(1, Math.ceil(DURATION / 8));
|
|
33226
33443
|
}
|
|
@@ -33261,8 +33478,8 @@ var CycleTimeOverTimeChart = ({
|
|
|
33261
33478
|
return `${minutes} minutes ${seconds} seconds ago`;
|
|
33262
33479
|
}
|
|
33263
33480
|
};
|
|
33264
|
-
const getNumericValue =
|
|
33265
|
-
const renderChartTooltip =
|
|
33481
|
+
const getNumericValue = React143__default.useCallback((value) => typeof value === "number" && Number.isFinite(value) ? value : null, []);
|
|
33482
|
+
const renderChartTooltip = React143__default.useCallback((tooltipProps) => {
|
|
33266
33483
|
const { active, payload } = tooltipProps;
|
|
33267
33484
|
if (!active || !Array.isArray(payload) || payload.length === 0) {
|
|
33268
33485
|
return null;
|
|
@@ -33325,7 +33542,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
33325
33542
|
] })
|
|
33326
33543
|
] });
|
|
33327
33544
|
}, [getNumericValue, shiftStart, showIdleTime]);
|
|
33328
|
-
const renderCycleDot =
|
|
33545
|
+
const renderCycleDot = React143__default.useCallback((props) => {
|
|
33329
33546
|
const { cx: cx2, cy, payload } = props;
|
|
33330
33547
|
const cycleTime = getNumericValue(payload?.cycleTime);
|
|
33331
33548
|
if (cycleTime === null) {
|
|
@@ -33358,7 +33575,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
33358
33575
|
}
|
|
33359
33576
|
);
|
|
33360
33577
|
}, [getNumericValue, idealCycleTime]);
|
|
33361
|
-
const renderCycleActiveDot =
|
|
33578
|
+
const renderCycleActiveDot = React143__default.useCallback((props) => {
|
|
33362
33579
|
const { cx: cx2, cy, payload } = props;
|
|
33363
33580
|
const cycleTime = getNumericValue(payload?.cycleTime);
|
|
33364
33581
|
if (cycleTime === null) {
|
|
@@ -33379,7 +33596,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
33379
33596
|
}
|
|
33380
33597
|
);
|
|
33381
33598
|
}, [getNumericValue, idealCycleTime]);
|
|
33382
|
-
const renderIdleDot =
|
|
33599
|
+
const renderIdleDot = React143__default.useCallback((props) => {
|
|
33383
33600
|
const { cx: cx2, cy, payload } = props;
|
|
33384
33601
|
const idleMinutes = getNumericValue(payload?.idleMinutes);
|
|
33385
33602
|
if (idleMinutes === null) {
|
|
@@ -33401,7 +33618,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
33401
33618
|
}
|
|
33402
33619
|
);
|
|
33403
33620
|
}, [getNumericValue, showIdleTime]);
|
|
33404
|
-
const renderIdleActiveDot =
|
|
33621
|
+
const renderIdleActiveDot = React143__default.useCallback((props) => {
|
|
33405
33622
|
const { cx: cx2, cy, payload } = props;
|
|
33406
33623
|
const idleMinutes = getNumericValue(payload?.idleMinutes);
|
|
33407
33624
|
if (idleMinutes === null || !showIdleTime) {
|
|
@@ -33419,7 +33636,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
33419
33636
|
}
|
|
33420
33637
|
);
|
|
33421
33638
|
}, [getNumericValue, showIdleTime]);
|
|
33422
|
-
const chartData =
|
|
33639
|
+
const chartData = React143__default.useMemo(() => Array.from({ length: DURATION }, (_, i) => {
|
|
33423
33640
|
const cycleTime = getNumericValue(finalData[i]);
|
|
33424
33641
|
const useIdleSlots = idleTimeSlots.length > 0;
|
|
33425
33642
|
const idleSlot = useIdleSlots ? idleTimeSlots[i] ?? null : null;
|
|
@@ -33616,7 +33833,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
33616
33833
|
}
|
|
33617
33834
|
);
|
|
33618
33835
|
};
|
|
33619
|
-
var Card =
|
|
33836
|
+
var Card = React143.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
33620
33837
|
"div",
|
|
33621
33838
|
{
|
|
33622
33839
|
ref,
|
|
@@ -33628,7 +33845,7 @@ var Card = React142.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
|
33628
33845
|
}
|
|
33629
33846
|
));
|
|
33630
33847
|
Card.displayName = "Card";
|
|
33631
|
-
var CardHeader =
|
|
33848
|
+
var CardHeader = React143.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
33632
33849
|
"div",
|
|
33633
33850
|
{
|
|
33634
33851
|
ref,
|
|
@@ -33637,7 +33854,7 @@ var CardHeader = React142.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
33637
33854
|
}
|
|
33638
33855
|
));
|
|
33639
33856
|
CardHeader.displayName = "CardHeader";
|
|
33640
|
-
var CardTitle =
|
|
33857
|
+
var CardTitle = React143.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
33641
33858
|
"h3",
|
|
33642
33859
|
{
|
|
33643
33860
|
ref,
|
|
@@ -33649,7 +33866,7 @@ var CardTitle = React142.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
33649
33866
|
}
|
|
33650
33867
|
));
|
|
33651
33868
|
CardTitle.displayName = "CardTitle";
|
|
33652
|
-
var CardDescription =
|
|
33869
|
+
var CardDescription = React143.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
33653
33870
|
"p",
|
|
33654
33871
|
{
|
|
33655
33872
|
ref,
|
|
@@ -33658,9 +33875,9 @@ var CardDescription = React142.forwardRef(({ className, ...props }, ref) => /* @
|
|
|
33658
33875
|
}
|
|
33659
33876
|
));
|
|
33660
33877
|
CardDescription.displayName = "CardDescription";
|
|
33661
|
-
var CardContent =
|
|
33878
|
+
var CardContent = React143.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("p-6 pt-0", className), ...props }));
|
|
33662
33879
|
CardContent.displayName = "CardContent";
|
|
33663
|
-
var CardFooter =
|
|
33880
|
+
var CardFooter = React143.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
33664
33881
|
"div",
|
|
33665
33882
|
{
|
|
33666
33883
|
ref,
|
|
@@ -33736,7 +33953,7 @@ var buttonVariants = cva(
|
|
|
33736
33953
|
}
|
|
33737
33954
|
}
|
|
33738
33955
|
);
|
|
33739
|
-
var Button =
|
|
33956
|
+
var Button = React143.forwardRef(
|
|
33740
33957
|
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
33741
33958
|
const Comp = asChild ? Slot : "button";
|
|
33742
33959
|
return /* @__PURE__ */ jsx(
|
|
@@ -33759,10 +33976,10 @@ var HourlyOutputChartComponent = ({
|
|
|
33759
33976
|
idleTimeHourly,
|
|
33760
33977
|
className = ""
|
|
33761
33978
|
}) => {
|
|
33762
|
-
const containerRef =
|
|
33763
|
-
const [containerReady, setContainerReady] =
|
|
33764
|
-
const [containerWidth, setContainerWidth] =
|
|
33765
|
-
const idleSlots =
|
|
33979
|
+
const containerRef = React143__default.useRef(null);
|
|
33980
|
+
const [containerReady, setContainerReady] = React143__default.useState(false);
|
|
33981
|
+
const [containerWidth, setContainerWidth] = React143__default.useState(0);
|
|
33982
|
+
const idleSlots = React143__default.useMemo(
|
|
33766
33983
|
() => buildHourlyIdleSlots({
|
|
33767
33984
|
idleTimeHourly,
|
|
33768
33985
|
shiftStart,
|
|
@@ -33771,12 +33988,12 @@ var HourlyOutputChartComponent = ({
|
|
|
33771
33988
|
[idleTimeHourly, shiftStart, shiftEnd]
|
|
33772
33989
|
);
|
|
33773
33990
|
const SHIFT_DURATION = idleSlots.length;
|
|
33774
|
-
const [animatedData, setAnimatedData] =
|
|
33991
|
+
const [animatedData, setAnimatedData] = React143__default.useState(
|
|
33775
33992
|
() => Array(SHIFT_DURATION).fill(0)
|
|
33776
33993
|
);
|
|
33777
|
-
const prevDataRef =
|
|
33778
|
-
const animationFrameRef =
|
|
33779
|
-
|
|
33994
|
+
const prevDataRef = React143__default.useRef(Array(SHIFT_DURATION).fill(0));
|
|
33995
|
+
const animationFrameRef = React143__default.useRef(null);
|
|
33996
|
+
React143__default.useEffect(() => {
|
|
33780
33997
|
setAnimatedData((prev) => {
|
|
33781
33998
|
if (prev.length !== SHIFT_DURATION) {
|
|
33782
33999
|
return Array(SHIFT_DURATION).fill(0);
|
|
@@ -33785,14 +34002,14 @@ var HourlyOutputChartComponent = ({
|
|
|
33785
34002
|
});
|
|
33786
34003
|
prevDataRef.current = Array(SHIFT_DURATION).fill(0);
|
|
33787
34004
|
}, [SHIFT_DURATION]);
|
|
33788
|
-
const [idleBarState, setIdleBarState] =
|
|
34005
|
+
const [idleBarState, setIdleBarState] = React143__default.useState({
|
|
33789
34006
|
visible: showIdleTime,
|
|
33790
34007
|
key: 0,
|
|
33791
34008
|
shouldAnimate: false
|
|
33792
34009
|
});
|
|
33793
|
-
const prevShowIdleTimeRef =
|
|
33794
|
-
const stateUpdateTimeoutRef =
|
|
33795
|
-
|
|
34010
|
+
const prevShowIdleTimeRef = React143__default.useRef(showIdleTime);
|
|
34011
|
+
const stateUpdateTimeoutRef = React143__default.useRef(null);
|
|
34012
|
+
React143__default.useEffect(() => {
|
|
33796
34013
|
if (stateUpdateTimeoutRef.current) {
|
|
33797
34014
|
clearTimeout(stateUpdateTimeoutRef.current);
|
|
33798
34015
|
}
|
|
@@ -33817,7 +34034,7 @@ var HourlyOutputChartComponent = ({
|
|
|
33817
34034
|
}
|
|
33818
34035
|
};
|
|
33819
34036
|
}, [showIdleTime]);
|
|
33820
|
-
const animateToNewData =
|
|
34037
|
+
const animateToNewData = React143__default.useCallback((targetData) => {
|
|
33821
34038
|
const startData = [...prevDataRef.current];
|
|
33822
34039
|
const startTime = performance.now();
|
|
33823
34040
|
const duration = 1200;
|
|
@@ -33847,7 +34064,7 @@ var HourlyOutputChartComponent = ({
|
|
|
33847
34064
|
}
|
|
33848
34065
|
animationFrameRef.current = requestAnimationFrame(animate);
|
|
33849
34066
|
}, []);
|
|
33850
|
-
|
|
34067
|
+
React143__default.useEffect(() => {
|
|
33851
34068
|
if (JSON.stringify(data) !== JSON.stringify(prevDataRef.current)) {
|
|
33852
34069
|
const shiftData = data.slice(0, SHIFT_DURATION);
|
|
33853
34070
|
animateToNewData(shiftData);
|
|
@@ -33858,7 +34075,7 @@ var HourlyOutputChartComponent = ({
|
|
|
33858
34075
|
}
|
|
33859
34076
|
};
|
|
33860
34077
|
}, [data, animateToNewData]);
|
|
33861
|
-
|
|
34078
|
+
React143__default.useEffect(() => {
|
|
33862
34079
|
const checkContainerDimensions = () => {
|
|
33863
34080
|
if (containerRef.current) {
|
|
33864
34081
|
const rect = containerRef.current.getBoundingClientRect();
|
|
@@ -33884,7 +34101,7 @@ var HourlyOutputChartComponent = ({
|
|
|
33884
34101
|
clearTimeout(fallbackTimeout);
|
|
33885
34102
|
};
|
|
33886
34103
|
}, []);
|
|
33887
|
-
const xAxisConfig =
|
|
34104
|
+
const xAxisConfig = React143__default.useMemo(() => {
|
|
33888
34105
|
if (containerWidth >= 960) {
|
|
33889
34106
|
return { interval: 0, angle: -45, height: 92, tickFont: 10, tickMargin: 12 };
|
|
33890
34107
|
}
|
|
@@ -33893,7 +34110,7 @@ var HourlyOutputChartComponent = ({
|
|
|
33893
34110
|
}
|
|
33894
34111
|
return { interval: 0, angle: -30, height: 64, tickFont: 9, tickMargin: 6 };
|
|
33895
34112
|
}, [containerWidth]);
|
|
33896
|
-
const chartData =
|
|
34113
|
+
const chartData = React143__default.useMemo(() => {
|
|
33897
34114
|
return Array.from({ length: SHIFT_DURATION }, (_, i) => {
|
|
33898
34115
|
const idleSlot = idleSlots[i];
|
|
33899
34116
|
return {
|
|
@@ -33909,7 +34126,7 @@ var HourlyOutputChartComponent = ({
|
|
|
33909
34126
|
};
|
|
33910
34127
|
});
|
|
33911
34128
|
}, [animatedData, data, pphThreshold, idleSlots, SHIFT_DURATION]);
|
|
33912
|
-
const IdleBar =
|
|
34129
|
+
const IdleBar = React143__default.useMemo(() => {
|
|
33913
34130
|
if (!idleBarState.visible) return null;
|
|
33914
34131
|
return /* @__PURE__ */ jsx(
|
|
33915
34132
|
Bar,
|
|
@@ -34207,7 +34424,7 @@ var HourlyOutputChartComponent = ({
|
|
|
34207
34424
|
}
|
|
34208
34425
|
);
|
|
34209
34426
|
};
|
|
34210
|
-
var HourlyOutputChart =
|
|
34427
|
+
var HourlyOutputChart = React143__default.memo(HourlyOutputChartComponent, (prevProps, nextProps) => {
|
|
34211
34428
|
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
34429
|
return false;
|
|
34213
34430
|
}
|
|
@@ -34387,7 +34604,7 @@ function getTrendArrowAndColor(trend) {
|
|
|
34387
34604
|
return { arrow: "\u2192", color: "text-gray-400" };
|
|
34388
34605
|
}
|
|
34389
34606
|
}
|
|
34390
|
-
var VideoCard =
|
|
34607
|
+
var VideoCard = React143__default.memo(({
|
|
34391
34608
|
workspace,
|
|
34392
34609
|
hlsUrl,
|
|
34393
34610
|
shouldPlay,
|
|
@@ -34585,7 +34802,7 @@ var logDebug2 = (...args) => {
|
|
|
34585
34802
|
if (!DEBUG_DASHBOARD_LOGS2) return;
|
|
34586
34803
|
console.log(...args);
|
|
34587
34804
|
};
|
|
34588
|
-
var VideoGridView =
|
|
34805
|
+
var VideoGridView = React143__default.memo(({
|
|
34589
34806
|
workspaces,
|
|
34590
34807
|
selectedLine,
|
|
34591
34808
|
lineNames = {},
|
|
@@ -34861,7 +35078,7 @@ var VideoGridView = React142__default.memo(({
|
|
|
34861
35078
|
efficiency: workspace.efficiency,
|
|
34862
35079
|
action_count: workspace.action_count
|
|
34863
35080
|
});
|
|
34864
|
-
const displayName = getWorkspaceDisplayName(workspace.workspace_name, workspace.line_id);
|
|
35081
|
+
const displayName = workspace.displayName || displayNames[`${workspace.line_id}_${workspace.workspace_name}`] || getWorkspaceDisplayName(workspace.workspace_name, workspace.line_id);
|
|
34865
35082
|
const currentPath = (router.asPath || "/").split("#")[0];
|
|
34866
35083
|
const navParams = getWorkspaceNavigationParams(workspaceId, displayName, workspace.line_id, currentPath);
|
|
34867
35084
|
router.push(`/workspace/${workspaceId}${navParams}`);
|
|
@@ -35019,7 +35236,7 @@ var VideoGridView = React142__default.memo(({
|
|
|
35019
35236
|
) });
|
|
35020
35237
|
});
|
|
35021
35238
|
VideoGridView.displayName = "VideoGridView";
|
|
35022
|
-
var MapGridView =
|
|
35239
|
+
var MapGridView = React143__default.memo(({
|
|
35023
35240
|
workspaces,
|
|
35024
35241
|
className = "",
|
|
35025
35242
|
displayNames = {},
|
|
@@ -35858,7 +36075,7 @@ var UptimeLineChartComponent = ({ points, className = "" }) => {
|
|
|
35858
36075
|
)
|
|
35859
36076
|
] }) }) });
|
|
35860
36077
|
};
|
|
35861
|
-
var UptimeLineChart =
|
|
36078
|
+
var UptimeLineChart = React143__default.memo(UptimeLineChartComponent);
|
|
35862
36079
|
var padTime = (value) => value.toString().padStart(2, "0");
|
|
35863
36080
|
var parseTime = (timeValue) => {
|
|
35864
36081
|
if (!timeValue) return null;
|
|
@@ -36098,10 +36315,10 @@ var HourlyUptimeChartComponent = ({
|
|
|
36098
36315
|
elapsedMinutes,
|
|
36099
36316
|
className = ""
|
|
36100
36317
|
}) => {
|
|
36101
|
-
const containerRef =
|
|
36102
|
-
const [containerReady, setContainerReady] =
|
|
36103
|
-
const [containerWidth, setContainerWidth] =
|
|
36104
|
-
const uptimeSeries =
|
|
36318
|
+
const containerRef = React143__default.useRef(null);
|
|
36319
|
+
const [containerReady, setContainerReady] = React143__default.useState(false);
|
|
36320
|
+
const [containerWidth, setContainerWidth] = React143__default.useState(0);
|
|
36321
|
+
const uptimeSeries = React143__default.useMemo(() => buildUptimeSeries({
|
|
36105
36322
|
idleTimeHourly,
|
|
36106
36323
|
shiftStart,
|
|
36107
36324
|
shiftEnd,
|
|
@@ -36110,11 +36327,11 @@ var HourlyUptimeChartComponent = ({
|
|
|
36110
36327
|
elapsedMinutes
|
|
36111
36328
|
}), [idleTimeHourly, shiftStart, shiftEnd, shiftDate, timezone, elapsedMinutes]);
|
|
36112
36329
|
const hasAggregateData = Boolean(hourlyAggregates && hourlyAggregates.length > 0);
|
|
36113
|
-
const shiftStartTime =
|
|
36330
|
+
const shiftStartTime = React143__default.useMemo(
|
|
36114
36331
|
() => getTimeFromTimeString(shiftStart),
|
|
36115
36332
|
[shiftStart]
|
|
36116
36333
|
);
|
|
36117
|
-
const { shiftDuration, shiftEndTime } =
|
|
36334
|
+
const { shiftDuration, shiftEndTime } = React143__default.useMemo(() => {
|
|
36118
36335
|
if (!shiftEnd) {
|
|
36119
36336
|
const fallbackHours = uptimeSeries.shiftMinutes > 0 ? Math.ceil(uptimeSeries.shiftMinutes / 60) : 0;
|
|
36120
36337
|
return { shiftDuration: fallbackHours, shiftEndTime: null };
|
|
@@ -36128,7 +36345,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
36128
36345
|
const hourCount = hasPartial ? Math.ceil(duration) : Math.round(duration);
|
|
36129
36346
|
return { shiftDuration: hourCount, shiftEndTime: endTime };
|
|
36130
36347
|
}, [shiftEnd, shiftStartTime.decimalHour, uptimeSeries.shiftMinutes]);
|
|
36131
|
-
const formatHour =
|
|
36348
|
+
const formatHour = React143__default.useCallback((hourIndex) => {
|
|
36132
36349
|
const isLastHour = hourIndex === shiftDuration - 1;
|
|
36133
36350
|
const startDecimalHour = shiftStartTime.decimalHour + hourIndex;
|
|
36134
36351
|
const startHour = Math.floor(startDecimalHour) % 24;
|
|
@@ -36153,7 +36370,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
36153
36370
|
};
|
|
36154
36371
|
return `${formatTime5(startHour, startMinute)}-${formatTime5(endHour, endMinute)}`;
|
|
36155
36372
|
}, [shiftDuration, shiftStartTime.decimalHour, shiftEndTime]);
|
|
36156
|
-
const formatTimeRange2 =
|
|
36373
|
+
const formatTimeRange2 = React143__default.useCallback((hourIndex) => {
|
|
36157
36374
|
const isLastHour = hourIndex === shiftDuration - 1;
|
|
36158
36375
|
const startDecimalHour = shiftStartTime.decimalHour + hourIndex;
|
|
36159
36376
|
const startHour = Math.floor(startDecimalHour) % 24;
|
|
@@ -36175,7 +36392,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
36175
36392
|
};
|
|
36176
36393
|
return `${formatTime5(startHour, startMinute)} - ${formatTime5(endHour, endMinute)}`;
|
|
36177
36394
|
}, [shiftDuration, shiftStartTime.decimalHour, shiftEndTime]);
|
|
36178
|
-
const chartData =
|
|
36395
|
+
const chartData = React143__default.useMemo(() => {
|
|
36179
36396
|
if (shiftDuration <= 0) return [];
|
|
36180
36397
|
if (hasAggregateData) {
|
|
36181
36398
|
return hourlyAggregates.map((entry, hourIndex) => ({
|
|
@@ -36217,7 +36434,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
36217
36434
|
}, [hasAggregateData, hourlyAggregates, uptimeSeries.points, uptimeSeries.elapsedMinutes, uptimeSeries.shiftMinutes, shiftDuration, formatHour, formatTimeRange2]);
|
|
36218
36435
|
const maxYValue = 100;
|
|
36219
36436
|
const yAxisTicks = [0, 25, 50, 75, 100];
|
|
36220
|
-
|
|
36437
|
+
React143__default.useEffect(() => {
|
|
36221
36438
|
const checkContainerDimensions = () => {
|
|
36222
36439
|
if (containerRef.current) {
|
|
36223
36440
|
const rect = containerRef.current.getBoundingClientRect();
|
|
@@ -36243,7 +36460,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
36243
36460
|
clearTimeout(fallbackTimeout);
|
|
36244
36461
|
};
|
|
36245
36462
|
}, []);
|
|
36246
|
-
const xAxisConfig =
|
|
36463
|
+
const xAxisConfig = React143__default.useMemo(() => {
|
|
36247
36464
|
if (containerWidth >= 960) {
|
|
36248
36465
|
return { interval: 0, angle: -45, height: 92, tickFont: 10, tickMargin: 12, labelMode: "full" };
|
|
36249
36466
|
}
|
|
@@ -36252,7 +36469,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
36252
36469
|
}
|
|
36253
36470
|
return { interval: 0, angle: -30, height: 64, tickFont: 9, tickMargin: 6, labelMode: "start" };
|
|
36254
36471
|
}, [containerWidth]);
|
|
36255
|
-
const formatXAxisTick =
|
|
36472
|
+
const formatXAxisTick = React143__default.useCallback((raw) => {
|
|
36256
36473
|
const label = typeof raw === "string" ? raw : String(raw);
|
|
36257
36474
|
if (xAxisConfig.labelMode === "full") return label;
|
|
36258
36475
|
const parts = label.split("-");
|
|
@@ -36458,7 +36675,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
36458
36675
|
}
|
|
36459
36676
|
);
|
|
36460
36677
|
};
|
|
36461
|
-
var HourlyUptimeChart =
|
|
36678
|
+
var HourlyUptimeChart = React143__default.memo(HourlyUptimeChartComponent);
|
|
36462
36679
|
var DEFAULT_COLORS2 = ["#00AB45", "#ef4444"];
|
|
36463
36680
|
var UptimeDonutChartComponent = ({
|
|
36464
36681
|
data,
|
|
@@ -36528,7 +36745,7 @@ var UptimeDonutChartComponent = ({
|
|
|
36528
36745
|
] }) })
|
|
36529
36746
|
] }) });
|
|
36530
36747
|
};
|
|
36531
|
-
var UptimeDonutChart =
|
|
36748
|
+
var UptimeDonutChart = React143__default.memo(UptimeDonutChartComponent);
|
|
36532
36749
|
UptimeDonutChart.displayName = "UptimeDonutChart";
|
|
36533
36750
|
var TrendIcon = ({ trend }) => {
|
|
36534
36751
|
if (trend === "up") {
|
|
@@ -36647,7 +36864,7 @@ var EmptyStateMessage = ({
|
|
|
36647
36864
|
iconClassName
|
|
36648
36865
|
}) => {
|
|
36649
36866
|
let IconContent = null;
|
|
36650
|
-
if (
|
|
36867
|
+
if (React143__default.isValidElement(iconType)) {
|
|
36651
36868
|
IconContent = iconType;
|
|
36652
36869
|
} else if (typeof iconType === "string") {
|
|
36653
36870
|
const MappedIcon = IconMap[iconType];
|
|
@@ -37146,37 +37363,101 @@ var getSeverityColor = (severity) => {
|
|
|
37146
37363
|
return "bg-gray-500";
|
|
37147
37364
|
}
|
|
37148
37365
|
};
|
|
37149
|
-
var
|
|
37150
|
-
|
|
37151
|
-
|
|
37152
|
-
|
|
37153
|
-
|
|
37154
|
-
|
|
37155
|
-
|
|
37156
|
-
|
|
37157
|
-
|
|
37158
|
-
|
|
37159
|
-
|
|
37160
|
-
const
|
|
37161
|
-
|
|
37162
|
-
|
|
37163
|
-
|
|
37164
|
-
|
|
37165
|
-
|
|
37166
|
-
|
|
37167
|
-
|
|
37168
|
-
|
|
37169
|
-
|
|
37170
|
-
|
|
37171
|
-
|
|
37172
|
-
|
|
37173
|
-
|
|
37174
|
-
|
|
37175
|
-
|
|
37176
|
-
|
|
37177
|
-
|
|
37366
|
+
var IDLE_RANGE_CATEGORY_IDS = /* @__PURE__ */ new Set(["idle_time", "low_value", "longest-idles"]);
|
|
37367
|
+
var CYCLE_RANGE_CATEGORY_IDS = /* @__PURE__ */ new Set([
|
|
37368
|
+
"cycle_completion",
|
|
37369
|
+
"best_cycle_time",
|
|
37370
|
+
"worst_cycle_time",
|
|
37371
|
+
"long_cycle_time",
|
|
37372
|
+
"fast-cycles",
|
|
37373
|
+
"slow-cycles"
|
|
37374
|
+
]);
|
|
37375
|
+
var roundToNearestMinute = (date) => {
|
|
37376
|
+
const rounded = new Date(date.getTime());
|
|
37377
|
+
const seconds = rounded.getSeconds();
|
|
37378
|
+
if (seconds > 30) {
|
|
37379
|
+
rounded.setMinutes(rounded.getMinutes() + 1);
|
|
37380
|
+
}
|
|
37381
|
+
rounded.setSeconds(0);
|
|
37382
|
+
rounded.setMilliseconds(0);
|
|
37383
|
+
return rounded;
|
|
37384
|
+
};
|
|
37385
|
+
var parseTimestamp = (value) => {
|
|
37386
|
+
if (!value) return null;
|
|
37387
|
+
const parsed = new Date(value);
|
|
37388
|
+
return Number.isNaN(parsed.getTime()) ? null : parsed;
|
|
37389
|
+
};
|
|
37390
|
+
var formatTimeWithoutPeriod = (date, timezone) => date.toLocaleTimeString("en-US", {
|
|
37391
|
+
hour: "numeric",
|
|
37392
|
+
minute: "2-digit",
|
|
37393
|
+
timeZone: timezone
|
|
37394
|
+
}).replace(/\s?(AM|PM)$/i, "");
|
|
37395
|
+
var formatClipExplorerSingleTime = (timestamp, timezone) => {
|
|
37396
|
+
const parsed = parseTimestamp(timestamp);
|
|
37397
|
+
if (!parsed) return "";
|
|
37398
|
+
return parsed.toLocaleTimeString("en-US", {
|
|
37399
|
+
hour12: true,
|
|
37400
|
+
hour: "numeric",
|
|
37401
|
+
minute: "2-digit",
|
|
37402
|
+
timeZone: timezone
|
|
37403
|
+
});
|
|
37404
|
+
};
|
|
37405
|
+
var formatTimestampRange = (startTime, endTime, timezone) => {
|
|
37406
|
+
const startDate = parseTimestamp(startTime);
|
|
37407
|
+
const endDate = parseTimestamp(endTime);
|
|
37408
|
+
if (!startDate || !endDate) {
|
|
37409
|
+
return formatClipExplorerSingleTime(endTime, timezone);
|
|
37410
|
+
}
|
|
37411
|
+
const roundedStart = roundToNearestMinute(startDate);
|
|
37412
|
+
const roundedEnd = roundToNearestMinute(endDate);
|
|
37413
|
+
const startFormatted = formatTimeWithoutPeriod(roundedStart, timezone);
|
|
37414
|
+
const endFormatted = roundedEnd.toLocaleTimeString("en-US", {
|
|
37415
|
+
hour: "numeric",
|
|
37416
|
+
minute: "2-digit",
|
|
37417
|
+
timeZone: timezone
|
|
37418
|
+
});
|
|
37178
37419
|
return `${startFormatted} - ${endFormatted}`;
|
|
37179
37420
|
};
|
|
37421
|
+
var getSecondsBetweenTimestamps = (startTime, endTime) => {
|
|
37422
|
+
const startDate = parseTimestamp(startTime);
|
|
37423
|
+
const endDate = parseTimestamp(endTime);
|
|
37424
|
+
if (!startDate || !endDate) return null;
|
|
37425
|
+
return Math.max(0, (endDate.getTime() - startDate.getTime()) / 1e3);
|
|
37426
|
+
};
|
|
37427
|
+
var formatClipExplorerTimeLabel = ({
|
|
37428
|
+
categoryId,
|
|
37429
|
+
clipTimestamp,
|
|
37430
|
+
timezone,
|
|
37431
|
+
durationSeconds,
|
|
37432
|
+
idleStartTime,
|
|
37433
|
+
idleEndTime
|
|
37434
|
+
}) => {
|
|
37435
|
+
if (IDLE_RANGE_CATEGORY_IDS.has(categoryId)) {
|
|
37436
|
+
const idleDurationSeconds = getSecondsBetweenTimestamps(idleStartTime, idleEndTime);
|
|
37437
|
+
const idleEndTimestamp = idleEndTime || clipTimestamp;
|
|
37438
|
+
if (idleDurationSeconds !== null && idleDurationSeconds >= 60 && idleStartTime && idleEndTime) {
|
|
37439
|
+
return formatTimestampRange(idleStartTime, idleEndTime, timezone);
|
|
37440
|
+
}
|
|
37441
|
+
if (idleDurationSeconds === null && typeof durationSeconds === "number" && Number.isFinite(durationSeconds) && durationSeconds >= 60) {
|
|
37442
|
+
const endDate = parseTimestamp(idleEndTimestamp);
|
|
37443
|
+
if (endDate) {
|
|
37444
|
+
const startDate = new Date(endDate.getTime() - durationSeconds * 1e3);
|
|
37445
|
+
return formatTimestampRange(startDate.toISOString(), idleEndTimestamp, timezone);
|
|
37446
|
+
}
|
|
37447
|
+
}
|
|
37448
|
+
return formatClipExplorerSingleTime(idleEndTimestamp, timezone);
|
|
37449
|
+
}
|
|
37450
|
+
const singleTime = formatClipExplorerSingleTime(clipTimestamp, timezone);
|
|
37451
|
+
if (CYCLE_RANGE_CATEGORY_IDS.has(categoryId) && typeof durationSeconds === "number" && Number.isFinite(durationSeconds) && durationSeconds > 60) {
|
|
37452
|
+
const endDate = parseTimestamp(clipTimestamp);
|
|
37453
|
+
if (endDate) {
|
|
37454
|
+
const startDate = new Date(endDate.getTime() - durationSeconds * 1e3);
|
|
37455
|
+
return formatTimestampRange(startDate.toISOString(), clipTimestamp, timezone);
|
|
37456
|
+
}
|
|
37457
|
+
}
|
|
37458
|
+
return singleTime;
|
|
37459
|
+
};
|
|
37460
|
+
var formatIdleTimeRange = (startTime, endTime, timezone) => formatTimestampRange(startTime, endTime, timezone);
|
|
37180
37461
|
var formatTime2 = (seconds) => {
|
|
37181
37462
|
if (!seconds || isNaN(seconds)) return "0:00";
|
|
37182
37463
|
const h = Math.floor(seconds / 3600);
|
|
@@ -38930,7 +39211,7 @@ function Skeleton({ className, ...props }) {
|
|
|
38930
39211
|
var Select = SelectPrimitive.Root;
|
|
38931
39212
|
var SelectGroup = SelectPrimitive.Group;
|
|
38932
39213
|
var SelectValue = SelectPrimitive.Value;
|
|
38933
|
-
var SelectTrigger =
|
|
39214
|
+
var SelectTrigger = React143.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
38934
39215
|
SelectPrimitive.Trigger,
|
|
38935
39216
|
{
|
|
38936
39217
|
ref,
|
|
@@ -38946,7 +39227,7 @@ var SelectTrigger = React142.forwardRef(({ className, children, ...props }, ref)
|
|
|
38946
39227
|
}
|
|
38947
39228
|
));
|
|
38948
39229
|
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
|
|
38949
|
-
var SelectScrollUpButton =
|
|
39230
|
+
var SelectScrollUpButton = React143.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
38950
39231
|
SelectPrimitive.ScrollUpButton,
|
|
38951
39232
|
{
|
|
38952
39233
|
ref,
|
|
@@ -38956,7 +39237,7 @@ var SelectScrollUpButton = React142.forwardRef(({ className, ...props }, ref) =>
|
|
|
38956
39237
|
}
|
|
38957
39238
|
));
|
|
38958
39239
|
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
|
|
38959
|
-
var SelectScrollDownButton =
|
|
39240
|
+
var SelectScrollDownButton = React143.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
38960
39241
|
SelectPrimitive.ScrollDownButton,
|
|
38961
39242
|
{
|
|
38962
39243
|
ref,
|
|
@@ -38966,7 +39247,7 @@ var SelectScrollDownButton = React142.forwardRef(({ className, ...props }, ref)
|
|
|
38966
39247
|
}
|
|
38967
39248
|
));
|
|
38968
39249
|
SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
|
|
38969
|
-
var SelectContent =
|
|
39250
|
+
var SelectContent = React143.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
|
|
38970
39251
|
SelectPrimitive.Content,
|
|
38971
39252
|
{
|
|
38972
39253
|
ref,
|
|
@@ -38994,7 +39275,7 @@ var SelectContent = React142.forwardRef(({ className, children, position = "popp
|
|
|
38994
39275
|
}
|
|
38995
39276
|
) }));
|
|
38996
39277
|
SelectContent.displayName = SelectPrimitive.Content.displayName;
|
|
38997
|
-
var SelectLabel =
|
|
39278
|
+
var SelectLabel = React143.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
38998
39279
|
SelectPrimitive.Label,
|
|
38999
39280
|
{
|
|
39000
39281
|
ref,
|
|
@@ -39003,7 +39284,7 @@ var SelectLabel = React142.forwardRef(({ className, ...props }, ref) => /* @__PU
|
|
|
39003
39284
|
}
|
|
39004
39285
|
));
|
|
39005
39286
|
SelectLabel.displayName = SelectPrimitive.Label.displayName;
|
|
39006
|
-
var SelectItem =
|
|
39287
|
+
var SelectItem = React143.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
39007
39288
|
SelectPrimitive.Item,
|
|
39008
39289
|
{
|
|
39009
39290
|
ref,
|
|
@@ -39019,7 +39300,7 @@ var SelectItem = React142.forwardRef(({ className, children, ...props }, ref) =>
|
|
|
39019
39300
|
}
|
|
39020
39301
|
));
|
|
39021
39302
|
SelectItem.displayName = SelectPrimitive.Item.displayName;
|
|
39022
|
-
var SelectSeparator =
|
|
39303
|
+
var SelectSeparator = React143.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
39023
39304
|
SelectPrimitive.Separator,
|
|
39024
39305
|
{
|
|
39025
39306
|
ref,
|
|
@@ -39641,7 +39922,7 @@ var TimePickerDropdown = ({
|
|
|
39641
39922
|
)
|
|
39642
39923
|
] });
|
|
39643
39924
|
};
|
|
39644
|
-
var SilentErrorBoundary = class extends
|
|
39925
|
+
var SilentErrorBoundary = class extends React143__default.Component {
|
|
39645
39926
|
constructor(props) {
|
|
39646
39927
|
super(props);
|
|
39647
39928
|
this.handleClearAndReload = () => {
|
|
@@ -39674,6 +39955,12 @@ var SilentErrorBoundary = class extends React142__default.Component {
|
|
|
39674
39955
|
componentStack: errorInfo.componentStack,
|
|
39675
39956
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
39676
39957
|
});
|
|
39958
|
+
captureSentryException(error, {
|
|
39959
|
+
surface: "react_error_boundary",
|
|
39960
|
+
component_stack: errorInfo.componentStack,
|
|
39961
|
+
error_count: this.state.errorCount + 1,
|
|
39962
|
+
pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
|
|
39963
|
+
});
|
|
39677
39964
|
this.setState((prev) => ({
|
|
39678
39965
|
errorCount: prev.errorCount + 1,
|
|
39679
39966
|
lastError: error,
|
|
@@ -41137,15 +41424,16 @@ var FileManagerFilters = ({
|
|
|
41137
41424
|
if ((displayCount > 0 || shouldShowEmptyIdleTime) && shouldShowCategory(category.id)) {
|
|
41138
41425
|
const colorClasses = getColorClasses(category.color);
|
|
41139
41426
|
const clipNodes = filteredClips.map((clip, index) => {
|
|
41140
|
-
const timeString = new Date(clip.clip_timestamp).toLocaleTimeString("en-US", {
|
|
41141
|
-
hour12: true,
|
|
41142
|
-
hour: "numeric",
|
|
41143
|
-
minute: "2-digit",
|
|
41144
|
-
timeZone: timezone
|
|
41145
|
-
// Use database timezone for display
|
|
41146
|
-
});
|
|
41147
41427
|
const cycleTime = extractCycleTimeSeconds(clip);
|
|
41148
|
-
const
|
|
41428
|
+
const baseTimeLabel = formatClipExplorerTimeLabel({
|
|
41429
|
+
categoryId: category.id,
|
|
41430
|
+
clipTimestamp: clip.clip_timestamp,
|
|
41431
|
+
timezone,
|
|
41432
|
+
durationSeconds: clip.duration,
|
|
41433
|
+
idleStartTime: clip.idle_start_time,
|
|
41434
|
+
idleEndTime: clip.idle_end_time
|
|
41435
|
+
});
|
|
41436
|
+
const displayLabel = `${baseTimeLabel}${clip.duration && category.id !== "idle_time" && category.id !== "low_value" ? ` - (${clip.duration.toFixed(1)}s)` : ""}`;
|
|
41149
41437
|
return {
|
|
41150
41438
|
id: clip.id,
|
|
41151
41439
|
label: displayLabel,
|
|
@@ -41196,16 +41484,15 @@ var FileManagerFilters = ({
|
|
|
41196
41484
|
percentileType: "fast-cycles",
|
|
41197
41485
|
isPercentile: true,
|
|
41198
41486
|
children: filteredFastCycles.map((clip, index) => {
|
|
41199
|
-
const timeString = new Date(clip.creation_timestamp || clip.timestamp || "").toLocaleTimeString("en-US", {
|
|
41200
|
-
hour12: true,
|
|
41201
|
-
hour: "numeric",
|
|
41202
|
-
minute: "2-digit",
|
|
41203
|
-
timeZone: timezone
|
|
41204
|
-
});
|
|
41205
41487
|
const cycleTime = extractCycleTimeSeconds(clip);
|
|
41206
41488
|
return {
|
|
41207
41489
|
id: clip.id,
|
|
41208
|
-
label: `${
|
|
41490
|
+
label: `${formatClipExplorerTimeLabel({
|
|
41491
|
+
categoryId: "fast-cycles",
|
|
41492
|
+
clipTimestamp: clip.creation_timestamp || clip.timestamp || "",
|
|
41493
|
+
timezone,
|
|
41494
|
+
durationSeconds: cycleTime
|
|
41495
|
+
})}${clip.cycle_time_seconds ? ` - (${clip.cycle_time_seconds.toFixed(1)}s)` : ""}`,
|
|
41209
41496
|
type: "video",
|
|
41210
41497
|
icon: getSeverityIcon(clip.severity, "fast-cycles", cycleTime, resolvedTargetCycleTime),
|
|
41211
41498
|
timestamp: clip.creation_timestamp,
|
|
@@ -41228,16 +41515,15 @@ var FileManagerFilters = ({
|
|
|
41228
41515
|
percentileType: "slow-cycles",
|
|
41229
41516
|
isPercentile: true,
|
|
41230
41517
|
children: filteredSlowCycles.map((clip, index) => {
|
|
41231
|
-
const timeString = new Date(clip.creation_timestamp || clip.timestamp || "").toLocaleTimeString("en-US", {
|
|
41232
|
-
hour12: true,
|
|
41233
|
-
hour: "numeric",
|
|
41234
|
-
minute: "2-digit",
|
|
41235
|
-
timeZone: timezone
|
|
41236
|
-
});
|
|
41237
41518
|
const cycleTime = extractCycleTimeSeconds(clip);
|
|
41238
41519
|
return {
|
|
41239
41520
|
id: clip.id,
|
|
41240
|
-
label: `${
|
|
41521
|
+
label: `${formatClipExplorerTimeLabel({
|
|
41522
|
+
categoryId: "slow-cycles",
|
|
41523
|
+
clipTimestamp: clip.creation_timestamp || clip.timestamp || "",
|
|
41524
|
+
timezone,
|
|
41525
|
+
durationSeconds: cycleTime
|
|
41526
|
+
})}${clip.cycle_time_seconds ? ` - (${clip.cycle_time_seconds.toFixed(1)}s)` : ""}`,
|
|
41241
41527
|
type: "video",
|
|
41242
41528
|
icon: getSeverityIcon(clip.severity, "slow-cycles", cycleTime, resolvedTargetCycleTime),
|
|
41243
41529
|
timestamp: clip.creation_timestamp,
|
|
@@ -46510,8 +46796,8 @@ var IdleTimeReasonChartComponent = ({
|
|
|
46510
46796
|
updateAnimation = "replay",
|
|
46511
46797
|
variant = "pie"
|
|
46512
46798
|
}) => {
|
|
46513
|
-
const [activeData, setActiveData] =
|
|
46514
|
-
|
|
46799
|
+
const [activeData, setActiveData] = React143__default.useState([]);
|
|
46800
|
+
React143__default.useEffect(() => {
|
|
46515
46801
|
if (updateAnimation === "smooth") {
|
|
46516
46802
|
setActiveData(data && data.length > 0 ? data : []);
|
|
46517
46803
|
return;
|
|
@@ -46530,7 +46816,7 @@ var IdleTimeReasonChartComponent = ({
|
|
|
46530
46816
|
setActiveData([]);
|
|
46531
46817
|
}
|
|
46532
46818
|
}, [data, updateAnimation]);
|
|
46533
|
-
|
|
46819
|
+
React143__default.useEffect(() => {
|
|
46534
46820
|
if (!data || data.length === 0) return;
|
|
46535
46821
|
data.forEach((entry, index) => {
|
|
46536
46822
|
if (entry.name.toLowerCase().includes("other")) {
|
|
@@ -46538,7 +46824,7 @@ var IdleTimeReasonChartComponent = ({
|
|
|
46538
46824
|
}
|
|
46539
46825
|
});
|
|
46540
46826
|
}, [data]);
|
|
46541
|
-
const pieKey =
|
|
46827
|
+
const pieKey = React143__default.useMemo(() => {
|
|
46542
46828
|
if (updateAnimation === "smooth") {
|
|
46543
46829
|
return "smooth";
|
|
46544
46830
|
}
|
|
@@ -46708,9 +46994,44 @@ var IdleTimeReasonChartComponent = ({
|
|
|
46708
46994
|
)
|
|
46709
46995
|
] });
|
|
46710
46996
|
};
|
|
46711
|
-
var IdleTimeReasonChart =
|
|
46997
|
+
var IdleTimeReasonChart = React143__default.memo(IdleTimeReasonChartComponent);
|
|
46712
46998
|
IdleTimeReasonChart.displayName = "IdleTimeReasonChart";
|
|
46713
46999
|
var IdleTimeReasonChart_default = IdleTimeReasonChart;
|
|
47000
|
+
|
|
47001
|
+
// src/lib/utils/cycleTime.ts
|
|
47002
|
+
var toFiniteNumber = (value) => {
|
|
47003
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
47004
|
+
if (typeof value === "string" && value.trim() !== "") {
|
|
47005
|
+
const parsed = Number(value);
|
|
47006
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
47007
|
+
}
|
|
47008
|
+
return null;
|
|
47009
|
+
};
|
|
47010
|
+
var getCycleRatio = (workspace) => {
|
|
47011
|
+
const idealCycleTime = toFiniteNumber(workspace.ideal_cycle_time);
|
|
47012
|
+
const avgCycleTime = toFiniteNumber(workspace.avg_cycle_time);
|
|
47013
|
+
if (idealCycleTime === null || avgCycleTime === null || idealCycleTime <= 0 || avgCycleTime <= 0) {
|
|
47014
|
+
return null;
|
|
47015
|
+
}
|
|
47016
|
+
return idealCycleTime / avgCycleTime;
|
|
47017
|
+
};
|
|
47018
|
+
var formatCycleTimeValue = (value) => {
|
|
47019
|
+
const numericValue = toFiniteNumber(value);
|
|
47020
|
+
if (numericValue === null || numericValue <= 0) return "--";
|
|
47021
|
+
return `${numericValue.toFixed(1)}s`;
|
|
47022
|
+
};
|
|
47023
|
+
var CycleTimeComparison = memo$1(({
|
|
47024
|
+
workspace
|
|
47025
|
+
}) => {
|
|
47026
|
+
const averageValue = formatCycleTimeValue(workspace.avg_cycle_time);
|
|
47027
|
+
const standardValue = formatCycleTimeValue(workspace.ideal_cycle_time);
|
|
47028
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 tabular-nums", children: [
|
|
47029
|
+
/* @__PURE__ */ jsx("span", { className: "font-semibold text-gray-900", children: averageValue }),
|
|
47030
|
+
/* @__PURE__ */ jsx("span", { className: "text-gray-400 font-normal", children: "/" }),
|
|
47031
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-gray-500", children: standardValue })
|
|
47032
|
+
] });
|
|
47033
|
+
}, (prevProps, nextProps) => prevProps.workspace.avg_cycle_time === nextProps.workspace.avg_cycle_time && prevProps.workspace.ideal_cycle_time === nextProps.workspace.ideal_cycle_time);
|
|
47034
|
+
CycleTimeComparison.displayName = "CycleTimeComparison";
|
|
46714
47035
|
var DEFAULT_PERFORMANCE_DATA = {
|
|
46715
47036
|
avg_efficiency: 0,
|
|
46716
47037
|
underperforming_workspaces: 0,
|
|
@@ -46809,6 +47130,7 @@ var LineMonthlyHistory = ({
|
|
|
46809
47130
|
timezone,
|
|
46810
47131
|
legend,
|
|
46811
47132
|
monitoringMode,
|
|
47133
|
+
lineAssembly = false,
|
|
46812
47134
|
underperformingWorkspaces = {},
|
|
46813
47135
|
lineId,
|
|
46814
47136
|
selectedShiftId = 0,
|
|
@@ -47098,7 +47420,7 @@ var LineMonthlyHistory = ({
|
|
|
47098
47420
|
"div",
|
|
47099
47421
|
{
|
|
47100
47422
|
className: `w-3 h-3 sm:w-4 sm:h-4 rounded ${getColorClass(performance2.performance_score)}`,
|
|
47101
|
-
title: `${getPerformanceText(performance2.performance_score)} performance on ${new Date(performance2.date).toLocaleDateString()}${performance2.efficiency !== void 0 ? ` (${performance2.efficiency.toFixed(1)}% efficiency)` : ""}`
|
|
47423
|
+
title: `${getPerformanceText(performance2.performance_score)} performance on ${new Date(performance2.date).toLocaleDateString()}${performance2.efficiency !== void 0 ? ` (${performance2.efficiency.toFixed(1)}% efficiency)` : performance2.avg_cycle_time !== void 0 && performance2.avg_cycle_time !== null && performance2.ideal_cycle_time !== void 0 && performance2.ideal_cycle_time !== null ? ` (${performance2.avg_cycle_time.toFixed(1)}s / ${performance2.ideal_cycle_time.toFixed(1)}s cycle time)` : ""}`
|
|
47102
47424
|
},
|
|
47103
47425
|
`${performance2.date}-${index}`
|
|
47104
47426
|
)) });
|
|
@@ -47344,13 +47666,20 @@ var LineMonthlyHistory = ({
|
|
|
47344
47666
|
onClick: () => handleWorkspaceClick(workspace),
|
|
47345
47667
|
className: "block hover:bg-gray-50 transition-colors rounded-lg w-full text-left group",
|
|
47346
47668
|
children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between py-1 sm:py-1.5 lg:py-2 px-1 sm:px-2 border-b border-gray-50 group-last:border-b-0", children: [
|
|
47347
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
47348
|
-
getWorkspaceDisplayName(workspace.workspace_name, lineId),
|
|
47349
|
-
workspace.
|
|
47350
|
-
|
|
47669
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
47670
|
+
/* @__PURE__ */ jsx("div", { className: "font-medium text-gray-900 text-[10px] sm:text-xs truncate", children: getWorkspaceDisplayName(workspace.workspace_name, lineId) }),
|
|
47671
|
+
lineAssembly && workspace.metric_mode === "cycle_time" ? /* @__PURE__ */ jsx("div", { className: "mt-0.5 text-[9px] sm:text-[11px]", children: /* @__PURE__ */ jsx(
|
|
47672
|
+
CycleTimeComparison,
|
|
47673
|
+
{
|
|
47674
|
+
workspace: {
|
|
47675
|
+
avg_cycle_time: workspace.avg_cycle_time ?? 0,
|
|
47676
|
+
ideal_cycle_time: workspace.ideal_cycle_time ?? void 0
|
|
47677
|
+
}
|
|
47678
|
+
}
|
|
47679
|
+
) }) : workspace.avg_efficiency !== void 0 ? /* @__PURE__ */ jsxs("div", { className: "mt-0.5 text-[8px] sm:text-[10px] text-gray-500", children: [
|
|
47351
47680
|
(workspace.avg_efficiency || 0).toFixed(1),
|
|
47352
|
-
"%
|
|
47353
|
-
] })
|
|
47681
|
+
"%"
|
|
47682
|
+
] }) : null
|
|
47354
47683
|
] }),
|
|
47355
47684
|
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-0.5 sm:gap-1 lg:gap-1.5", children: renderPerformanceSquares(workspace.last_5_days) })
|
|
47356
47685
|
] })
|
|
@@ -49720,7 +50049,7 @@ var WorkspaceMonthlyHistory = ({
|
|
|
49720
50049
|
Math.round(shiftData.efficiency || 0),
|
|
49721
50050
|
"%"
|
|
49722
50051
|
] }),
|
|
49723
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
50052
|
+
!isAssemblyWorkspace && /* @__PURE__ */ jsxs("div", { children: [
|
|
49724
50053
|
"Output: ",
|
|
49725
50054
|
shiftData.output || 0,
|
|
49726
50055
|
" units"
|
|
@@ -51075,7 +51404,7 @@ var arePropsEqual = (prevProps, nextProps) => {
|
|
|
51075
51404
|
return prevProps.data.efficiency === nextProps.data.efficiency && prevProps.data.trend_score === nextProps.data.trend_score && prevProps.data.workspace_id === nextProps.data.workspace_id && prevProps.data.workspace_name === nextProps.data.workspace_name && prevProps.isBottleneck === nextProps.isBottleneck && prevProps.isLowEfficiency === nextProps.isLowEfficiency && prevProps.isVeryLowEfficiency === nextProps.isVeryLowEfficiency && prevLegend.green_min === nextLegend.green_min && prevLegend.green_max === nextLegend.green_max && prevLegend.yellow_min === nextLegend.yellow_min && prevLegend.yellow_max === nextLegend.yellow_max && prevLegend.red_min === nextLegend.red_min && prevLegend.red_max === nextLegend.red_max && prevLegend.critical_threshold === nextLegend.critical_threshold && // Position doesn't need deep equality check as it's generally static
|
|
51076
51405
|
prevProps.position.id === nextProps.position.id;
|
|
51077
51406
|
};
|
|
51078
|
-
var WorkspaceGridItem =
|
|
51407
|
+
var WorkspaceGridItem = React143__default.memo(({
|
|
51079
51408
|
data,
|
|
51080
51409
|
position,
|
|
51081
51410
|
isBottleneck = false,
|
|
@@ -51103,7 +51432,7 @@ var WorkspaceGridItem = React142__default.memo(({
|
|
|
51103
51432
|
const handleClick = useCallback((e) => {
|
|
51104
51433
|
e.preventDefault();
|
|
51105
51434
|
if (isInactive) return;
|
|
51106
|
-
const displayName = getWorkspaceDisplayName(data.workspace_name, data.line_id);
|
|
51435
|
+
const displayName = data.displayName || getWorkspaceDisplayName(data.workspace_name, data.line_id);
|
|
51107
51436
|
const currentPath = typeof window !== "undefined" ? `${window.location.pathname}${window.location.search}` : "/";
|
|
51108
51437
|
const navParams = getWorkspaceNavigationParams(data.workspace_id, displayName, data.line_id, currentPath);
|
|
51109
51438
|
navigate(`/workspace/${data.workspace_id}${navParams}`, {
|
|
@@ -51152,7 +51481,7 @@ var WorkspaceGridItem = React142__default.memo(({
|
|
|
51152
51481
|
onClick: handleClick,
|
|
51153
51482
|
className: `${styles2} ${colorClass} ${isBottleneck ? "ring-2 ring-red-500/70" : ""} ${isVeryLowEfficiency ? "ring-2 ring-red-500/50" : ""} ${isInactive ? "bg-gray-200" : ""} shadow-lg touch-manipulation active:scale-[0.98] transition-transform`,
|
|
51154
51483
|
"aria-label": isInactive ? `Inactive workspace ${workspaceNumber}` : `View details for workspace ${workspaceNumber}`,
|
|
51155
|
-
title: isInactive ? `Inactive: ${getWorkspaceDisplayName(data.workspace_name, data.line_id)}` : getWorkspaceDisplayName(data.workspace_name, data.line_id),
|
|
51484
|
+
title: isInactive ? `Inactive: ${data.displayName || getWorkspaceDisplayName(data.workspace_name, data.line_id)}` : data.displayName || getWorkspaceDisplayName(data.workspace_name, data.line_id),
|
|
51156
51485
|
children: /* @__PURE__ */ jsx("div", { className: `font-semibold tracking-wide text-lg sm:text-xl md:text-[min(4vw,2rem)] uppercase ${isInactive ? "text-gray-400" : "text-white"} drop-shadow-sm`, children: workspaceNumber })
|
|
51157
51486
|
}
|
|
51158
51487
|
),
|
|
@@ -51170,7 +51499,7 @@ var WorkspaceGridItem = React142__default.memo(({
|
|
|
51170
51499
|
);
|
|
51171
51500
|
}, arePropsEqual);
|
|
51172
51501
|
WorkspaceGridItem.displayName = "WorkspaceGridItem";
|
|
51173
|
-
var WorkspaceGrid =
|
|
51502
|
+
var WorkspaceGrid = React143__default.memo(({
|
|
51174
51503
|
workspaces,
|
|
51175
51504
|
isPdfMode = false,
|
|
51176
51505
|
customWorkspacePositions,
|
|
@@ -51434,7 +51763,7 @@ var KPICard = ({
|
|
|
51434
51763
|
}) => {
|
|
51435
51764
|
useThemeConfig();
|
|
51436
51765
|
const { formatNumber } = useFormatNumber();
|
|
51437
|
-
const trendInfo =
|
|
51766
|
+
const trendInfo = React143__default.useMemo(() => {
|
|
51438
51767
|
let trendValue = trend || "neutral";
|
|
51439
51768
|
if (change !== void 0 && trend === void 0) {
|
|
51440
51769
|
trendValue = change > 0 ? "up" : change < 0 ? "down" : "neutral";
|
|
@@ -51461,7 +51790,7 @@ var KPICard = ({
|
|
|
51461
51790
|
const shouldShowTrend = !(change === 0 && trend === void 0);
|
|
51462
51791
|
return { trendValue, Icon: Icon2, colorClass, bgClass, shouldShowTrend };
|
|
51463
51792
|
}, [trend, change]);
|
|
51464
|
-
const formattedValue =
|
|
51793
|
+
const formattedValue = React143__default.useMemo(() => {
|
|
51465
51794
|
if (title === "Quality Compliance" && typeof value === "number") {
|
|
51466
51795
|
return value.toFixed(1);
|
|
51467
51796
|
}
|
|
@@ -51475,7 +51804,7 @@ var KPICard = ({
|
|
|
51475
51804
|
}
|
|
51476
51805
|
return value;
|
|
51477
51806
|
}, [value, title]);
|
|
51478
|
-
const formattedChange =
|
|
51807
|
+
const formattedChange = React143__default.useMemo(() => {
|
|
51479
51808
|
if (change === void 0 || change === 0 && !showZeroChange) return null;
|
|
51480
51809
|
const absChange = Math.abs(change);
|
|
51481
51810
|
return formatNumber(absChange, { minimumFractionDigits: 0, maximumFractionDigits: 1 });
|
|
@@ -52982,7 +53311,7 @@ var Breadcrumbs = ({ items }) => {
|
|
|
52982
53311
|
}
|
|
52983
53312
|
}
|
|
52984
53313
|
};
|
|
52985
|
-
return /* @__PURE__ */ jsx("nav", { "aria-label": "Breadcrumb", className: "mb-1 flex items-center space-x-1 text-xs font-medium text-gray-500 dark:text-gray-400", children: items.map((item, index) => /* @__PURE__ */ jsxs(
|
|
53314
|
+
return /* @__PURE__ */ jsx("nav", { "aria-label": "Breadcrumb", className: "mb-1 flex items-center space-x-1 text-xs font-medium text-gray-500 dark:text-gray-400", children: items.map((item, index) => /* @__PURE__ */ jsxs(React143__default.Fragment, { children: [
|
|
52986
53315
|
index > 0 && /* @__PURE__ */ jsx(ChevronRight, { className: "h-3 w-3 text-gray-400 dark:text-gray-500" }),
|
|
52987
53316
|
/* @__PURE__ */ jsxs(
|
|
52988
53317
|
"span",
|
|
@@ -54458,7 +54787,7 @@ var AwardBadge = ({
|
|
|
54458
54787
|
}) => {
|
|
54459
54788
|
const styles2 = getBadgeStyles(type);
|
|
54460
54789
|
const Icon2 = CustomIcon || getDefaultIcon(type);
|
|
54461
|
-
const randomDelay =
|
|
54790
|
+
const randomDelay = React143__default.useMemo(() => Math.random() * 2, []);
|
|
54462
54791
|
const floatingAnimation = {
|
|
54463
54792
|
animate: {
|
|
54464
54793
|
y: [0, -10, 0],
|
|
@@ -59962,67 +60291,77 @@ var NotificationService = class {
|
|
|
59962
60291
|
this.supabaseClient = supabaseClient || null;
|
|
59963
60292
|
}
|
|
59964
60293
|
async fetchWithAuth(url, options = {}) {
|
|
59965
|
-
|
|
59966
|
-
|
|
59967
|
-
|
|
59968
|
-
const { data: { session }, error: sessionError } = await this.supabaseClient.auth.getSession();
|
|
59969
|
-
if (sessionError) {
|
|
59970
|
-
console.error("Session error:", sessionError);
|
|
59971
|
-
throw new Error("Failed to get authentication session. Please log in.");
|
|
59972
|
-
}
|
|
59973
|
-
if (!session) {
|
|
59974
|
-
console.error("No session found. User must be logged in.");
|
|
59975
|
-
throw new Error("User not authenticated. Please log in.");
|
|
59976
|
-
}
|
|
59977
|
-
if (!session.access_token) {
|
|
59978
|
-
console.error("Session exists but no access_token found");
|
|
59979
|
-
throw new Error("Invalid session. Please log in again.");
|
|
59980
|
-
}
|
|
59981
|
-
const token = session.access_token;
|
|
59982
|
-
if (process.env.NODE_ENV === "development") {
|
|
59983
|
-
console.log("[NotificationService] Using JWT token for notifications API");
|
|
59984
|
-
}
|
|
59985
|
-
const headers = {
|
|
59986
|
-
"Content-Type": "application/json",
|
|
59987
|
-
...options.headers,
|
|
59988
|
-
"Authorization": `Bearer ${token}`
|
|
59989
|
-
};
|
|
59990
|
-
const response = await fetch(url, {
|
|
59991
|
-
...options,
|
|
59992
|
-
headers
|
|
59993
|
-
});
|
|
59994
|
-
if (response.status === 401) {
|
|
59995
|
-
console.error("401 Unauthorized - Token expired or invalid");
|
|
59996
|
-
throw new Error("Authentication failed. Please log in again.");
|
|
59997
|
-
}
|
|
59998
|
-
if (response.status === 403) {
|
|
59999
|
-
console.error("403 Forbidden - User does not have permission");
|
|
60000
|
-
throw new Error("Access denied. You do not have permission to access this resource.");
|
|
60001
|
-
}
|
|
60002
|
-
if (response.status === 500) {
|
|
60003
|
-
console.error("500 Internal Server Error - Backend error");
|
|
60004
|
-
let errorDetail = "Internal server error occurred.";
|
|
60005
|
-
try {
|
|
60006
|
-
const errorData = await response.text();
|
|
60007
|
-
console.error("Backend error details:", errorData);
|
|
60008
|
-
errorDetail = errorData || errorDetail;
|
|
60009
|
-
} catch (e) {
|
|
60294
|
+
try {
|
|
60295
|
+
if (!this.supabaseClient) {
|
|
60296
|
+
throw new Error("Supabase client not initialized. Please provide a Supabase client to NotificationService.");
|
|
60010
60297
|
}
|
|
60011
|
-
|
|
60012
|
-
|
|
60013
|
-
|
|
60014
|
-
|
|
60015
|
-
|
|
60016
|
-
|
|
60017
|
-
|
|
60018
|
-
|
|
60019
|
-
|
|
60298
|
+
const { data: { session }, error: sessionError } = await this.supabaseClient.auth.getSession();
|
|
60299
|
+
if (sessionError) {
|
|
60300
|
+
console.error("Session error:", sessionError);
|
|
60301
|
+
throw new Error("Failed to get authentication session. Please log in.");
|
|
60302
|
+
}
|
|
60303
|
+
if (!session) {
|
|
60304
|
+
console.error("No session found. User must be logged in.");
|
|
60305
|
+
throw new Error("User not authenticated. Please log in.");
|
|
60306
|
+
}
|
|
60307
|
+
if (!session.access_token) {
|
|
60308
|
+
console.error("Session exists but no access_token found");
|
|
60309
|
+
throw new Error("Invalid session. Please log in again.");
|
|
60310
|
+
}
|
|
60311
|
+
const token = session.access_token;
|
|
60312
|
+
if (process.env.NODE_ENV === "development") {
|
|
60313
|
+
console.log("[NotificationService] Using JWT token for notifications API");
|
|
60314
|
+
}
|
|
60315
|
+
const headers = {
|
|
60316
|
+
"Content-Type": "application/json",
|
|
60317
|
+
...options.headers,
|
|
60318
|
+
"Authorization": `Bearer ${token}`
|
|
60319
|
+
};
|
|
60320
|
+
const response = await fetch(url, {
|
|
60321
|
+
...options,
|
|
60322
|
+
headers
|
|
60323
|
+
});
|
|
60324
|
+
if (response.status === 401) {
|
|
60325
|
+
console.error("401 Unauthorized - Token expired or invalid");
|
|
60326
|
+
throw new Error("Authentication failed. Please log in again.");
|
|
60327
|
+
}
|
|
60328
|
+
if (response.status === 403) {
|
|
60329
|
+
console.error("403 Forbidden - User does not have permission");
|
|
60330
|
+
throw new Error("Access denied. You do not have permission to access this resource.");
|
|
60331
|
+
}
|
|
60332
|
+
if (response.status === 500) {
|
|
60333
|
+
console.error("500 Internal Server Error - Backend error");
|
|
60334
|
+
let errorDetail = "Internal server error occurred.";
|
|
60335
|
+
try {
|
|
60336
|
+
const errorData = await response.text();
|
|
60337
|
+
console.error("Backend error details:", errorData);
|
|
60338
|
+
errorDetail = errorData || errorDetail;
|
|
60339
|
+
} catch (e) {
|
|
60020
60340
|
}
|
|
60021
|
-
|
|
60341
|
+
throw new Error(`Backend error: ${errorDetail}`);
|
|
60022
60342
|
}
|
|
60023
|
-
|
|
60343
|
+
if (!response.ok) {
|
|
60344
|
+
console.error(`HTTP ${response.status} - ${response.statusText}`);
|
|
60345
|
+
let errorDetail = response.statusText;
|
|
60346
|
+
try {
|
|
60347
|
+
const errorData = await response.json();
|
|
60348
|
+
if (errorData.detail) {
|
|
60349
|
+
errorDetail = errorData.detail;
|
|
60350
|
+
}
|
|
60351
|
+
} catch (e) {
|
|
60352
|
+
}
|
|
60353
|
+
throw new Error(`Request failed (${response.status}): ${errorDetail}`);
|
|
60354
|
+
}
|
|
60355
|
+
return response;
|
|
60356
|
+
} catch (error) {
|
|
60357
|
+
captureHandledFrontendException(error, {
|
|
60358
|
+
surface: "notification_service",
|
|
60359
|
+
url,
|
|
60360
|
+
method: options.method || "GET",
|
|
60361
|
+
pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
|
|
60362
|
+
});
|
|
60363
|
+
throw error;
|
|
60024
60364
|
}
|
|
60025
|
-
return response;
|
|
60026
60365
|
}
|
|
60027
60366
|
/**
|
|
60028
60367
|
* Get bottleneck notifications
|
|
@@ -60096,8 +60435,6 @@ function HomeView({
|
|
|
60096
60435
|
}) {
|
|
60097
60436
|
const [isHydrated, setIsHydrated] = useState(false);
|
|
60098
60437
|
const [isChangingFilter, setIsChangingFilter] = useState(false);
|
|
60099
|
-
const [errorMessage, setErrorMessage] = useState(null);
|
|
60100
|
-
const [displayNamesInitialized, setDisplayNamesInitialized] = useState(false);
|
|
60101
60438
|
const [hasInitialDataLoaded, setHasInitialDataLoaded] = useState(false);
|
|
60102
60439
|
const [showDataLoading, setShowDataLoading] = useState(false);
|
|
60103
60440
|
const loadingStartRef = useRef(null);
|
|
@@ -60106,7 +60443,7 @@ function HomeView({
|
|
|
60106
60443
|
const dashboardConfig = useDashboardConfig();
|
|
60107
60444
|
const entityConfig = useEntityConfig();
|
|
60108
60445
|
const supabaseClient = useSupabaseClient();
|
|
60109
|
-
const { user } = useAuth();
|
|
60446
|
+
const { user, authStatus, isRecoveringSession, retrySessionHydration } = useAuth();
|
|
60110
60447
|
const { lines: dbLines } = useLines();
|
|
60111
60448
|
const mergedLineNames = useMemo(() => {
|
|
60112
60449
|
const merged = { ...lineNames };
|
|
@@ -60240,26 +60577,7 @@ function HomeView({
|
|
|
60240
60577
|
visibleLineIds,
|
|
60241
60578
|
dashboardConfig?.shiftConfig
|
|
60242
60579
|
);
|
|
60243
|
-
|
|
60244
|
-
const initDisplayNames = async () => {
|
|
60245
|
-
try {
|
|
60246
|
-
for (const lineId of selectedLineIds) {
|
|
60247
|
-
await preInitializeWorkspaceDisplayNames(lineId);
|
|
60248
|
-
}
|
|
60249
|
-
setDisplayNamesInitialized(true);
|
|
60250
|
-
} catch (error) {
|
|
60251
|
-
console.error("Failed to pre-initialize workspace display names:", error);
|
|
60252
|
-
setDisplayNamesInitialized(true);
|
|
60253
|
-
}
|
|
60254
|
-
};
|
|
60255
|
-
initDisplayNames();
|
|
60256
|
-
}, [selectedLineIdsKey]);
|
|
60257
|
-
const displayNameLineId = isMultiLineSelection ? void 0 : primarySelectedLineId;
|
|
60258
|
-
const {
|
|
60259
|
-
displayNames: workspaceDisplayNames,
|
|
60260
|
-
loading: displayNamesLoading,
|
|
60261
|
-
error: displayNamesError
|
|
60262
|
-
} = useWorkspaceDisplayNames(displayNameLineId, void 0);
|
|
60580
|
+
const shouldEnableMetricsFetch = authStatus === "ready";
|
|
60263
60581
|
const handleLineMetricsUpdate = useCallback(() => {
|
|
60264
60582
|
if (trendRefreshTimerRef.current) {
|
|
60265
60583
|
window.clearTimeout(trendRefreshTimerRef.current);
|
|
@@ -60286,9 +60604,32 @@ function HomeView({
|
|
|
60286
60604
|
lineId: metricsScopeLineId,
|
|
60287
60605
|
lineIds: selectedLineIds,
|
|
60288
60606
|
onLineMetricsUpdate: handleLineMetricsUpdate,
|
|
60289
|
-
userAccessibleLineIds: visibleLineIds
|
|
60607
|
+
userAccessibleLineIds: visibleLineIds,
|
|
60290
60608
|
// Pass user's accessible lines for supervisor filtering
|
|
60609
|
+
enabled: shouldEnableMetricsFetch
|
|
60291
60610
|
});
|
|
60611
|
+
const metricsDisplayNames = useMemo(() => {
|
|
60612
|
+
const nextDisplayNames = {};
|
|
60613
|
+
workspaceMetrics.forEach((workspace) => {
|
|
60614
|
+
if (!workspace.displayName) {
|
|
60615
|
+
return;
|
|
60616
|
+
}
|
|
60617
|
+
nextDisplayNames[`${workspace.line_id}_${workspace.workspace_name}`] = workspace.displayName;
|
|
60618
|
+
});
|
|
60619
|
+
return nextDisplayNames;
|
|
60620
|
+
}, [workspaceMetrics]);
|
|
60621
|
+
useEffect(() => {
|
|
60622
|
+
workspaceMetrics.forEach((workspace) => {
|
|
60623
|
+
if (!workspace.displayName) {
|
|
60624
|
+
return;
|
|
60625
|
+
}
|
|
60626
|
+
upsertWorkspaceDisplayNameInCache({
|
|
60627
|
+
lineId: workspace.line_id,
|
|
60628
|
+
workspaceId: workspace.workspace_name,
|
|
60629
|
+
displayName: workspace.displayName
|
|
60630
|
+
});
|
|
60631
|
+
});
|
|
60632
|
+
}, [workspaceMetrics]);
|
|
60292
60633
|
const trendGroups = useMemo(() => {
|
|
60293
60634
|
const lineMetricsRows = lineMetrics || [];
|
|
60294
60635
|
if (!lineMetricsRows.length) return null;
|
|
@@ -60729,13 +61070,13 @@ function HomeView({
|
|
|
60729
61070
|
dashboard_surface: "monitor"
|
|
60730
61071
|
});
|
|
60731
61072
|
}, []);
|
|
60732
|
-
|
|
60733
|
-
|
|
60734
|
-
|
|
60735
|
-
|
|
60736
|
-
setErrorMessage(null);
|
|
61073
|
+
const metricsErrorMessage = metricsError?.message || null;
|
|
61074
|
+
const handleRetryDashboardData = useCallback(async () => {
|
|
61075
|
+
if (isRecoveringSession) {
|
|
61076
|
+
await retrySessionHydration();
|
|
60737
61077
|
}
|
|
60738
|
-
|
|
61078
|
+
refetchMetrics();
|
|
61079
|
+
}, [isRecoveringSession, refetchMetrics, retrySessionHydration]);
|
|
60739
61080
|
const getTrackedLineScope = useCallback((lineIdsForScope) => {
|
|
60740
61081
|
if (isAllLinesSelection(lineIdsForScope)) {
|
|
60741
61082
|
return factoryViewId;
|
|
@@ -60793,7 +61134,7 @@ function HomeView({
|
|
|
60793
61134
|
}
|
|
60794
61135
|
}, [metricsLoading, isChangingFilter]);
|
|
60795
61136
|
useEffect(() => {
|
|
60796
|
-
if (!metricsLoading && !hasInitialDataLoaded) {
|
|
61137
|
+
if (shouldEnableMetricsFetch && !metricsLoading && !metricsError && !hasInitialDataLoaded) {
|
|
60797
61138
|
setHasInitialDataLoaded(true);
|
|
60798
61139
|
trackCoreEvent("monitor page loaded", {
|
|
60799
61140
|
default_line_id: defaultLineId,
|
|
@@ -60802,7 +61143,7 @@ function HomeView({
|
|
|
60802
61143
|
dashboard_surface: "monitor"
|
|
60803
61144
|
});
|
|
60804
61145
|
}
|
|
60805
|
-
}, [metricsLoading, hasInitialDataLoaded, defaultLineId, factoryViewId, isSupervisor]);
|
|
61146
|
+
}, [shouldEnableMetricsFetch, metricsLoading, metricsError, hasInitialDataLoaded, defaultLineId, factoryViewId, isSupervisor]);
|
|
60806
61147
|
const lineTitle = useMemo(() => {
|
|
60807
61148
|
return factoryName;
|
|
60808
61149
|
}, [factoryName]);
|
|
@@ -60952,8 +61293,9 @@ function HomeView({
|
|
|
60952
61293
|
}, [isLoading, minDuration]);
|
|
60953
61294
|
return showLoading;
|
|
60954
61295
|
};
|
|
60955
|
-
const
|
|
60956
|
-
const
|
|
61296
|
+
const isAuthBootstrapping = authStatus === "loading";
|
|
61297
|
+
const isInitialLoading = !isHydrated || !hasInitialDataLoaded && (isAuthBootstrapping || shouldEnableMetricsFetch && metricsLoading);
|
|
61298
|
+
const isDataLoading = metricsLoading;
|
|
60957
61299
|
const hasKpiDataReady = useMemo(() => {
|
|
60958
61300
|
const lineMetricsRows = lineMetrics || [];
|
|
60959
61301
|
if (selectedLineIds.length > 1) {
|
|
@@ -60962,6 +61304,10 @@ function HomeView({
|
|
|
60962
61304
|
return lineMetricsRows.some((row) => row?.line_id === primarySelectedLineId);
|
|
60963
61305
|
}, [lineMetrics, primarySelectedLineId, selectedLineIdSet, selectedLineIds.length]);
|
|
60964
61306
|
const isKpiLoading = !hasKpiDataReady;
|
|
61307
|
+
const shouldShowReconnectScreen = !hasInitialDataLoaded && (isRecoveringSession || !shouldEnableMetricsFetch && authStatus !== "failed" || !!metricsErrorMessage && authStatus !== "failed");
|
|
61308
|
+
const shouldShowFatalLoadFailure = !hasInitialDataLoaded && !!metricsErrorMessage && authStatus === "failed";
|
|
61309
|
+
const shouldShowRecoveryBanner = hasInitialDataLoaded && (isRecoveringSession || !!metricsErrorMessage);
|
|
61310
|
+
const recoveryBannerMessage = isRecoveringSession ? "Reconnecting to the dashboard. Showing the last good data while auth recovers." : metricsErrorMessage ? "Live data refresh failed. Showing the last good dashboard snapshot." : null;
|
|
60965
61311
|
useEffect(() => {
|
|
60966
61312
|
const minLoadingDurationMs = 250;
|
|
60967
61313
|
if (isDataLoading) {
|
|
@@ -61001,14 +61347,41 @@ function HomeView({
|
|
|
61001
61347
|
if (isInitialLoading) {
|
|
61002
61348
|
return /* @__PURE__ */ jsx(LoadingPageCmp, { message: "Loading Dashboard..." });
|
|
61003
61349
|
}
|
|
61004
|
-
if (
|
|
61005
|
-
return /* @__PURE__ */ jsx("div", { className: "flex h-screen items-center justify-center
|
|
61006
|
-
/* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-6 w-6", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "
|
|
61007
|
-
/* @__PURE__ */
|
|
61008
|
-
|
|
61009
|
-
|
|
61010
|
-
|
|
61011
|
-
|
|
61350
|
+
if (shouldShowReconnectScreen) {
|
|
61351
|
+
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: [
|
|
61352
|
+
/* @__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" }) }) }),
|
|
61353
|
+
/* @__PURE__ */ jsx("h2", { className: "mt-4 text-lg font-semibold text-slate-900", children: "Reconnecting to Optifye" }),
|
|
61354
|
+
/* @__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." }),
|
|
61355
|
+
/* @__PURE__ */ jsx(
|
|
61356
|
+
"button",
|
|
61357
|
+
{
|
|
61358
|
+
type: "button",
|
|
61359
|
+
onClick: () => {
|
|
61360
|
+
void handleRetryDashboardData();
|
|
61361
|
+
},
|
|
61362
|
+
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",
|
|
61363
|
+
children: "Retry Now"
|
|
61364
|
+
}
|
|
61365
|
+
)
|
|
61366
|
+
] }) });
|
|
61367
|
+
}
|
|
61368
|
+
if (shouldShowFatalLoadFailure) {
|
|
61369
|
+
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: [
|
|
61370
|
+
/* @__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" }) }) }),
|
|
61371
|
+
/* @__PURE__ */ jsx("h2", { className: "mt-4 text-lg font-semibold text-slate-900", children: "Unable to load the dashboard" }),
|
|
61372
|
+
/* @__PURE__ */ jsx("p", { className: "mt-2 text-sm text-slate-600", children: metricsErrorMessage }),
|
|
61373
|
+
/* @__PURE__ */ jsx(
|
|
61374
|
+
"button",
|
|
61375
|
+
{
|
|
61376
|
+
type: "button",
|
|
61377
|
+
onClick: () => {
|
|
61378
|
+
void handleRetryDashboardData();
|
|
61379
|
+
},
|
|
61380
|
+
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",
|
|
61381
|
+
children: "Retry Now"
|
|
61382
|
+
}
|
|
61383
|
+
)
|
|
61384
|
+
] }) });
|
|
61012
61385
|
}
|
|
61013
61386
|
return /* @__PURE__ */ jsx(
|
|
61014
61387
|
motion.div,
|
|
@@ -61027,6 +61400,20 @@ function HomeView({
|
|
|
61027
61400
|
headerControls: kpiSectionControl
|
|
61028
61401
|
}
|
|
61029
61402
|
) }) }),
|
|
61403
|
+
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: [
|
|
61404
|
+
/* @__PURE__ */ jsx("span", { children: recoveryBannerMessage }),
|
|
61405
|
+
/* @__PURE__ */ jsx(
|
|
61406
|
+
"button",
|
|
61407
|
+
{
|
|
61408
|
+
type: "button",
|
|
61409
|
+
onClick: () => {
|
|
61410
|
+
void handleRetryDashboardData();
|
|
61411
|
+
},
|
|
61412
|
+
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",
|
|
61413
|
+
children: "Retry"
|
|
61414
|
+
}
|
|
61415
|
+
)
|
|
61416
|
+
] }) }) : null,
|
|
61030
61417
|
/* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto sm:overflow-hidden relative flex flex-col", children: /* @__PURE__ */ jsx("div", { className: "flex-1 min-h-[calc(100vh-100px)] sm:min-h-0", children: workspaceMetricsWithBreakState.length > 0 ? /* @__PURE__ */ jsx(
|
|
61031
61418
|
motion.div,
|
|
61032
61419
|
{
|
|
@@ -61034,7 +61421,7 @@ function HomeView({
|
|
|
61034
61421
|
animate: { opacity: 1, scale: 1 },
|
|
61035
61422
|
transition: { duration: 0.3 },
|
|
61036
61423
|
className: "h-full",
|
|
61037
|
-
children:
|
|
61424
|
+
children: React143__default.createElement(WorkspaceGrid, {
|
|
61038
61425
|
workspaces: workspaceMetricsWithBreakState,
|
|
61039
61426
|
lineNames: mergedLineNames,
|
|
61040
61427
|
lineOrder: selectedLineIds,
|
|
@@ -61043,7 +61430,7 @@ function HomeView({
|
|
|
61043
61430
|
videoSources,
|
|
61044
61431
|
videoStreamsByWorkspaceId,
|
|
61045
61432
|
videoStreamsLoading,
|
|
61046
|
-
displayNames:
|
|
61433
|
+
displayNames: metricsDisplayNames,
|
|
61047
61434
|
hasFlowBuffers,
|
|
61048
61435
|
className: "h-full",
|
|
61049
61436
|
toolbarRightContent: lineSelectorComponent,
|
|
@@ -61067,7 +61454,7 @@ function HomeView({
|
|
|
61067
61454
|
animate: { opacity: 1, scale: 1 },
|
|
61068
61455
|
transition: { duration: 0.3 },
|
|
61069
61456
|
className: "h-full",
|
|
61070
|
-
children:
|
|
61457
|
+
children: React143__default.createElement(WorkspaceGrid, {
|
|
61071
61458
|
workspaces: [],
|
|
61072
61459
|
// Show empty grid while loading
|
|
61073
61460
|
lineNames: mergedLineNames,
|
|
@@ -61077,7 +61464,7 @@ function HomeView({
|
|
|
61077
61464
|
videoSources,
|
|
61078
61465
|
videoStreamsByWorkspaceId,
|
|
61079
61466
|
videoStreamsLoading,
|
|
61080
|
-
displayNames:
|
|
61467
|
+
displayNames: metricsDisplayNames,
|
|
61081
61468
|
hasFlowBuffers,
|
|
61082
61469
|
className: "h-full",
|
|
61083
61470
|
toolbarRightContent: lineSelectorComponent,
|
|
@@ -61135,7 +61522,7 @@ function HomeView({
|
|
|
61135
61522
|
}
|
|
61136
61523
|
);
|
|
61137
61524
|
}
|
|
61138
|
-
var AuthenticatedHomeView = withAuth(
|
|
61525
|
+
var AuthenticatedHomeView = withAuth(React143__default.memo(HomeView));
|
|
61139
61526
|
var HomeView_default = HomeView;
|
|
61140
61527
|
function withWorkspaceDisplayNames(Component3, options = {}) {
|
|
61141
61528
|
const {
|
|
@@ -61333,6 +61720,7 @@ var buildLineInfoSnapshot = (lineDetails, metrics2) => {
|
|
|
61333
61720
|
shift_id: metrics2.shift_id ?? 0,
|
|
61334
61721
|
date: metrics2.date || "",
|
|
61335
61722
|
monitoring_mode: lineDetails.monitoring_mode ?? void 0,
|
|
61723
|
+
assembly: lineDetails.assembly ?? null,
|
|
61336
61724
|
metrics: {
|
|
61337
61725
|
avg_efficiency: metrics2.avg_efficiency ?? 0,
|
|
61338
61726
|
avg_cycle_time: metrics2.avg_cycle_time ?? 0,
|
|
@@ -61365,6 +61753,7 @@ var transformWorkspaceMetrics = (workspaceData, lineId, companyId, queryDate, qu
|
|
|
61365
61753
|
pph: item.avg_pph || 0,
|
|
61366
61754
|
performance_score: item.performance_score || 0,
|
|
61367
61755
|
avg_cycle_time: item.avg_cycle_time || 0,
|
|
61756
|
+
ideal_cycle_time: item.ideal_cycle_time ?? void 0,
|
|
61368
61757
|
trend: item.trend_score === 1 ? 2 : 0,
|
|
61369
61758
|
predicted_output: item.ideal_output || 0,
|
|
61370
61759
|
efficiency: item.efficiency || 0,
|
|
@@ -61400,7 +61789,8 @@ var transformLineDetails = (lineId, detailResponse) => {
|
|
|
61400
61789
|
id: detailResponse.line_details.factory_id || "",
|
|
61401
61790
|
factory_name: detailResponse.line_details.factory_name || ""
|
|
61402
61791
|
},
|
|
61403
|
-
monitoring_mode: detailResponse.line_details.monitoring_mode ?? void 0
|
|
61792
|
+
monitoring_mode: detailResponse.line_details.monitoring_mode ?? void 0,
|
|
61793
|
+
assembly: detailResponse.line_details.assembly ?? null
|
|
61404
61794
|
};
|
|
61405
61795
|
};
|
|
61406
61796
|
var transformLineMetrics = (lineId, detailResponse, queryDate, queryShiftId) => {
|
|
@@ -61801,6 +62191,21 @@ function useEfficiencyLegend(companyId) {
|
|
|
61801
62191
|
refetch: fetchLegend
|
|
61802
62192
|
};
|
|
61803
62193
|
}
|
|
62194
|
+
|
|
62195
|
+
// src/lib/utils/kpiPoorestPerformers.ts
|
|
62196
|
+
var getWorstAssemblyCycleTimeWorkspaces = (workspaces, limit = 5) => {
|
|
62197
|
+
return workspaces.map((workspace, index) => ({
|
|
62198
|
+
workspace,
|
|
62199
|
+
index,
|
|
62200
|
+
cycleRatio: getCycleRatio(workspace)
|
|
62201
|
+
})).sort((a, b) => {
|
|
62202
|
+
if (a.cycleRatio === null && b.cycleRatio === null) return a.index - b.index;
|
|
62203
|
+
if (a.cycleRatio === null) return 1;
|
|
62204
|
+
if (b.cycleRatio === null) return -1;
|
|
62205
|
+
if (a.cycleRatio !== b.cycleRatio) return a.cycleRatio - b.cycleRatio;
|
|
62206
|
+
return a.index - b.index;
|
|
62207
|
+
}).slice(0, limit).map(({ workspace }) => workspace);
|
|
62208
|
+
};
|
|
61804
62209
|
var WEEKDAYS4 = ["S", "M", "T", "W", "T", "F", "S"];
|
|
61805
62210
|
var MonthlyRangeFilter = ({
|
|
61806
62211
|
month,
|
|
@@ -62400,7 +62805,13 @@ var BottomSection = memo$1(({
|
|
|
62400
62805
|
}) => {
|
|
62401
62806
|
const navigation = useNavigation();
|
|
62402
62807
|
const handleNavigate = navigate || navigation.navigate;
|
|
62808
|
+
const isAssemblyLine = (lineInfo.assembly === true || workspaceData.some((workspace) => workspace.assembly_enabled)) && lineInfo.monitoring_mode !== "uptime";
|
|
62809
|
+
const assemblyRows = useMemo(
|
|
62810
|
+
() => isAssemblyLine ? getWorstAssemblyCycleTimeWorkspaces(workspaceData) : [],
|
|
62811
|
+
[isAssemblyLine, workspaceData]
|
|
62812
|
+
);
|
|
62403
62813
|
const handleWorkspaceClick = useCallback((ws, index) => {
|
|
62814
|
+
const cycleRatio = getCycleRatio(ws);
|
|
62404
62815
|
trackCoreEvent("Workspace from KPI Clicked", {
|
|
62405
62816
|
workspace_name: ws.workspace_name,
|
|
62406
62817
|
workspace_id: ws.workspace_uuid,
|
|
@@ -62409,9 +62820,13 @@ var BottomSection = memo$1(({
|
|
|
62409
62820
|
efficiency: ws.efficiency,
|
|
62410
62821
|
action_count: ws.action_count,
|
|
62411
62822
|
action_threshold: ws.action_threshold,
|
|
62823
|
+
avg_cycle_time: ws.avg_cycle_time ?? null,
|
|
62824
|
+
ideal_cycle_time: ws.ideal_cycle_time ?? null,
|
|
62825
|
+
cycle_ratio: cycleRatio,
|
|
62826
|
+
ranking_metric: isAssemblyLine ? "cycle_time" : "efficiency",
|
|
62412
62827
|
section: "Poorest Performing Workspaces"
|
|
62413
62828
|
});
|
|
62414
|
-
}, [workspaceData.length]);
|
|
62829
|
+
}, [isAssemblyLine, workspaceData.length]);
|
|
62415
62830
|
return /* @__PURE__ */ jsxs(
|
|
62416
62831
|
motion.div,
|
|
62417
62832
|
{
|
|
@@ -62433,14 +62848,42 @@ var BottomSection = memo$1(({
|
|
|
62433
62848
|
)
|
|
62434
62849
|
] }),
|
|
62435
62850
|
/* @__PURE__ */ jsxs("div", { className: "divide-y overflow-auto flex-1 pr-1 sm:pr-2", children: [
|
|
62436
|
-
/* @__PURE__ */
|
|
62851
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-between pb-2", children: isAssemblyLine ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
62852
|
+
/* @__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" }),
|
|
62853
|
+
/* @__PURE__ */ jsx("div", { className: "text-xs md:text-sm font-medium text-gray-500 pr-1 sm:pr-2", children: "Cycle Time" })
|
|
62854
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
62437
62855
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 sm:gap-3 md:gap-6", children: [
|
|
62438
62856
|
/* @__PURE__ */ jsx("div", { className: "font-medium text-gray-500 min-w-[80px] sm:min-w-[100px] md:min-w-[120px] text-xs sm:text-sm md:text-base", children: "Workspace" }),
|
|
62439
62857
|
/* @__PURE__ */ jsx("div", { className: "text-xs md:text-sm font-medium text-gray-500", children: "Current/Ideal" })
|
|
62440
62858
|
] }),
|
|
62441
62859
|
/* @__PURE__ */ jsx("div", { className: "text-xs md:text-sm font-medium text-gray-500 pr-1 sm:pr-2", children: "Efficiency" })
|
|
62442
|
-
] }),
|
|
62443
|
-
|
|
62860
|
+
] }) }),
|
|
62861
|
+
isAssemblyLine ? assemblyRows.map((ws, index) => {
|
|
62862
|
+
if (!ws.workspace_uuid) {
|
|
62863
|
+
return null;
|
|
62864
|
+
}
|
|
62865
|
+
const clickHandler = () => handleWorkspaceClick(ws, index);
|
|
62866
|
+
const displayName = workspaceDisplayNames && workspaceDisplayNames[ws.workspace_name] || getWorkspaceDisplayName(ws.workspace_name, lineId);
|
|
62867
|
+
const navParams = getWorkspaceNavigationParams(ws.workspace_uuid, displayName, lineId);
|
|
62868
|
+
const dateShiftParams = urlDate ? `&date=${urlDate}&shift=${urlShift || "0"}` : "";
|
|
62869
|
+
const returnToParam = `&returnTo=${encodeURIComponent(`/kpis/${lineInfo?.line_id}`)}`;
|
|
62870
|
+
const fullUrl = `/workspace/${ws.workspace_uuid}${navParams}${dateShiftParams}${returnToParam}`;
|
|
62871
|
+
return /* @__PURE__ */ jsx(
|
|
62872
|
+
"div",
|
|
62873
|
+
{
|
|
62874
|
+
onClick: () => {
|
|
62875
|
+
clickHandler();
|
|
62876
|
+
handleNavigate && handleNavigate(fullUrl);
|
|
62877
|
+
},
|
|
62878
|
+
className: "block py-2 sm:py-3 hover:bg-gray-50 transition-colors rounded-lg cursor-pointer",
|
|
62879
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3", children: [
|
|
62880
|
+
/* @__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 }) }),
|
|
62881
|
+
/* @__PURE__ */ jsx("div", { className: "shrink-0 text-xs md:text-sm", children: /* @__PURE__ */ jsx(CycleTimeComparison, { workspace: ws }) })
|
|
62882
|
+
] })
|
|
62883
|
+
},
|
|
62884
|
+
ws.workspace_uuid
|
|
62885
|
+
);
|
|
62886
|
+
}) : lineInfo.metrics.poorest_performing_workspaces && lineInfo.metrics.poorest_performing_workspaces.length > 0 ? lineInfo.metrics.poorest_performing_workspaces.map((ws, index) => {
|
|
62444
62887
|
const wsMetrics = workspaceData.find((w) => w.workspace_name === ws.workspace_name);
|
|
62445
62888
|
const wsUuid = wsMetrics?.workspace_uuid;
|
|
62446
62889
|
if (!wsUuid) {
|
|
@@ -62536,10 +62979,63 @@ var BottomSection = memo$1(({
|
|
|
62536
62979
|
const prevPoorest = prevProps.lineInfo.metrics.poorest_performing_workspaces || [];
|
|
62537
62980
|
const nextPoorest = nextProps.lineInfo.metrics.poorest_performing_workspaces || [];
|
|
62538
62981
|
if (prevPoorest.length !== nextPoorest.length) return false;
|
|
62982
|
+
const prevPoorestSignature = JSON.stringify(prevPoorest);
|
|
62983
|
+
const nextPoorestSignature = JSON.stringify(nextPoorest);
|
|
62984
|
+
if (prevPoorestSignature !== nextPoorestSignature) return false;
|
|
62985
|
+
if (prevProps.lineInfo.assembly !== nextProps.lineInfo.assembly) return false;
|
|
62986
|
+
if (prevProps.lineInfo.monitoring_mode !== nextProps.lineInfo.monitoring_mode) return false;
|
|
62539
62987
|
if (prevProps.hourlyOutputData.length !== nextProps.hourlyOutputData.length) return false;
|
|
62540
62988
|
const hourlyDataChanged = prevProps.hourlyOutputData.some((value, index) => value !== nextProps.hourlyOutputData[index]);
|
|
62541
62989
|
if (hourlyDataChanged) return false;
|
|
62542
62990
|
if (prevProps.sortedByEfficiency.length !== nextProps.sortedByEfficiency.length) return false;
|
|
62991
|
+
const prevSortedSignature = JSON.stringify(
|
|
62992
|
+
prevProps.sortedByEfficiency.map((workspace) => ({
|
|
62993
|
+
workspace_uuid: workspace.workspace_uuid,
|
|
62994
|
+
workspace_name: workspace.workspace_name,
|
|
62995
|
+
efficiency: workspace.efficiency,
|
|
62996
|
+
action_count: workspace.action_count,
|
|
62997
|
+
predicted_output: workspace.predicted_output,
|
|
62998
|
+
avg_cycle_time: workspace.avg_cycle_time,
|
|
62999
|
+
ideal_cycle_time: workspace.ideal_cycle_time ?? null
|
|
63000
|
+
}))
|
|
63001
|
+
);
|
|
63002
|
+
const nextSortedSignature = JSON.stringify(
|
|
63003
|
+
nextProps.sortedByEfficiency.map((workspace) => ({
|
|
63004
|
+
workspace_uuid: workspace.workspace_uuid,
|
|
63005
|
+
workspace_name: workspace.workspace_name,
|
|
63006
|
+
efficiency: workspace.efficiency,
|
|
63007
|
+
action_count: workspace.action_count,
|
|
63008
|
+
predicted_output: workspace.predicted_output,
|
|
63009
|
+
avg_cycle_time: workspace.avg_cycle_time,
|
|
63010
|
+
ideal_cycle_time: workspace.ideal_cycle_time ?? null
|
|
63011
|
+
}))
|
|
63012
|
+
);
|
|
63013
|
+
if (prevSortedSignature !== nextSortedSignature) return false;
|
|
63014
|
+
const prevWorkspaceSignature = JSON.stringify(
|
|
63015
|
+
prevProps.workspaceData.map((workspace) => ({
|
|
63016
|
+
workspace_uuid: workspace.workspace_uuid,
|
|
63017
|
+
workspace_name: workspace.workspace_name,
|
|
63018
|
+
efficiency: workspace.efficiency,
|
|
63019
|
+
action_count: workspace.action_count,
|
|
63020
|
+
action_threshold: workspace.action_threshold,
|
|
63021
|
+
predicted_output: workspace.predicted_output,
|
|
63022
|
+
avg_cycle_time: workspace.avg_cycle_time,
|
|
63023
|
+
ideal_cycle_time: workspace.ideal_cycle_time ?? null
|
|
63024
|
+
}))
|
|
63025
|
+
);
|
|
63026
|
+
const nextWorkspaceSignature = JSON.stringify(
|
|
63027
|
+
nextProps.workspaceData.map((workspace) => ({
|
|
63028
|
+
workspace_uuid: workspace.workspace_uuid,
|
|
63029
|
+
workspace_name: workspace.workspace_name,
|
|
63030
|
+
efficiency: workspace.efficiency,
|
|
63031
|
+
action_count: workspace.action_count,
|
|
63032
|
+
action_threshold: workspace.action_threshold,
|
|
63033
|
+
predicted_output: workspace.predicted_output,
|
|
63034
|
+
avg_cycle_time: workspace.avg_cycle_time,
|
|
63035
|
+
ideal_cycle_time: workspace.ideal_cycle_time ?? null
|
|
63036
|
+
}))
|
|
63037
|
+
);
|
|
63038
|
+
if (prevWorkspaceSignature !== nextWorkspaceSignature) return false;
|
|
62543
63039
|
if (prevProps.lineInfo.metrics.shift_start !== nextProps.lineInfo.metrics.shift_start) return false;
|
|
62544
63040
|
if (prevProps.hourlyThreshold !== nextProps.hourlyThreshold) return false;
|
|
62545
63041
|
if (prevProps.urlDate !== nextProps.urlDate || prevProps.urlShift !== nextProps.urlShift) return false;
|
|
@@ -62883,27 +63379,33 @@ var KPIDetailView = ({
|
|
|
62883
63379
|
error: idleTimeError
|
|
62884
63380
|
}), [idleTimeRawData, idleTimeChartData, idleTimeLoading, idleTimeError]);
|
|
62885
63381
|
useEffect(() => {
|
|
62886
|
-
if (activeTab === "monthly_history" && lineId) {
|
|
63382
|
+
if (activeTab === "monthly_history" && lineId && lineDetails) {
|
|
62887
63383
|
if (!supabase || !dashboardConfig || !dashboardConfig.supabaseUrl || !dashboardConfig.supabaseKey) {
|
|
62888
63384
|
console.error("Supabase client or required config not available in KPIsPage for monthly data");
|
|
62889
63385
|
return;
|
|
62890
63386
|
}
|
|
62891
63387
|
setMonthlyDataLoading(true);
|
|
63388
|
+
const monthlyShiftIds = shiftConfig?.shifts?.map((s) => s.shiftId);
|
|
63389
|
+
const monthlyHistoryAssemblyMode = lineDetails.assembly === true && !isUptimeMode;
|
|
63390
|
+
const underperformingPromise = monthlyHistoryAssemblyMode ? dashboardService.getAssemblyMonthlyPoorestPerformers(lineId, currentMonth, currentYear, {
|
|
63391
|
+
startDate: isFullRange ? void 0 : range.startKey,
|
|
63392
|
+
endDate: isFullRange ? void 0 : range.endKey,
|
|
63393
|
+
shiftIds: monthlyShiftIds
|
|
63394
|
+
}) : dashboardService.getUnderperformingWorkspaces(
|
|
63395
|
+
lineId,
|
|
63396
|
+
currentMonth,
|
|
63397
|
+
currentYear,
|
|
63398
|
+
monthlyShiftIds,
|
|
63399
|
+
isFullRange ? void 0 : range.startKey,
|
|
63400
|
+
isFullRange ? void 0 : range.endKey
|
|
63401
|
+
);
|
|
62892
63402
|
Promise.all([
|
|
62893
63403
|
dashboardService.getLineMonthlyData(lineId, currentMonth, currentYear, {
|
|
62894
63404
|
startDate: isFullRange ? void 0 : range.startKey,
|
|
62895
63405
|
endDate: isFullRange ? void 0 : range.endKey,
|
|
62896
|
-
shiftIds:
|
|
63406
|
+
shiftIds: monthlyShiftIds
|
|
62897
63407
|
}),
|
|
62898
|
-
|
|
62899
|
-
lineId,
|
|
62900
|
-
currentMonth,
|
|
62901
|
-
currentYear,
|
|
62902
|
-
shiftConfig?.shifts?.map((s) => s.shiftId),
|
|
62903
|
-
// Pass dynamic shift IDs
|
|
62904
|
-
isFullRange ? void 0 : range.startKey,
|
|
62905
|
-
isFullRange ? void 0 : range.endKey
|
|
62906
|
-
)
|
|
63408
|
+
underperformingPromise
|
|
62907
63409
|
]).then(([monthlyMetrics, underperformingData]) => {
|
|
62908
63410
|
console.log("Fetched monthly metrics data:", monthlyMetrics);
|
|
62909
63411
|
const dayDataMap = /* @__PURE__ */ new Map();
|
|
@@ -62967,11 +63469,17 @@ var KPIDetailView = ({
|
|
|
62967
63469
|
const mapWorkspaces = (workspaces2) => (workspaces2 || []).map((ws) => ({
|
|
62968
63470
|
workspace_name: ws.workspace_name || "Unknown Workspace",
|
|
62969
63471
|
workspace_uuid: ws.workspace_uuid || ws.workspace_name || `unknown-${Math.random()}`,
|
|
62970
|
-
avg_efficiency: ws.avg_efficiency
|
|
63472
|
+
avg_efficiency: ws.avg_efficiency ?? 0,
|
|
63473
|
+
avg_cycle_time: ws.avg_cycle_time ?? null,
|
|
63474
|
+
ideal_cycle_time: ws.ideal_cycle_time ?? null,
|
|
63475
|
+
cycle_ratio: ws.cycle_ratio ?? null,
|
|
63476
|
+
metric_mode: ws.metric_mode ?? "efficiency",
|
|
62971
63477
|
last_5_days: (ws.last_5_days || []).map((day) => ({
|
|
62972
63478
|
date: day.date,
|
|
62973
63479
|
efficiency: day.efficiency ?? 0,
|
|
62974
|
-
performance_score: day.performance_score
|
|
63480
|
+
performance_score: day.performance_score,
|
|
63481
|
+
avg_cycle_time: day.avg_cycle_time ?? null,
|
|
63482
|
+
ideal_cycle_time: day.ideal_cycle_time ?? null
|
|
62975
63483
|
}))
|
|
62976
63484
|
}));
|
|
62977
63485
|
const mappedData = {};
|
|
@@ -62996,7 +63504,7 @@ var KPIDetailView = ({
|
|
|
62996
63504
|
setMonthlyDataLoading(false);
|
|
62997
63505
|
});
|
|
62998
63506
|
}
|
|
62999
|
-
}, [activeTab, lineId, currentMonth, currentYear, supabase, dashboardConfig, shiftConfig, range.startKey, range.endKey, isFullRange, configuredTimezone, isUptimeMode, resolveShiftTimes]);
|
|
63507
|
+
}, [activeTab, lineId, lineDetails, currentMonth, currentYear, supabase, dashboardConfig, shiftConfig, range.startKey, range.endKey, isFullRange, configuredTimezone, isUptimeMode, resolveShiftTimes]);
|
|
63000
63508
|
const analysisMonthlyData = useMemo(() => {
|
|
63001
63509
|
return filterDataByDateKeyRange(monthlyData, range);
|
|
63002
63510
|
}, [monthlyData, range]);
|
|
@@ -63014,6 +63522,7 @@ var KPIDetailView = ({
|
|
|
63014
63522
|
shift_id: metrics2.shift_id ?? 0,
|
|
63015
63523
|
date: metrics2.date || getOperationalDate(timezone || "UTC"),
|
|
63016
63524
|
monitoring_mode: lineDetails.monitoring_mode ?? void 0,
|
|
63525
|
+
assembly: lineDetails.assembly ?? null,
|
|
63017
63526
|
metrics: {
|
|
63018
63527
|
avg_efficiency: metrics2.avg_efficiency ?? 0,
|
|
63019
63528
|
avg_cycle_time: metrics2.avg_cycle_time ?? 0,
|
|
@@ -63901,6 +64410,7 @@ var KPIDetailView = ({
|
|
|
63901
64410
|
timezone: configuredTimezone,
|
|
63902
64411
|
legend: efficiencyLegend,
|
|
63903
64412
|
monitoringMode: resolvedMonitoringMode,
|
|
64413
|
+
lineAssembly: resolvedLineInfo?.assembly === true,
|
|
63904
64414
|
shiftConfig,
|
|
63905
64415
|
selectedShiftId,
|
|
63906
64416
|
onShiftChange: setSelectedShiftId,
|
|
@@ -64105,18 +64615,18 @@ var LinesLeaderboard = ({
|
|
|
64105
64615
|
isHistoricalDaily
|
|
64106
64616
|
}) => {
|
|
64107
64617
|
const formatEfficiency = (value) => typeof value === "number" && Number.isFinite(value) ? `${value.toFixed(1)}%` : "--";
|
|
64108
|
-
const assignedLineIdSet =
|
|
64618
|
+
const assignedLineIdSet = React143__default.useMemo(
|
|
64109
64619
|
() => new Set(assignedLineIds || []),
|
|
64110
64620
|
[assignedLineIds]
|
|
64111
64621
|
);
|
|
64112
|
-
const canClickLine =
|
|
64622
|
+
const canClickLine = React143__default.useCallback(
|
|
64113
64623
|
(lineId) => {
|
|
64114
64624
|
if (!assignedLineIds) return true;
|
|
64115
64625
|
return assignedLineIdSet.has(lineId);
|
|
64116
64626
|
},
|
|
64117
64627
|
[assignedLineIds, assignedLineIdSet]
|
|
64118
64628
|
);
|
|
64119
|
-
const handleTimeRangeChange =
|
|
64629
|
+
const handleTimeRangeChange = React143__default.useCallback((newRange) => {
|
|
64120
64630
|
if (newRange === timeRange) return;
|
|
64121
64631
|
trackCoreEvent("Leaderboard Time Range Changed", {
|
|
64122
64632
|
from_range: timeRange,
|
|
@@ -64127,7 +64637,7 @@ var LinesLeaderboard = ({
|
|
|
64127
64637
|
});
|
|
64128
64638
|
setTimeRange(newRange);
|
|
64129
64639
|
}, [timeRange, lines.length, monthlyEfficiencyByLineId, setTimeRange]);
|
|
64130
|
-
const handleLeaderboardLineClick =
|
|
64640
|
+
const handleLeaderboardLineClick = React143__default.useCallback((item, clickSource) => {
|
|
64131
64641
|
if (!canClickLine(item.line.id)) return;
|
|
64132
64642
|
trackCoreEvent("Leaderboard Line Clicked", {
|
|
64133
64643
|
line_id: item.line.id,
|
|
@@ -64141,8 +64651,8 @@ var LinesLeaderboard = ({
|
|
|
64141
64651
|
});
|
|
64142
64652
|
onLineClick(item.line);
|
|
64143
64653
|
}, [canClickLine, onLineClick, timeRange]);
|
|
64144
|
-
const viewLoadedTrackedRef =
|
|
64145
|
-
const leaderboardData =
|
|
64654
|
+
const viewLoadedTrackedRef = React143__default.useRef(null);
|
|
64655
|
+
const leaderboardData = React143__default.useMemo(() => {
|
|
64146
64656
|
const loading = timeRange === "today" ? isLoadingToday : isLoadingMonthly;
|
|
64147
64657
|
const efficiencyMap = timeRange === "today" ? todayEfficiencyByLineId : monthlyEfficiencyByLineId;
|
|
64148
64658
|
return lines.map((line) => {
|
|
@@ -64173,7 +64683,7 @@ var LinesLeaderboard = ({
|
|
|
64173
64683
|
isLoadingToday,
|
|
64174
64684
|
isLoadingMonthly
|
|
64175
64685
|
]);
|
|
64176
|
-
|
|
64686
|
+
React143__default.useEffect(() => {
|
|
64177
64687
|
const isLoading = timeRange === "today" ? isLoadingToday : isLoadingMonthly;
|
|
64178
64688
|
const trackingKey = `${timeRange}-${leaderboardData.length}`;
|
|
64179
64689
|
if (leaderboardData.length > 0 && !isLoading && viewLoadedTrackedRef.current !== trackingKey) {
|
|
@@ -64199,7 +64709,7 @@ var LinesLeaderboard = ({
|
|
|
64199
64709
|
const countdownFormat = timeRange === "monthly" ? "days" : "clock";
|
|
64200
64710
|
const countdownFinishedLabel = timeRange === "monthly" ? "Finished" : "Shift Ended";
|
|
64201
64711
|
const showCountdown = timeRange === "monthly" || !isHistoricalDaily;
|
|
64202
|
-
const handleCountdownFinished =
|
|
64712
|
+
const handleCountdownFinished = React143__default.useCallback(() => {
|
|
64203
64713
|
trackCoreEvent("Leaderboard Countdown Finished", {
|
|
64204
64714
|
countdown_type: timeRange === "monthly" ? "month_end" : "shift_end",
|
|
64205
64715
|
time_range: timeRange,
|
|
@@ -64226,7 +64736,7 @@ var LinesLeaderboard = ({
|
|
|
64226
64736
|
return "bg-white border-gray-100";
|
|
64227
64737
|
}
|
|
64228
64738
|
};
|
|
64229
|
-
|
|
64739
|
+
React143__default.useEffect(() => {
|
|
64230
64740
|
const style = document.createElement("style");
|
|
64231
64741
|
style.innerHTML = `
|
|
64232
64742
|
@keyframes float {
|
|
@@ -64413,7 +64923,7 @@ var LineCard = ({
|
|
|
64413
64923
|
supervisors
|
|
64414
64924
|
}) => {
|
|
64415
64925
|
const isUptimeLine = (line.monitoring_mode ?? "output") === "uptime";
|
|
64416
|
-
const isOnTrack =
|
|
64926
|
+
const isOnTrack = React143__default.useMemo(() => {
|
|
64417
64927
|
if (!kpis) return null;
|
|
64418
64928
|
return isEfficiencyOnTrack(kpis.efficiency.value);
|
|
64419
64929
|
}, [kpis]);
|
|
@@ -64611,46 +65121,46 @@ var KPIsOverviewView = ({
|
|
|
64611
65121
|
const configuredTimezone = dbTimezone || dateTimeConfig.defaultTimezone || "UTC";
|
|
64612
65122
|
const { startDate: monthStartDate, endDate: monthEndDateKey, monthEndDate } = getMonthDateInfo(configuredTimezone);
|
|
64613
65123
|
const isSuperAdmin = user?.scope_mode === "SUPER_ADMIN" || !!user?.access_scope?.is_super_admin;
|
|
64614
|
-
const scopedLineIds =
|
|
65124
|
+
const scopedLineIds = React143__default.useMemo(
|
|
64615
65125
|
() => Array.isArray(user?.access_scope?.line_ids) ? user.access_scope.line_ids.filter((lineId) => typeof lineId === "string" && lineId.length > 0) : [],
|
|
64616
65126
|
[user?.access_scope?.line_ids]
|
|
64617
65127
|
);
|
|
64618
65128
|
const hasCanonicalScope = !!user?.scope_mode || !!user?.access_scope;
|
|
64619
65129
|
const scopeRole = (user?.role_level || user?.role || "").toLowerCase();
|
|
64620
65130
|
const isStrictLineScopedRole = scopeRole === "supervisor" || isFactoryScopedRole(scopeRole);
|
|
64621
|
-
const resolvedAssignedLineIds =
|
|
65131
|
+
const resolvedAssignedLineIds = React143__default.useMemo(() => {
|
|
64622
65132
|
if (isSuperAdmin) return [];
|
|
64623
65133
|
if (scopedLineIds.length > 0) return scopedLineIds;
|
|
64624
65134
|
if (lineIds && lineIds.length > 0) return lineIds;
|
|
64625
65135
|
if (isStrictLineScopedRole && hasCanonicalScope) return [];
|
|
64626
65136
|
return [];
|
|
64627
65137
|
}, [isSuperAdmin, scopedLineIds, lineIds, isStrictLineScopedRole, hasCanonicalScope]);
|
|
64628
|
-
const assignedLineIdSet =
|
|
65138
|
+
const assignedLineIdSet = React143__default.useMemo(
|
|
64629
65139
|
() => new Set(resolvedAssignedLineIds),
|
|
64630
65140
|
[resolvedAssignedLineIds]
|
|
64631
65141
|
);
|
|
64632
|
-
const metricsLineIds =
|
|
65142
|
+
const metricsLineIds = React143__default.useMemo(() => {
|
|
64633
65143
|
if (isSuperAdmin) {
|
|
64634
65144
|
return lineIds ?? [];
|
|
64635
65145
|
}
|
|
64636
65146
|
return resolvedAssignedLineIds;
|
|
64637
65147
|
}, [isSuperAdmin, lineIds, resolvedAssignedLineIds]);
|
|
64638
65148
|
const assignedLineIdsForLeaderboard = isSuperAdmin ? void 0 : resolvedAssignedLineIds;
|
|
64639
|
-
const leaderboardLinesForView =
|
|
65149
|
+
const leaderboardLinesForView = React143__default.useMemo(() => {
|
|
64640
65150
|
const targetMode = viewType === "machine" ? "uptime" : "output";
|
|
64641
65151
|
return leaderboardLines.filter((line) => (line.monitoring_mode ?? "output") === targetMode);
|
|
64642
65152
|
}, [leaderboardLines, viewType]);
|
|
64643
|
-
const linesForView =
|
|
65153
|
+
const linesForView = React143__default.useMemo(() => {
|
|
64644
65154
|
const targetMode = viewType === "machine" ? "uptime" : "output";
|
|
64645
65155
|
return lines.filter((line) => (line.monitoring_mode ?? "output") === targetMode);
|
|
64646
65156
|
}, [lines, viewType]);
|
|
64647
|
-
const relevantLinesForMode =
|
|
65157
|
+
const relevantLinesForMode = React143__default.useMemo(() => {
|
|
64648
65158
|
if (activeTab === "leaderboard") {
|
|
64649
65159
|
return leaderboardLines.length > 0 ? leaderboardLines : lines;
|
|
64650
65160
|
}
|
|
64651
65161
|
return lines;
|
|
64652
65162
|
}, [activeTab, leaderboardLines, lines]);
|
|
64653
|
-
const { hasUptime, hasOutput } =
|
|
65163
|
+
const { hasUptime, hasOutput } = React143__default.useMemo(() => {
|
|
64654
65164
|
let uptime = false;
|
|
64655
65165
|
let output = false;
|
|
64656
65166
|
for (const line of relevantLinesForMode) {
|
|
@@ -64675,14 +65185,14 @@ var KPIsOverviewView = ({
|
|
|
64675
65185
|
const currentShiftDetails = getCurrentShift(configuredTimezone, shiftConfig);
|
|
64676
65186
|
const currentShiftDate = currentShiftDetails.date;
|
|
64677
65187
|
const currentShiftId = currentShiftDetails.shiftId;
|
|
64678
|
-
const activeFiltersCount =
|
|
65188
|
+
const activeFiltersCount = React143__default.useMemo(() => {
|
|
64679
65189
|
let count = 0;
|
|
64680
65190
|
if (selectedLeaderboardShiftId !== currentShiftId) {
|
|
64681
65191
|
count++;
|
|
64682
65192
|
}
|
|
64683
65193
|
return count;
|
|
64684
65194
|
}, [selectedLeaderboardShiftId, currentShiftId]);
|
|
64685
|
-
const clearFilters =
|
|
65195
|
+
const clearFilters = React143__default.useCallback(() => {
|
|
64686
65196
|
setSelectedLeaderboardShiftId(currentShiftId);
|
|
64687
65197
|
}, [currentShiftId]);
|
|
64688
65198
|
useEffect(() => {
|
|
@@ -64696,11 +65206,11 @@ var KPIsOverviewView = ({
|
|
|
64696
65206
|
document.addEventListener("mousedown", handleClickOutside);
|
|
64697
65207
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
64698
65208
|
}, []);
|
|
64699
|
-
const shiftEndDate =
|
|
65209
|
+
const shiftEndDate = React143__default.useMemo(
|
|
64700
65210
|
() => getShiftEndDate(currentShiftDetails, configuredTimezone),
|
|
64701
65211
|
[currentShiftDetails, configuredTimezone]
|
|
64702
65212
|
);
|
|
64703
|
-
const leaderboardShiftOptions =
|
|
65213
|
+
const leaderboardShiftOptions = React143__default.useMemo(() => {
|
|
64704
65214
|
if (shiftConfig?.shifts && shiftConfig.shifts.length > 0) {
|
|
64705
65215
|
return shiftConfig.shifts.map((shift) => ({
|
|
64706
65216
|
id: shift.shiftId,
|
|
@@ -64780,15 +65290,15 @@ var KPIsOverviewView = ({
|
|
|
64780
65290
|
lineId: factoryViewId,
|
|
64781
65291
|
userAccessibleLineIds: metricsLineIds
|
|
64782
65292
|
});
|
|
64783
|
-
const defaultKPIs =
|
|
64784
|
-
const kpisByLineId =
|
|
65293
|
+
const defaultKPIs = React143__default.useMemo(() => createDefaultKPIs(), []);
|
|
65294
|
+
const kpisByLineId = React143__default.useMemo(() => {
|
|
64785
65295
|
const map = /* @__PURE__ */ new Map();
|
|
64786
65296
|
lineMetrics.forEach((row) => {
|
|
64787
65297
|
if (row?.line_id) map.set(row.line_id, buildKPIsFromLineMetricsRow(row));
|
|
64788
65298
|
});
|
|
64789
65299
|
return map;
|
|
64790
65300
|
}, [lineMetrics]);
|
|
64791
|
-
const supervisorLineIds =
|
|
65301
|
+
const supervisorLineIds = React143__default.useMemo(
|
|
64792
65302
|
() => (leaderboardLines.length > 0 ? leaderboardLines : lines).map((l) => l.id),
|
|
64793
65303
|
[leaderboardLines, lines]
|
|
64794
65304
|
);
|
|
@@ -65628,39 +66138,6 @@ var KPIsOverviewView = ({
|
|
|
65628
66138
|
] });
|
|
65629
66139
|
};
|
|
65630
66140
|
var KPIsOverviewView_default = KPIsOverviewView;
|
|
65631
|
-
var toFiniteNumber = (value) => {
|
|
65632
|
-
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
65633
|
-
if (typeof value === "string" && value.trim() !== "") {
|
|
65634
|
-
const parsed = Number(value);
|
|
65635
|
-
return Number.isFinite(parsed) ? parsed : null;
|
|
65636
|
-
}
|
|
65637
|
-
return null;
|
|
65638
|
-
};
|
|
65639
|
-
var getCycleRatio = (workspace) => {
|
|
65640
|
-
const idealCycleTime = toFiniteNumber(workspace.ideal_cycle_time);
|
|
65641
|
-
const avgCycleTime = toFiniteNumber(workspace.avg_cycle_time);
|
|
65642
|
-
if (idealCycleTime === null || avgCycleTime === null || idealCycleTime <= 0 || avgCycleTime <= 0) {
|
|
65643
|
-
return null;
|
|
65644
|
-
}
|
|
65645
|
-
return idealCycleTime / avgCycleTime;
|
|
65646
|
-
};
|
|
65647
|
-
var formatCycleTimeValue = (value) => {
|
|
65648
|
-
const numericValue = toFiniteNumber(value);
|
|
65649
|
-
if (numericValue === null || numericValue <= 0) return "--";
|
|
65650
|
-
return `${numericValue.toFixed(1)}s`;
|
|
65651
|
-
};
|
|
65652
|
-
var CycleTimeComparison = memo$1(({
|
|
65653
|
-
workspace
|
|
65654
|
-
}) => {
|
|
65655
|
-
const averageValue = formatCycleTimeValue(workspace.avg_cycle_time);
|
|
65656
|
-
const standardValue = formatCycleTimeValue(workspace.ideal_cycle_time);
|
|
65657
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 tabular-nums", children: [
|
|
65658
|
-
/* @__PURE__ */ jsx("span", { className: "font-semibold text-gray-900", children: averageValue }),
|
|
65659
|
-
/* @__PURE__ */ jsx("span", { className: "text-gray-400 font-normal", children: "/" }),
|
|
65660
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium text-gray-500", children: standardValue })
|
|
65661
|
-
] });
|
|
65662
|
-
}, (prevProps, nextProps) => prevProps.workspace.avg_cycle_time === nextProps.workspace.avg_cycle_time && prevProps.workspace.ideal_cycle_time === nextProps.workspace.ideal_cycle_time);
|
|
65663
|
-
CycleTimeComparison.displayName = "CycleTimeComparison";
|
|
65664
66141
|
var IsolatedTimer = memo$1(() => {
|
|
65665
66142
|
return /* @__PURE__ */ jsx(ISTTimer_default, {});
|
|
65666
66143
|
});
|
|
@@ -65912,7 +66389,7 @@ var LeaderboardDetailView = memo$1(({
|
|
|
65912
66389
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
65913
66390
|
}, []);
|
|
65914
66391
|
const [isMobile, setIsMobile] = useState(false);
|
|
65915
|
-
|
|
66392
|
+
React143__default.useEffect(() => {
|
|
65916
66393
|
const checkMobile = () => setIsMobile(window.innerWidth < 640);
|
|
65917
66394
|
checkMobile();
|
|
65918
66395
|
window.addEventListener("resize", checkMobile);
|
|
@@ -66202,10 +66679,25 @@ var LeaderboardDetailView = memo$1(({
|
|
|
66202
66679
|
setTodayLoading(true);
|
|
66203
66680
|
setTodayError(null);
|
|
66204
66681
|
try {
|
|
66205
|
-
|
|
66682
|
+
if (!supabase) {
|
|
66683
|
+
throw new Error("Supabase client not initialized");
|
|
66684
|
+
}
|
|
66685
|
+
if (!entityConfig.companyId) {
|
|
66686
|
+
throw new Error("Company ID is not configured");
|
|
66687
|
+
}
|
|
66688
|
+
const searchParams = new URLSearchParams({
|
|
66689
|
+
company_id: entityConfig.companyId,
|
|
66206
66690
|
date: todayDate,
|
|
66207
|
-
|
|
66691
|
+
shift_id: todayShiftId.toString()
|
|
66208
66692
|
});
|
|
66693
|
+
if (configuredLineIds.length > 0) {
|
|
66694
|
+
searchParams.set("line_ids", configuredLineIds.join(","));
|
|
66695
|
+
}
|
|
66696
|
+
const metricsData = await fetchBackendJson(
|
|
66697
|
+
supabase,
|
|
66698
|
+
`/api/dashboard/metrics?${searchParams.toString()}`
|
|
66699
|
+
);
|
|
66700
|
+
const entries = metricsData.workspace_metrics || [];
|
|
66209
66701
|
if (todayRequestKeyRef.current !== requestKey) {
|
|
66210
66702
|
return;
|
|
66211
66703
|
}
|
|
@@ -66222,7 +66714,15 @@ var LeaderboardDetailView = memo$1(({
|
|
|
66222
66714
|
setTodayLoading(false);
|
|
66223
66715
|
}
|
|
66224
66716
|
}
|
|
66225
|
-
}, [
|
|
66717
|
+
}, [
|
|
66718
|
+
configuredLineIds,
|
|
66719
|
+
entityConfig.companyId,
|
|
66720
|
+
mapEntriesToWorkspaces,
|
|
66721
|
+
supabase,
|
|
66722
|
+
todayDate,
|
|
66723
|
+
todayShiftId,
|
|
66724
|
+
lineKey
|
|
66725
|
+
]);
|
|
66226
66726
|
const queueTodayLeaderboardRefresh = useCallback(() => {
|
|
66227
66727
|
if (leaderboardUpdateQueuedRef.current) return;
|
|
66228
66728
|
leaderboardUpdateQueuedRef.current = true;
|
|
@@ -68308,7 +68808,7 @@ var ShiftsView = ({
|
|
|
68308
68808
|
] })
|
|
68309
68809
|
] });
|
|
68310
68810
|
};
|
|
68311
|
-
var AuthenticatedShiftsView = withAuth(
|
|
68811
|
+
var AuthenticatedShiftsView = withAuth(React143__default.memo(ShiftsView));
|
|
68312
68812
|
var ShiftsView_default = ShiftsView;
|
|
68313
68813
|
|
|
68314
68814
|
// src/views/TargetsView.utils.ts
|
|
@@ -70010,7 +70510,7 @@ var TargetsView = ({
|
|
|
70010
70510
|
};
|
|
70011
70511
|
var TargetsViewWithDisplayNames = withAllWorkspaceDisplayNames(TargetsView);
|
|
70012
70512
|
var TargetsView_default = TargetsViewWithDisplayNames;
|
|
70013
|
-
var AuthenticatedTargetsView = withAuth(
|
|
70513
|
+
var AuthenticatedTargetsView = withAuth(React143__default.memo(TargetsViewWithDisplayNames));
|
|
70014
70514
|
function useTimezone(options = {}) {
|
|
70015
70515
|
const dashboardConfig = useDashboardConfig();
|
|
70016
70516
|
const workspaceConfig = useWorkspaceConfig();
|
|
@@ -70237,7 +70737,20 @@ var WorkspaceDetailView = ({
|
|
|
70237
70737
|
} = useCompanyFastSlowClipFiltersEnabled();
|
|
70238
70738
|
const isClipsEnabled = dashboardConfig?.clipsConfig?.enabled ?? true;
|
|
70239
70739
|
dashboardConfig?.supervisorConfig?.enabled || false;
|
|
70240
|
-
const
|
|
70740
|
+
const routedLineId = lineId || selectedLineId;
|
|
70741
|
+
const latestCachedDetailedMetrics = useMemo(() => {
|
|
70742
|
+
if (!workspaceId) {
|
|
70743
|
+
return null;
|
|
70744
|
+
}
|
|
70745
|
+
return workspaceMetricsStore.getLatestDetailed(workspaceId);
|
|
70746
|
+
}, [workspaceId]);
|
|
70747
|
+
const latestCachedOverviewMetrics = useMemo(() => {
|
|
70748
|
+
if (!workspaceId) {
|
|
70749
|
+
return null;
|
|
70750
|
+
}
|
|
70751
|
+
return workspaceMetricsStore.getLatestOverview(workspaceId);
|
|
70752
|
+
}, [workspaceId]);
|
|
70753
|
+
const effectiveLineId = routedLineId || latestCachedDetailedMetrics?.line_id || latestCachedOverviewMetrics?.line_id;
|
|
70241
70754
|
const { shiftConfig, isLoading: isShiftConfigLoading, isFromDatabase: isShiftConfigFromDatabase } = useDynamicShiftConfig(effectiveLineId);
|
|
70242
70755
|
const currentShiftDetails = useMemo(() => {
|
|
70243
70756
|
if (isShiftConfigLoading || !shiftConfig) return null;
|
|
@@ -70514,8 +71027,9 @@ var WorkspaceDetailView = ({
|
|
|
70514
71027
|
}, [cachedOverviewMetrics, shiftConfig?.shifts]);
|
|
70515
71028
|
const authoritativeCycleMetrics = isHistoricView ? historicMetrics : liveMetrics;
|
|
70516
71029
|
const workspace = authoritativeCycleMetrics || cachedDetailedMetrics || overviewFallback;
|
|
71030
|
+
const resolvedLineId = effectiveLineId || workspace?.line_id || cachedDetailedMetrics?.line_id || cachedOverviewMetrics?.line_id || overviewFallback?.line_id;
|
|
70517
71031
|
const { timezone: cycleTimeTimezone } = useTimezone({
|
|
70518
|
-
lineId:
|
|
71032
|
+
lineId: resolvedLineId || void 0,
|
|
70519
71033
|
workspaceId: workspaceId || void 0
|
|
70520
71034
|
});
|
|
70521
71035
|
const effectiveCycleTimeTimezone = cycleTimeTimezone || timezone;
|
|
@@ -70560,7 +71074,7 @@ var WorkspaceDetailView = ({
|
|
|
70560
71074
|
const error = isHistoricView ? historicError : liveError;
|
|
70561
71075
|
const monitoringMode = workspace?.monitoring_mode ?? "output";
|
|
70562
71076
|
const isUptimeMode = monitoringMode === "uptime";
|
|
70563
|
-
const idleTimeVlmEnabled = isIdleTimeVlmEnabled(
|
|
71077
|
+
const idleTimeVlmEnabled = isIdleTimeVlmEnabled(resolvedLineId);
|
|
70564
71078
|
useEffect(() => {
|
|
70565
71079
|
if (!isClipsEnabled || !dashboardConfig?.s3Config || !workspaceId) {
|
|
70566
71080
|
return;
|
|
@@ -70795,7 +71309,7 @@ var WorkspaceDetailView = ({
|
|
|
70795
71309
|
const analysisMonthlyData = useMemo(() => {
|
|
70796
71310
|
return filterDataByDateKeyRange(monthlyData, range);
|
|
70797
71311
|
}, [monthlyData, range]);
|
|
70798
|
-
const formattedWorkspaceName = displayName || formatWorkspaceName3(workspace?.workspace_name || "",
|
|
71312
|
+
const formattedWorkspaceName = displayName || formatWorkspaceName3(workspace?.workspace_name || "", resolvedLineId);
|
|
70799
71313
|
const workspaceCycleTimeEligibility = workspace ? {
|
|
70800
71314
|
line_assembly_enabled: workspace.line_assembly_enabled,
|
|
70801
71315
|
action_family: workspace.action_family,
|
|
@@ -70972,8 +71486,8 @@ var WorkspaceDetailView = ({
|
|
|
70972
71486
|
params.set("rangeStart", range.startKey);
|
|
70973
71487
|
params.set("rangeEnd", range.endKey);
|
|
70974
71488
|
}
|
|
70975
|
-
if (
|
|
70976
|
-
params.set("lineId",
|
|
71489
|
+
if (resolvedLineId) {
|
|
71490
|
+
params.set("lineId", resolvedLineId);
|
|
70977
71491
|
}
|
|
70978
71492
|
appendReturnUrl(params);
|
|
70979
71493
|
onNavigate(`/workspace/${workspaceId}?${params.toString()}`);
|
|
@@ -71002,8 +71516,8 @@ var WorkspaceDetailView = ({
|
|
|
71002
71516
|
params.set("rangeStart", range.startKey);
|
|
71003
71517
|
params.set("rangeEnd", range.endKey);
|
|
71004
71518
|
}
|
|
71005
|
-
if (
|
|
71006
|
-
params.set("lineId",
|
|
71519
|
+
if (resolvedLineId) {
|
|
71520
|
+
params.set("lineId", resolvedLineId);
|
|
71007
71521
|
}
|
|
71008
71522
|
appendReturnUrl(params);
|
|
71009
71523
|
onNavigate(`/workspace/${workspaceId}?${params.toString()}`);
|
|
@@ -71627,7 +72141,7 @@ var WorkspaceDetailView = ({
|
|
|
71627
72141
|
month: selectedMonth,
|
|
71628
72142
|
year: selectedYear,
|
|
71629
72143
|
workspaceId,
|
|
71630
|
-
lineId:
|
|
72144
|
+
lineId: resolvedLineId,
|
|
71631
72145
|
monitoringMode: workspace?.monitoring_mode,
|
|
71632
72146
|
selectedShiftId: selectedShift,
|
|
71633
72147
|
rangeStart,
|
|
@@ -71652,8 +72166,8 @@ var WorkspaceDetailView = ({
|
|
|
71652
72166
|
params.set("rangeStart", range.startKey);
|
|
71653
72167
|
params.set("rangeEnd", range.endKey);
|
|
71654
72168
|
}
|
|
71655
|
-
if (
|
|
71656
|
-
params.set("lineId",
|
|
72169
|
+
if (resolvedLineId) {
|
|
72170
|
+
params.set("lineId", resolvedLineId);
|
|
71657
72171
|
}
|
|
71658
72172
|
appendReturnUrl(params);
|
|
71659
72173
|
onNavigate(`/workspace/${workspaceId}?${params.toString()}`);
|
|
@@ -71681,7 +72195,7 @@ var WorkspaceDetailView = ({
|
|
|
71681
72195
|
workspaceId,
|
|
71682
72196
|
workspaceName: formattedWorkspaceName,
|
|
71683
72197
|
date,
|
|
71684
|
-
lineId:
|
|
72198
|
+
lineId: resolvedLineId,
|
|
71685
72199
|
shift,
|
|
71686
72200
|
totalOutput: workspace?.total_actions,
|
|
71687
72201
|
workspaceMetrics: detailedWorkspaceMetrics || void 0,
|
|
@@ -73429,7 +73943,7 @@ function BottleneckClipsView({
|
|
|
73429
73943
|
) })
|
|
73430
73944
|
] }) });
|
|
73431
73945
|
}
|
|
73432
|
-
var AuthenticatedBottleneckClipsView = withAuth(
|
|
73946
|
+
var AuthenticatedBottleneckClipsView = withAuth(React143__default.memo(BottleneckClipsView));
|
|
73433
73947
|
var BottleneckClipsView_default = BottleneckClipsView;
|
|
73434
73948
|
|
|
73435
73949
|
// src/lib/services/ticketService.ts
|
|
@@ -73459,8 +73973,8 @@ var TicketService = class {
|
|
|
73459
73973
|
return response;
|
|
73460
73974
|
} catch (error) {
|
|
73461
73975
|
lastError = error instanceof Error ? error : new Error(String(error));
|
|
73462
|
-
const
|
|
73463
|
-
if (!
|
|
73976
|
+
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");
|
|
73977
|
+
if (!isRetryableError2 || attempt === retries) {
|
|
73464
73978
|
throw lastError;
|
|
73465
73979
|
}
|
|
73466
73980
|
const delay2 = 1e3 * Math.pow(2, attempt);
|
|
@@ -73475,69 +73989,78 @@ var TicketService = class {
|
|
|
73475
73989
|
* Uses the user's JWT access token from Supabase session (NOT the anon key)
|
|
73476
73990
|
*/
|
|
73477
73991
|
async fetchWithAuth(url, options = {}) {
|
|
73478
|
-
|
|
73479
|
-
|
|
73480
|
-
|
|
73481
|
-
const { data: { session }, error: sessionError } = await this.supabaseClient.auth.getSession();
|
|
73482
|
-
if (sessionError) {
|
|
73483
|
-
console.error("Session error:", sessionError);
|
|
73484
|
-
throw new Error("Failed to get authentication session. Please log in.");
|
|
73485
|
-
}
|
|
73486
|
-
if (!session) {
|
|
73487
|
-
console.error("No session found. User must be logged in.");
|
|
73488
|
-
throw new Error("User not authenticated. Please log in.");
|
|
73489
|
-
}
|
|
73490
|
-
if (!session.access_token) {
|
|
73491
|
-
console.error("Session exists but no access_token found");
|
|
73492
|
-
throw new Error("Invalid session. Please log in again.");
|
|
73493
|
-
}
|
|
73494
|
-
const token = session.access_token;
|
|
73495
|
-
if (process.env.NODE_ENV === "development") {
|
|
73496
|
-
console.log("[TicketService] Using JWT token (first 20 chars):", token.substring(0, 20) + "...");
|
|
73497
|
-
console.log("[TicketService] Token is NOT the anon key - it is the user JWT from session.access_token");
|
|
73498
|
-
}
|
|
73499
|
-
const headers = {
|
|
73500
|
-
"Content-Type": "application/json",
|
|
73501
|
-
...options.headers,
|
|
73502
|
-
"Authorization": `Bearer ${token}`
|
|
73503
|
-
// This is the USER's JWT, not the anon key
|
|
73504
|
-
};
|
|
73505
|
-
const response = await this.fetchWithRetry(url, {
|
|
73506
|
-
...options,
|
|
73507
|
-
headers
|
|
73508
|
-
});
|
|
73509
|
-
if (response.status === 401) {
|
|
73510
|
-
console.error("401 Unauthorized - Token expired or invalid");
|
|
73511
|
-
throw new Error("Authentication failed. Token expired or invalid. Please log in again.");
|
|
73512
|
-
}
|
|
73513
|
-
if (response.status === 403) {
|
|
73514
|
-
console.error("403 Forbidden - User does not have permission");
|
|
73515
|
-
throw new Error("Access denied. You do not have permission to access this resource.");
|
|
73516
|
-
}
|
|
73517
|
-
if (response.status === 500) {
|
|
73518
|
-
console.error("500 Internal Server Error - Backend error");
|
|
73519
|
-
let errorDetail = "Internal server error occurred.";
|
|
73520
|
-
try {
|
|
73521
|
-
const errorData = await response.text();
|
|
73522
|
-
console.error("Backend error details:", errorData);
|
|
73523
|
-
errorDetail = errorData || errorDetail;
|
|
73524
|
-
} catch (e) {
|
|
73992
|
+
try {
|
|
73993
|
+
if (!this.supabaseClient) {
|
|
73994
|
+
throw new Error("Supabase client not initialized. Please provide a Supabase client to TicketService.");
|
|
73525
73995
|
}
|
|
73526
|
-
|
|
73527
|
-
|
|
73528
|
-
|
|
73529
|
-
|
|
73530
|
-
|
|
73531
|
-
|
|
73532
|
-
|
|
73533
|
-
|
|
73534
|
-
|
|
73996
|
+
const { data: { session }, error: sessionError } = await this.supabaseClient.auth.getSession();
|
|
73997
|
+
if (sessionError) {
|
|
73998
|
+
console.error("Session error:", sessionError);
|
|
73999
|
+
throw new Error("Failed to get authentication session. Please log in.");
|
|
74000
|
+
}
|
|
74001
|
+
if (!session) {
|
|
74002
|
+
console.error("No session found. User must be logged in.");
|
|
74003
|
+
throw new Error("User not authenticated. Please log in.");
|
|
74004
|
+
}
|
|
74005
|
+
if (!session.access_token) {
|
|
74006
|
+
console.error("Session exists but no access_token found");
|
|
74007
|
+
throw new Error("Invalid session. Please log in again.");
|
|
74008
|
+
}
|
|
74009
|
+
const token = session.access_token;
|
|
74010
|
+
if (process.env.NODE_ENV === "development") {
|
|
74011
|
+
console.log("[TicketService] Using JWT token (first 20 chars):", token.substring(0, 20) + "...");
|
|
74012
|
+
console.log("[TicketService] Token is NOT the anon key - it is the user JWT from session.access_token");
|
|
74013
|
+
}
|
|
74014
|
+
const headers = {
|
|
74015
|
+
"Content-Type": "application/json",
|
|
74016
|
+
...options.headers,
|
|
74017
|
+
"Authorization": `Bearer ${token}`
|
|
74018
|
+
};
|
|
74019
|
+
const response = await this.fetchWithRetry(url, {
|
|
74020
|
+
...options,
|
|
74021
|
+
headers
|
|
74022
|
+
});
|
|
74023
|
+
if (response.status === 401) {
|
|
74024
|
+
console.error("401 Unauthorized - Token expired or invalid");
|
|
74025
|
+
throw new Error("Authentication failed. Token expired or invalid. Please log in again.");
|
|
74026
|
+
}
|
|
74027
|
+
if (response.status === 403) {
|
|
74028
|
+
console.error("403 Forbidden - User does not have permission");
|
|
74029
|
+
throw new Error("Access denied. You do not have permission to access this resource.");
|
|
74030
|
+
}
|
|
74031
|
+
if (response.status === 500) {
|
|
74032
|
+
console.error("500 Internal Server Error - Backend error");
|
|
74033
|
+
let errorDetail = "Internal server error occurred.";
|
|
74034
|
+
try {
|
|
74035
|
+
const errorData = await response.text();
|
|
74036
|
+
console.error("Backend error details:", errorData);
|
|
74037
|
+
errorDetail = errorData || errorDetail;
|
|
74038
|
+
} catch (e) {
|
|
73535
74039
|
}
|
|
73536
|
-
|
|
74040
|
+
throw new Error(`Backend error: ${errorDetail}`);
|
|
74041
|
+
}
|
|
74042
|
+
if (!response.ok) {
|
|
74043
|
+
console.error(`HTTP ${response.status} - ${response.statusText}`);
|
|
74044
|
+
let errorDetail = response.statusText;
|
|
74045
|
+
try {
|
|
74046
|
+
const errorData = await response.json();
|
|
74047
|
+
if (errorData.detail) {
|
|
74048
|
+
errorDetail = errorData.detail;
|
|
74049
|
+
}
|
|
74050
|
+
} catch (e) {
|
|
74051
|
+
}
|
|
74052
|
+
throw new Error(`Request failed (${response.status}): ${errorDetail}`);
|
|
73537
74053
|
}
|
|
73538
|
-
|
|
74054
|
+
return response;
|
|
74055
|
+
} catch (error) {
|
|
74056
|
+
captureHandledFrontendException(error, {
|
|
74057
|
+
surface: "ticket_service",
|
|
74058
|
+
url,
|
|
74059
|
+
method: options.method || "GET",
|
|
74060
|
+
pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
|
|
74061
|
+
});
|
|
74062
|
+
throw error;
|
|
73539
74063
|
}
|
|
73540
|
-
return response;
|
|
73541
74064
|
}
|
|
73542
74065
|
/**
|
|
73543
74066
|
* Get tickets with filters and pagination
|
|
@@ -74260,7 +74783,7 @@ Please ensure:
|
|
|
74260
74783
|
)
|
|
74261
74784
|
] });
|
|
74262
74785
|
}
|
|
74263
|
-
var AuthenticatedTicketsView = withAuth(
|
|
74786
|
+
var AuthenticatedTicketsView = withAuth(React143__default.memo(TicketsView));
|
|
74264
74787
|
var TicketsView_default = TicketsView;
|
|
74265
74788
|
|
|
74266
74789
|
// src/lib/utils/improvementDisplay.ts
|
|
@@ -75231,7 +75754,7 @@ var ImprovementCenterView = () => {
|
|
|
75231
75754
|
setSelectedMemberId("all");
|
|
75232
75755
|
}
|
|
75233
75756
|
}, [memberOptions, selectedMemberId]);
|
|
75234
|
-
const getRecommendationDisplayMetadata =
|
|
75757
|
+
const getRecommendationDisplayMetadata = React143__default.useCallback((rec) => {
|
|
75235
75758
|
const supervisors = rec.line_id ? supervisorsByLineId.get(rec.line_id) || [] : [];
|
|
75236
75759
|
return getImprovementDisplayMetadata({
|
|
75237
75760
|
location: rec.location,
|
|
@@ -75705,7 +76228,7 @@ var ThreadSidebar = ({
|
|
|
75705
76228
|
] }) })
|
|
75706
76229
|
] });
|
|
75707
76230
|
};
|
|
75708
|
-
var ProfilePicture =
|
|
76231
|
+
var ProfilePicture = React143__default.memo(({
|
|
75709
76232
|
alt = "Axel",
|
|
75710
76233
|
className = "",
|
|
75711
76234
|
size = "md",
|
|
@@ -78230,7 +78753,7 @@ var OverviewImprovementsSkeleton = () => /* @__PURE__ */ jsx("div", { className:
|
|
|
78230
78753
|
] }),
|
|
78231
78754
|
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-end flex-shrink-0 ml-4", children: /* @__PURE__ */ jsx(SectionPulse, { className: "h-6 w-20 rounded-full" }) })
|
|
78232
78755
|
] }, index)) });
|
|
78233
|
-
var OperationsOverviewHeader =
|
|
78756
|
+
var OperationsOverviewHeader = React143__default.memo(({
|
|
78234
78757
|
dateRange,
|
|
78235
78758
|
displayDateRange,
|
|
78236
78759
|
trendMode,
|
|
@@ -78250,65 +78773,65 @@ var OperationsOverviewHeader = React142__default.memo(({
|
|
|
78250
78773
|
bumpRenderCounter();
|
|
78251
78774
|
const subtitleRange = displayDateRange || dateRange;
|
|
78252
78775
|
const showLiveShiftMeta = isLiveScope && trendMode !== "all";
|
|
78253
|
-
const liveShiftLabel =
|
|
78776
|
+
const liveShiftLabel = React143__default.useMemo(
|
|
78254
78777
|
() => normalizeShiftLabel(liveShiftName, trendMode),
|
|
78255
78778
|
[liveShiftName, trendMode]
|
|
78256
78779
|
);
|
|
78257
|
-
const liveShiftIcon =
|
|
78780
|
+
const liveShiftIcon = React143__default.useMemo(
|
|
78258
78781
|
() => getShiftIcon(liveShiftName, trendMode),
|
|
78259
78782
|
[liveShiftName, trendMode]
|
|
78260
78783
|
);
|
|
78261
|
-
const [isFilterOpen, setIsFilterOpen] =
|
|
78262
|
-
const [isLinesDropdownOpen, setIsLinesDropdownOpen] =
|
|
78263
|
-
const filterRef =
|
|
78264
|
-
const filterButtonRef =
|
|
78265
|
-
const mobileFilterButtonRef =
|
|
78266
|
-
const linesDropdownRef =
|
|
78267
|
-
const mobileSubtitle =
|
|
78784
|
+
const [isFilterOpen, setIsFilterOpen] = React143__default.useState(false);
|
|
78785
|
+
const [isLinesDropdownOpen, setIsLinesDropdownOpen] = React143__default.useState(false);
|
|
78786
|
+
const filterRef = React143__default.useRef(null);
|
|
78787
|
+
const filterButtonRef = React143__default.useRef(null);
|
|
78788
|
+
const mobileFilterButtonRef = React143__default.useRef(null);
|
|
78789
|
+
const linesDropdownRef = React143__default.useRef(null);
|
|
78790
|
+
const mobileSubtitle = React143__default.useMemo(() => {
|
|
78268
78791
|
if (subtitleRange.startKey === subtitleRange.endKey) {
|
|
78269
78792
|
return format(parseDateKeyToDate(subtitleRange.startKey), "do MMM, yyyy");
|
|
78270
78793
|
}
|
|
78271
78794
|
return `${format(parseDateKeyToDate(subtitleRange.startKey), "do MMM")} - ${format(parseDateKeyToDate(subtitleRange.endKey), "do MMM, yyyy")}`;
|
|
78272
78795
|
}, [subtitleRange.endKey, subtitleRange.startKey]);
|
|
78273
|
-
const desktopSubtitle =
|
|
78796
|
+
const desktopSubtitle = React143__default.useMemo(() => {
|
|
78274
78797
|
if (subtitleRange.startKey === subtitleRange.endKey) {
|
|
78275
78798
|
return format(parseDateKeyToDate(subtitleRange.startKey), "do MMMM, yyyy");
|
|
78276
78799
|
}
|
|
78277
78800
|
return `${format(parseDateKeyToDate(subtitleRange.startKey), "do MMMM, yyyy")} - ${format(parseDateKeyToDate(subtitleRange.endKey), "do MMMM, yyyy")}`;
|
|
78278
78801
|
}, [subtitleRange.endKey, subtitleRange.startKey]);
|
|
78279
|
-
const availableLineIds =
|
|
78802
|
+
const availableLineIds = React143__default.useMemo(
|
|
78280
78803
|
() => lineOptions.map((line) => line.id),
|
|
78281
78804
|
[lineOptions]
|
|
78282
78805
|
);
|
|
78283
|
-
const selectedLineIdSet =
|
|
78806
|
+
const selectedLineIdSet = React143__default.useMemo(
|
|
78284
78807
|
() => new Set(selectedLineIds),
|
|
78285
78808
|
[selectedLineIds]
|
|
78286
78809
|
);
|
|
78287
|
-
const isAllLinesSelected =
|
|
78810
|
+
const isAllLinesSelected = React143__default.useMemo(() => {
|
|
78288
78811
|
if (availableLineIds.length === 0) return true;
|
|
78289
78812
|
return availableLineIds.every((lineId) => selectedLineIdSet.has(lineId));
|
|
78290
78813
|
}, [availableLineIds, selectedLineIdSet]);
|
|
78291
|
-
const activeFilterCount =
|
|
78814
|
+
const activeFilterCount = React143__default.useMemo(() => {
|
|
78292
78815
|
let count = 0;
|
|
78293
78816
|
if (trendMode !== "all") count += 1;
|
|
78294
78817
|
if (selectedSupervisorId !== "all") count += 1;
|
|
78295
78818
|
if (!isAllLinesSelected) count += 1;
|
|
78296
78819
|
return count;
|
|
78297
78820
|
}, [isAllLinesSelected, selectedSupervisorId, trendMode]);
|
|
78298
|
-
const handleFilterToggle =
|
|
78821
|
+
const handleFilterToggle = React143__default.useCallback(() => {
|
|
78299
78822
|
trackCoreEvent("Operations Overview Filter Toggled", {
|
|
78300
78823
|
action: !isFilterOpen ? "open" : "close"
|
|
78301
78824
|
});
|
|
78302
78825
|
setIsFilterOpen((previous) => !previous);
|
|
78303
78826
|
}, [isFilterOpen]);
|
|
78304
|
-
const handleTrendModeChange =
|
|
78827
|
+
const handleTrendModeChange = React143__default.useCallback((event) => {
|
|
78305
78828
|
const nextMode = event.target.value;
|
|
78306
78829
|
trackCoreEvent("Operations Overview Shift Filter Changed", {
|
|
78307
78830
|
shift_mode: nextMode
|
|
78308
78831
|
});
|
|
78309
78832
|
onTrendModeChange(nextMode);
|
|
78310
78833
|
}, [onTrendModeChange]);
|
|
78311
|
-
const handleAllLinesToggle =
|
|
78834
|
+
const handleAllLinesToggle = React143__default.useCallback(() => {
|
|
78312
78835
|
trackCoreEvent("Operations Overview Line Filter Changed", {
|
|
78313
78836
|
selected_line_ids: availableLineIds,
|
|
78314
78837
|
selected_line_count: availableLineIds.length,
|
|
@@ -78316,7 +78839,7 @@ var OperationsOverviewHeader = React142__default.memo(({
|
|
|
78316
78839
|
});
|
|
78317
78840
|
onSelectedLineIdsChange(availableLineIds);
|
|
78318
78841
|
}, [availableLineIds, onSelectedLineIdsChange]);
|
|
78319
|
-
const handleSupervisorChange =
|
|
78842
|
+
const handleSupervisorChange = React143__default.useCallback((event) => {
|
|
78320
78843
|
const supervisorId = event.target.value;
|
|
78321
78844
|
const selectedSupervisor = supervisorOptions.find((option) => option.id === supervisorId);
|
|
78322
78845
|
trackCoreEvent("Operations Overview Supervisor Filter Changed", {
|
|
@@ -78327,7 +78850,7 @@ var OperationsOverviewHeader = React142__default.memo(({
|
|
|
78327
78850
|
});
|
|
78328
78851
|
onSelectedSupervisorIdChange(supervisorId);
|
|
78329
78852
|
}, [availableLineIds, onSelectedSupervisorIdChange, supervisorOptions]);
|
|
78330
|
-
const handleLineToggle =
|
|
78853
|
+
const handleLineToggle = React143__default.useCallback((lineId) => {
|
|
78331
78854
|
const current = new Set(selectedLineIds);
|
|
78332
78855
|
if (current.has(lineId)) {
|
|
78333
78856
|
if (current.size <= 1) return;
|
|
@@ -78343,13 +78866,13 @@ var OperationsOverviewHeader = React142__default.memo(({
|
|
|
78343
78866
|
});
|
|
78344
78867
|
onSelectedLineIdsChange(next);
|
|
78345
78868
|
}, [availableLineIds, onSelectedLineIdsChange, selectedLineIds]);
|
|
78346
|
-
const handleClearAllFilters =
|
|
78869
|
+
const handleClearAllFilters = React143__default.useCallback(() => {
|
|
78347
78870
|
onTrendModeChange("all");
|
|
78348
78871
|
onSelectedSupervisorIdChange("all");
|
|
78349
78872
|
onSelectedLineIdsChange(availableLineIds);
|
|
78350
78873
|
setIsFilterOpen(false);
|
|
78351
78874
|
}, [availableLineIds, onSelectedLineIdsChange, onSelectedSupervisorIdChange, onTrendModeChange]);
|
|
78352
|
-
|
|
78875
|
+
React143__default.useEffect(() => {
|
|
78353
78876
|
const handleClickOutside = (event) => {
|
|
78354
78877
|
const target = event.target;
|
|
78355
78878
|
if (filterRef.current && !filterRef.current.contains(target) && filterButtonRef.current && !filterButtonRef.current.contains(target) && mobileFilterButtonRef.current && !mobileFilterButtonRef.current.contains(target)) {
|
|
@@ -78588,12 +79111,12 @@ var OperationsOverviewHeader = React142__default.memo(({
|
|
|
78588
79111
|
] }) });
|
|
78589
79112
|
});
|
|
78590
79113
|
OperationsOverviewHeader.displayName = "OperationsOverviewHeader";
|
|
78591
|
-
var OverviewSummaryCards =
|
|
79114
|
+
var OverviewSummaryCards = React143__default.memo(({ store }) => {
|
|
78592
79115
|
bumpRenderCounter();
|
|
78593
79116
|
const scope = useOperationsOverviewScope(store);
|
|
78594
79117
|
const snapshot = useOperationsOverviewSnapshot(store);
|
|
78595
79118
|
const showSnapshotSkeleton = snapshot.loading && !snapshot.hasLoadedOnce;
|
|
78596
|
-
const comparisonLabel =
|
|
79119
|
+
const comparisonLabel = React143__default.useMemo(() => {
|
|
78597
79120
|
return formatComparisonWindow({
|
|
78598
79121
|
currentDayCount: scope.current_range?.day_count ?? null,
|
|
78599
79122
|
previousDayCount: scope.previous_range?.day_count ?? null,
|
|
@@ -78606,27 +79129,27 @@ var OverviewSummaryCards = React142__default.memo(({ store }) => {
|
|
|
78606
79129
|
scope.previous_range?.day_count,
|
|
78607
79130
|
scope.shift_mode
|
|
78608
79131
|
]);
|
|
78609
|
-
const [isIdleContributorsOpen, setIsIdleContributorsOpen] =
|
|
78610
|
-
const [isIdleContributorsPinned, setIsIdleContributorsPinned] =
|
|
78611
|
-
const idleContributorsRef =
|
|
78612
|
-
const plantEfficiencyBadge =
|
|
79132
|
+
const [isIdleContributorsOpen, setIsIdleContributorsOpen] = React143__default.useState(false);
|
|
79133
|
+
const [isIdleContributorsPinned, setIsIdleContributorsPinned] = React143__default.useState(false);
|
|
79134
|
+
const idleContributorsRef = React143__default.useRef(null);
|
|
79135
|
+
const plantEfficiencyBadge = React143__default.useMemo(() => {
|
|
78613
79136
|
return buildDeltaBadge(snapshot.data.summary.plant_efficiency?.delta_pp, {
|
|
78614
79137
|
positiveIsGood: true,
|
|
78615
79138
|
formatter: (value) => `${value >= 0 ? "+" : ""}${roundOne(value)}%`,
|
|
78616
79139
|
comparisonLabel
|
|
78617
79140
|
});
|
|
78618
79141
|
}, [comparisonLabel, snapshot.data.summary.plant_efficiency?.delta_pp]);
|
|
78619
|
-
const idleBadge =
|
|
79142
|
+
const idleBadge = React143__default.useMemo(() => {
|
|
78620
79143
|
return buildDeltaBadge(snapshot.data.summary.avg_idle_per_workstation?.delta_seconds, {
|
|
78621
79144
|
positiveIsGood: false,
|
|
78622
79145
|
formatter: (value) => formatSignedIdleDuration(value),
|
|
78623
79146
|
comparisonLabel
|
|
78624
79147
|
});
|
|
78625
79148
|
}, [comparisonLabel, snapshot.data.summary.avg_idle_per_workstation?.delta_seconds]);
|
|
78626
|
-
const canInspectIdleContributors =
|
|
79149
|
+
const canInspectIdleContributors = React143__default.useMemo(() => {
|
|
78627
79150
|
return !showSnapshotSkeleton && snapshot.data.summary.avg_idle_per_workstation?.current_seconds !== null && snapshot.data.summary.avg_idle_per_workstation?.current_seconds !== void 0;
|
|
78628
79151
|
}, [showSnapshotSkeleton, snapshot.data.summary.avg_idle_per_workstation?.current_seconds]);
|
|
78629
|
-
const idleTopContributors =
|
|
79152
|
+
const idleTopContributors = React143__default.useMemo(() => {
|
|
78630
79153
|
return (snapshot.data.summary.avg_idle_per_workstation?.top_contributors || []).map((item) => ({
|
|
78631
79154
|
workspaceId: item.workspace_id || "",
|
|
78632
79155
|
workspaceName: item.workspace_name?.trim() || item.workspace_id || "Unknown",
|
|
@@ -78634,14 +79157,14 @@ var OverviewSummaryCards = React142__default.memo(({ store }) => {
|
|
|
78634
79157
|
avgIdleSeconds: toNumber3(item.avg_idle_seconds)
|
|
78635
79158
|
})).slice(0, 5);
|
|
78636
79159
|
}, [snapshot.data.summary.avg_idle_per_workstation?.top_contributors]);
|
|
78637
|
-
const showIdleContributorLineNames =
|
|
79160
|
+
const showIdleContributorLineNames = React143__default.useMemo(() => {
|
|
78638
79161
|
return (scope.line_count ?? 0) > 1;
|
|
78639
79162
|
}, [scope.line_count]);
|
|
78640
|
-
const closeIdleContributors =
|
|
79163
|
+
const closeIdleContributors = React143__default.useCallback(() => {
|
|
78641
79164
|
setIsIdleContributorsOpen(false);
|
|
78642
79165
|
setIsIdleContributorsPinned(false);
|
|
78643
79166
|
}, []);
|
|
78644
|
-
const handleIdleContributorsToggle =
|
|
79167
|
+
const handleIdleContributorsToggle = React143__default.useCallback(() => {
|
|
78645
79168
|
if (!canInspectIdleContributors) return;
|
|
78646
79169
|
setIsIdleContributorsPinned((previous) => {
|
|
78647
79170
|
const next = !previous;
|
|
@@ -78649,7 +79172,7 @@ var OverviewSummaryCards = React142__default.memo(({ store }) => {
|
|
|
78649
79172
|
return next;
|
|
78650
79173
|
});
|
|
78651
79174
|
}, [canInspectIdleContributors]);
|
|
78652
|
-
const handleIdleContributorsKeyDown =
|
|
79175
|
+
const handleIdleContributorsKeyDown = React143__default.useCallback((event) => {
|
|
78653
79176
|
if (!canInspectIdleContributors) return;
|
|
78654
79177
|
if (event.key === "Enter" || event.key === " ") {
|
|
78655
79178
|
event.preventDefault();
|
|
@@ -78661,11 +79184,11 @@ var OverviewSummaryCards = React142__default.memo(({ store }) => {
|
|
|
78661
79184
|
closeIdleContributors();
|
|
78662
79185
|
}
|
|
78663
79186
|
}, [canInspectIdleContributors, closeIdleContributors, handleIdleContributorsToggle]);
|
|
78664
|
-
|
|
79187
|
+
React143__default.useEffect(() => {
|
|
78665
79188
|
setIsIdleContributorsOpen(false);
|
|
78666
79189
|
setIsIdleContributorsPinned(false);
|
|
78667
79190
|
}, [scope.comparison_strategy, scope.current_range?.start_date, scope.current_range?.end_date, scope.line_count, scope.shift_mode]);
|
|
78668
|
-
|
|
79191
|
+
React143__default.useEffect(() => {
|
|
78669
79192
|
if (!isIdleContributorsOpen) return void 0;
|
|
78670
79193
|
const handleClickOutside = (event) => {
|
|
78671
79194
|
if (!isIdleContributorsPinned) return;
|
|
@@ -78803,7 +79326,7 @@ var OverviewSummaryCards = React142__default.memo(({ store }) => {
|
|
|
78803
79326
|
] });
|
|
78804
79327
|
});
|
|
78805
79328
|
OverviewSummaryCards.displayName = "OverviewSummaryCards";
|
|
78806
|
-
var PoorestPerformersCard =
|
|
79329
|
+
var PoorestPerformersCard = React143__default.memo(({
|
|
78807
79330
|
store,
|
|
78808
79331
|
supervisorsByLineId,
|
|
78809
79332
|
onViewAll,
|
|
@@ -78812,9 +79335,9 @@ var PoorestPerformersCard = React142__default.memo(({
|
|
|
78812
79335
|
bumpRenderCounter();
|
|
78813
79336
|
const scope = useOperationsOverviewScope(store);
|
|
78814
79337
|
const snapshot = useOperationsOverviewSnapshot(store);
|
|
78815
|
-
const [poorestLineMode, setPoorestLineMode] =
|
|
79338
|
+
const [poorestLineMode, setPoorestLineMode] = React143__default.useState("output");
|
|
78816
79339
|
const availableLineModes = scope.available_line_modes;
|
|
78817
|
-
|
|
79340
|
+
React143__default.useEffect(() => {
|
|
78818
79341
|
const hasOutput = !!availableLineModes?.has_output;
|
|
78819
79342
|
const hasUptime = !!availableLineModes?.has_uptime;
|
|
78820
79343
|
if (hasOutput && !hasUptime && poorestLineMode !== "output") {
|
|
@@ -78823,7 +79346,7 @@ var PoorestPerformersCard = React142__default.memo(({
|
|
|
78823
79346
|
setPoorestLineMode("uptime");
|
|
78824
79347
|
}
|
|
78825
79348
|
}, [availableLineModes?.has_output, availableLineModes?.has_uptime, poorestLineMode]);
|
|
78826
|
-
const comparisonLabel =
|
|
79349
|
+
const comparisonLabel = React143__default.useMemo(() => {
|
|
78827
79350
|
return formatComparisonWindow({
|
|
78828
79351
|
currentDayCount: scope.current_range?.day_count ?? null,
|
|
78829
79352
|
previousDayCount: scope.previous_range?.day_count ?? null,
|
|
@@ -78837,7 +79360,7 @@ var PoorestPerformersCard = React142__default.memo(({
|
|
|
78837
79360
|
scope.shift_mode
|
|
78838
79361
|
]);
|
|
78839
79362
|
const showSnapshotSkeleton = snapshot.loading && !snapshot.hasLoadedOnce;
|
|
78840
|
-
const mergedPoorestLines =
|
|
79363
|
+
const mergedPoorestLines = React143__default.useMemo(() => {
|
|
78841
79364
|
const rows = snapshot.data.poorest_lines?.[poorestLineMode] || [];
|
|
78842
79365
|
return rows.slice(0, 3).map((line) => {
|
|
78843
79366
|
const lineId = line.line_id || "";
|
|
@@ -78856,7 +79379,7 @@ var PoorestPerformersCard = React142__default.memo(({
|
|
|
78856
79379
|
}, [poorestLineMode, snapshot.data.poorest_lines, supervisorsByLineId]);
|
|
78857
79380
|
const showPoorestModeToggle = !!availableLineModes?.has_output && !!availableLineModes?.has_uptime;
|
|
78858
79381
|
const poorestMetricLabel = poorestLineMode === "uptime" ? "Uptime" : "Efficiency";
|
|
78859
|
-
const handlePoorestLineModeChange =
|
|
79382
|
+
const handlePoorestLineModeChange = React143__default.useCallback((mode) => {
|
|
78860
79383
|
trackCoreEvent("Operations Overview Poorest Line Mode Changed", { mode });
|
|
78861
79384
|
setPoorestLineMode(mode);
|
|
78862
79385
|
}, []);
|
|
@@ -78942,14 +79465,14 @@ var PoorestPerformersCard = React142__default.memo(({
|
|
|
78942
79465
|
] });
|
|
78943
79466
|
});
|
|
78944
79467
|
PoorestPerformersCard.displayName = "PoorestPerformersCard";
|
|
78945
|
-
var IdleBreakdownCard =
|
|
79468
|
+
var IdleBreakdownCard = React143__default.memo(({
|
|
78946
79469
|
store,
|
|
78947
79470
|
scopedLineCount
|
|
78948
79471
|
}) => {
|
|
78949
79472
|
bumpRenderCounter();
|
|
78950
79473
|
const idle = useOperationsOverviewIdle(store);
|
|
78951
79474
|
const showInitialSkeleton = idle.loading && idle.lastUpdated === null;
|
|
78952
|
-
const idleBreakdown =
|
|
79475
|
+
const idleBreakdown = React143__default.useMemo(() => {
|
|
78953
79476
|
return idle.data.map((item) => ({
|
|
78954
79477
|
name: item.display_name?.trim() || item.reason?.trim() || "Unknown",
|
|
78955
79478
|
reasonKey: item.reason_key?.trim() || item.reason?.trim() || "unknown",
|
|
@@ -78968,7 +79491,7 @@ var IdleBreakdownCard = React142__default.memo(({
|
|
|
78968
79491
|
}))
|
|
78969
79492
|
})).filter((item) => item.value > 0);
|
|
78970
79493
|
}, [idle.data]);
|
|
78971
|
-
const showIdleModuleNotEnabledState =
|
|
79494
|
+
const showIdleModuleNotEnabledState = React143__default.useMemo(() => {
|
|
78972
79495
|
const enabledLineCount = idle.scope.idle_time_vlm_enabled_line_count;
|
|
78973
79496
|
return !showInitialSkeleton && scopedLineCount > 0 && typeof enabledLineCount === "number" && enabledLineCount === 0;
|
|
78974
79497
|
}, [idle.scope.idle_time_vlm_enabled_line_count, scopedLineCount, showInitialSkeleton]);
|
|
@@ -78989,7 +79512,7 @@ var IdleBreakdownCard = React142__default.memo(({
|
|
|
78989
79512
|
] });
|
|
78990
79513
|
});
|
|
78991
79514
|
IdleBreakdownCard.displayName = "IdleBreakdownCard";
|
|
78992
|
-
var EfficiencyTrendCard =
|
|
79515
|
+
var EfficiencyTrendCard = React143__default.memo(({
|
|
78993
79516
|
store,
|
|
78994
79517
|
dateRange,
|
|
78995
79518
|
appTimezone,
|
|
@@ -78997,14 +79520,14 @@ var EfficiencyTrendCard = React142__default.memo(({
|
|
|
78997
79520
|
}) => {
|
|
78998
79521
|
bumpRenderCounter();
|
|
78999
79522
|
const trend = useOperationsOverviewTrend(store);
|
|
79000
|
-
const currentWeekRange =
|
|
79523
|
+
const currentWeekRange = React143__default.useMemo(
|
|
79001
79524
|
() => getCurrentWeekToDateRange(appTimezone),
|
|
79002
79525
|
[appTimezone]
|
|
79003
79526
|
);
|
|
79004
79527
|
const isCurrentWeekToDateRange = dateRange.startKey === currentWeekRange.startKey && dateRange.endKey === currentWeekRange.endKey;
|
|
79005
79528
|
const showInitialSkeleton = trend.loading && trend.lastUpdated === null;
|
|
79006
79529
|
const isHourlyTrend = trend.data.granularity === "hour";
|
|
79007
|
-
const trendData =
|
|
79530
|
+
const trendData = React143__default.useMemo(() => {
|
|
79008
79531
|
if (isHourlyTrend) {
|
|
79009
79532
|
return (trend.data.points || []).map((point, index) => ({
|
|
79010
79533
|
name: (() => {
|
|
@@ -79076,13 +79599,13 @@ var EfficiencyTrendCard = React142__default.memo(({
|
|
|
79076
79599
|
};
|
|
79077
79600
|
});
|
|
79078
79601
|
}, [currentWeekRange.startKey, hourlyLabelStartTime, isCurrentWeekToDateRange, isHourlyTrend, trend.data.points]);
|
|
79079
|
-
const trendTooltipLabelFormatter =
|
|
79602
|
+
const trendTooltipLabelFormatter = React143__default.useCallback((label, payload) => {
|
|
79080
79603
|
if (isHourlyTrend) return label;
|
|
79081
79604
|
const dayOfWeek = payload?.[0]?.payload?.dayOfWeek;
|
|
79082
79605
|
if (!dayOfWeek || typeof label !== "string") return label;
|
|
79083
79606
|
return `${label} (${dayOfWeek})`;
|
|
79084
79607
|
}, [isHourlyTrend]);
|
|
79085
|
-
const trendXAxisTickFormatter =
|
|
79608
|
+
const trendXAxisTickFormatter = React143__default.useCallback((value, index) => {
|
|
79086
79609
|
if (!isHourlyTrend) {
|
|
79087
79610
|
return typeof value === "string" ? value : String(value ?? "");
|
|
79088
79611
|
}
|
|
@@ -79109,7 +79632,7 @@ var EfficiencyTrendCard = React142__default.memo(({
|
|
|
79109
79632
|
] });
|
|
79110
79633
|
});
|
|
79111
79634
|
EfficiencyTrendCard.displayName = "EfficiencyTrendCard";
|
|
79112
|
-
var TopImprovementsCard =
|
|
79635
|
+
var TopImprovementsCard = React143__default.memo(({
|
|
79113
79636
|
store,
|
|
79114
79637
|
supervisorsByLineId,
|
|
79115
79638
|
onViewAll,
|
|
@@ -79118,7 +79641,7 @@ var TopImprovementsCard = React142__default.memo(({
|
|
|
79118
79641
|
bumpRenderCounter();
|
|
79119
79642
|
const improvements = useOperationsOverviewImprovements(store);
|
|
79120
79643
|
const showInitialSkeleton = improvements.loading && improvements.lastUpdated === null;
|
|
79121
|
-
const displayImprovements =
|
|
79644
|
+
const displayImprovements = React143__default.useMemo(() => {
|
|
79122
79645
|
return improvements.data.map((item) => {
|
|
79123
79646
|
const supervisors = item.lineId ? supervisorsByLineId.get(item.lineId) || [] : [];
|
|
79124
79647
|
return {
|
|
@@ -79191,7 +79714,7 @@ var debugRefreshLog = (message, payload) => {
|
|
|
79191
79714
|
}
|
|
79192
79715
|
console.log(`[OperationsOverviewRefresh] ${message}`);
|
|
79193
79716
|
};
|
|
79194
|
-
var
|
|
79717
|
+
var isAbortError2 = (error) => {
|
|
79195
79718
|
return error instanceof DOMException && error.name === "AbortError";
|
|
79196
79719
|
};
|
|
79197
79720
|
var toNumber4 = (value) => {
|
|
@@ -79246,33 +79769,33 @@ var useOperationsOverviewRefresh = ({
|
|
|
79246
79769
|
isLiveScope,
|
|
79247
79770
|
enabled = true
|
|
79248
79771
|
}) => {
|
|
79249
|
-
const lineIdsKey =
|
|
79250
|
-
const scopeSignature =
|
|
79772
|
+
const lineIdsKey = React143__default.useMemo(() => lineIds.join(","), [lineIds]);
|
|
79773
|
+
const scopeSignature = React143__default.useMemo(
|
|
79251
79774
|
() => [companyId || "", startKey, endKey, trendMode, comparisonStrategy || "", lineIdsKey].join("::"),
|
|
79252
79775
|
[companyId, comparisonStrategy, endKey, lineIdsKey, startKey, trendMode]
|
|
79253
79776
|
);
|
|
79254
|
-
const controllersRef =
|
|
79255
|
-
const requestIdsRef =
|
|
79777
|
+
const controllersRef = React143__default.useRef({});
|
|
79778
|
+
const requestIdsRef = React143__default.useRef({
|
|
79256
79779
|
snapshot: 0,
|
|
79257
79780
|
trend: 0,
|
|
79258
79781
|
idle: 0,
|
|
79259
79782
|
improvements: 0
|
|
79260
79783
|
});
|
|
79261
|
-
const intervalRef =
|
|
79262
|
-
const isPageActiveRef =
|
|
79263
|
-
const lastResumeRefreshAtRef =
|
|
79264
|
-
const abortAll =
|
|
79784
|
+
const intervalRef = React143__default.useRef(null);
|
|
79785
|
+
const isPageActiveRef = React143__default.useRef(true);
|
|
79786
|
+
const lastResumeRefreshAtRef = React143__default.useRef(0);
|
|
79787
|
+
const abortAll = React143__default.useCallback(() => {
|
|
79265
79788
|
Object.values(controllersRef.current).forEach((controller) => {
|
|
79266
79789
|
controller?.abort();
|
|
79267
79790
|
});
|
|
79268
79791
|
controllersRef.current = {};
|
|
79269
79792
|
}, []);
|
|
79270
|
-
|
|
79793
|
+
React143__default.useEffect(() => {
|
|
79271
79794
|
return () => {
|
|
79272
79795
|
abortAll();
|
|
79273
79796
|
};
|
|
79274
79797
|
}, [abortAll]);
|
|
79275
|
-
const getIsPageActive =
|
|
79798
|
+
const getIsPageActive = React143__default.useCallback(() => {
|
|
79276
79799
|
if (typeof document === "undefined") {
|
|
79277
79800
|
return true;
|
|
79278
79801
|
}
|
|
@@ -79280,7 +79803,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
79280
79803
|
const hasFocus = typeof document.hasFocus === "function" ? document.hasFocus() : true;
|
|
79281
79804
|
return isVisible && hasFocus;
|
|
79282
79805
|
}, []);
|
|
79283
|
-
const stopPolling =
|
|
79806
|
+
const stopPolling = React143__default.useCallback((reason) => {
|
|
79284
79807
|
if (intervalRef.current === null) {
|
|
79285
79808
|
return;
|
|
79286
79809
|
}
|
|
@@ -79288,7 +79811,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
79288
79811
|
intervalRef.current = null;
|
|
79289
79812
|
debugRefreshLog("poll stopped", { reason });
|
|
79290
79813
|
}, []);
|
|
79291
|
-
const runRefresh =
|
|
79814
|
+
const runRefresh = React143__default.useCallback(
|
|
79292
79815
|
async (section, begin, onSuccess, onError, request, reason) => {
|
|
79293
79816
|
if (!enabled || !supabase || !companyId || lineIds.length === 0) return;
|
|
79294
79817
|
const requestId = requestIdsRef.current[section] + 1;
|
|
@@ -79304,7 +79827,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
79304
79827
|
}
|
|
79305
79828
|
onSuccess(response, Date.now(), reason === "live_refresh" ? "transition" : "default");
|
|
79306
79829
|
} catch (error) {
|
|
79307
|
-
if (controller.signal.aborted || requestIdsRef.current[section] !== requestId ||
|
|
79830
|
+
if (controller.signal.aborted || requestIdsRef.current[section] !== requestId || isAbortError2(error)) {
|
|
79308
79831
|
return;
|
|
79309
79832
|
}
|
|
79310
79833
|
onError(error instanceof Error ? error.message : `Failed to refresh ${section}`);
|
|
@@ -79312,7 +79835,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
79312
79835
|
},
|
|
79313
79836
|
[companyId, enabled, lineIds.length, supabase]
|
|
79314
79837
|
);
|
|
79315
|
-
const refreshSnapshot =
|
|
79838
|
+
const refreshSnapshot = React143__default.useCallback(
|
|
79316
79839
|
async (reason) => {
|
|
79317
79840
|
await runRefresh(
|
|
79318
79841
|
"snapshot",
|
|
@@ -79344,7 +79867,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
79344
79867
|
},
|
|
79345
79868
|
[companyId, comparisonStrategy, endKey, lineIdsKey, runRefresh, scopeSignature, startKey, store, supabase, trendMode]
|
|
79346
79869
|
);
|
|
79347
|
-
const refreshTrend =
|
|
79870
|
+
const refreshTrend = React143__default.useCallback(
|
|
79348
79871
|
async (reason) => {
|
|
79349
79872
|
await runRefresh(
|
|
79350
79873
|
"trend",
|
|
@@ -79373,7 +79896,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
79373
79896
|
},
|
|
79374
79897
|
[companyId, endKey, lineIdsKey, runRefresh, scopeSignature, startKey, store, supabase, trendMode]
|
|
79375
79898
|
);
|
|
79376
|
-
const refreshIdle =
|
|
79899
|
+
const refreshIdle = React143__default.useCallback(
|
|
79377
79900
|
async (reason) => {
|
|
79378
79901
|
await runRefresh(
|
|
79379
79902
|
"idle",
|
|
@@ -79402,7 +79925,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
79402
79925
|
},
|
|
79403
79926
|
[companyId, endKey, lineIdsKey, runRefresh, scopeSignature, startKey, store, supabase, trendMode]
|
|
79404
79927
|
);
|
|
79405
|
-
const refreshImprovements =
|
|
79928
|
+
const refreshImprovements = React143__default.useCallback(
|
|
79406
79929
|
async (reason) => {
|
|
79407
79930
|
await runRefresh(
|
|
79408
79931
|
"improvements",
|
|
@@ -79432,7 +79955,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
79432
79955
|
},
|
|
79433
79956
|
[companyId, lineIds, lineIdsKey, runRefresh, scopeSignature, store, supabase]
|
|
79434
79957
|
);
|
|
79435
|
-
const refreshAll =
|
|
79958
|
+
const refreshAll = React143__default.useCallback(
|
|
79436
79959
|
async (reason) => {
|
|
79437
79960
|
await Promise.allSettled([
|
|
79438
79961
|
refreshSnapshot(reason),
|
|
@@ -79443,7 +79966,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
79443
79966
|
},
|
|
79444
79967
|
[refreshIdle, refreshImprovements, refreshSnapshot, refreshTrend]
|
|
79445
79968
|
);
|
|
79446
|
-
const startPolling =
|
|
79969
|
+
const startPolling = React143__default.useCallback((reason) => {
|
|
79447
79970
|
if (!isLiveScope || !supabase || !companyId || lineIds.length === 0) {
|
|
79448
79971
|
return;
|
|
79449
79972
|
}
|
|
@@ -79464,7 +79987,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
79464
79987
|
}, LIVE_REFRESH_INTERVAL_MS);
|
|
79465
79988
|
debugRefreshLog("poll started", { reason, intervalMs: LIVE_REFRESH_INTERVAL_MS });
|
|
79466
79989
|
}, [companyId, isLiveScope, lineIds.length, refreshAll, stopPolling, supabase]);
|
|
79467
|
-
const refreshFromResume =
|
|
79990
|
+
const refreshFromResume = React143__default.useCallback((reason) => {
|
|
79468
79991
|
const now4 = Date.now();
|
|
79469
79992
|
if (now4 - lastResumeRefreshAtRef.current < 1e3) {
|
|
79470
79993
|
debugRefreshLog("resume refresh suppressed", { reason });
|
|
@@ -79479,7 +80002,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
79479
80002
|
}
|
|
79480
80003
|
});
|
|
79481
80004
|
}, [refreshAll, startPolling, stopPolling]);
|
|
79482
|
-
|
|
80005
|
+
React143__default.useEffect(() => {
|
|
79483
80006
|
if (!enabled) {
|
|
79484
80007
|
stopPolling("disabled");
|
|
79485
80008
|
abortAll();
|
|
@@ -79494,7 +80017,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
79494
80017
|
}
|
|
79495
80018
|
void refreshAll("scope_change");
|
|
79496
80019
|
}, [abortAll, companyId, enabled, lineIds.length, refreshAll, scopeSignature, stopPolling, store, supabase]);
|
|
79497
|
-
|
|
80020
|
+
React143__default.useEffect(() => {
|
|
79498
80021
|
if (!enabled || !isLiveScope || !supabase || !companyId || lineIds.length === 0) {
|
|
79499
80022
|
isPageActiveRef.current = false;
|
|
79500
80023
|
stopPolling("live_scope_disabled");
|
|
@@ -79669,55 +80192,55 @@ var PlantHeadView = () => {
|
|
|
79669
80192
|
const { accessibleLineIds } = useUserLineAccess();
|
|
79670
80193
|
const mobileMenuContext = useMobileMenu();
|
|
79671
80194
|
useHideMobileHeader(!!mobileMenuContext);
|
|
79672
|
-
const storeRef =
|
|
80195
|
+
const storeRef = React143__default.useRef(createOperationsOverviewStore());
|
|
79673
80196
|
const store = storeRef.current;
|
|
79674
|
-
const fallbackOperationalDate =
|
|
80197
|
+
const fallbackOperationalDate = React143__default.useMemo(
|
|
79675
80198
|
() => getOperationalDate(appTimezone),
|
|
79676
80199
|
[appTimezone]
|
|
79677
80200
|
);
|
|
79678
|
-
const [dateRange, setDateRange] =
|
|
80201
|
+
const [dateRange, setDateRange] = React143__default.useState(() => ({
|
|
79679
80202
|
startKey: fallbackOperationalDate,
|
|
79680
80203
|
endKey: fallbackOperationalDate
|
|
79681
80204
|
}));
|
|
79682
|
-
const [usesThisWeekComparison, setUsesThisWeekComparison] =
|
|
79683
|
-
const [trendMode, setTrendMode] =
|
|
79684
|
-
const [selectedSupervisorId, setSelectedSupervisorId] =
|
|
79685
|
-
const [selectedLineIds, setSelectedLineIds] =
|
|
79686
|
-
const [isInitialScopeReady, setIsInitialScopeReady] =
|
|
79687
|
-
const [shiftResolutionTick, setShiftResolutionTick] =
|
|
79688
|
-
const hasAutoInitializedScopeRef =
|
|
79689
|
-
const hasUserAdjustedScopeRef =
|
|
79690
|
-
|
|
80205
|
+
const [usesThisWeekComparison, setUsesThisWeekComparison] = React143__default.useState(false);
|
|
80206
|
+
const [trendMode, setTrendMode] = React143__default.useState("all");
|
|
80207
|
+
const [selectedSupervisorId, setSelectedSupervisorId] = React143__default.useState("all");
|
|
80208
|
+
const [selectedLineIds, setSelectedLineIds] = React143__default.useState([]);
|
|
80209
|
+
const [isInitialScopeReady, setIsInitialScopeReady] = React143__default.useState(false);
|
|
80210
|
+
const [shiftResolutionTick, setShiftResolutionTick] = React143__default.useState(0);
|
|
80211
|
+
const hasAutoInitializedScopeRef = React143__default.useRef(false);
|
|
80212
|
+
const hasUserAdjustedScopeRef = React143__default.useRef(false);
|
|
80213
|
+
React143__default.useEffect(() => {
|
|
79691
80214
|
trackCorePageView("Operations Overview", {
|
|
79692
80215
|
dashboard_surface: "operations_overview"
|
|
79693
80216
|
});
|
|
79694
80217
|
}, []);
|
|
79695
|
-
const currentWeekRange =
|
|
80218
|
+
const currentWeekRange = React143__default.useMemo(
|
|
79696
80219
|
() => getCurrentWeekToDateRange(appTimezone),
|
|
79697
80220
|
[appTimezone]
|
|
79698
80221
|
);
|
|
79699
|
-
const currentWeekDisplayRange =
|
|
80222
|
+
const currentWeekDisplayRange = React143__default.useMemo(
|
|
79700
80223
|
() => getCurrentWeekFullRange(appTimezone),
|
|
79701
80224
|
[appTimezone]
|
|
79702
80225
|
);
|
|
79703
80226
|
const isCurrentWeekToDateRange = dateRange.startKey === currentWeekRange.startKey && dateRange.endKey === currentWeekRange.endKey;
|
|
79704
|
-
const headerDateRange =
|
|
80227
|
+
const headerDateRange = React143__default.useMemo(() => {
|
|
79705
80228
|
if (usesThisWeekComparison && isCurrentWeekToDateRange) {
|
|
79706
80229
|
return currentWeekDisplayRange;
|
|
79707
80230
|
}
|
|
79708
80231
|
return dateRange;
|
|
79709
80232
|
}, [currentWeekDisplayRange, dateRange, isCurrentWeekToDateRange, usesThisWeekComparison]);
|
|
79710
|
-
const normalizedLineIds =
|
|
80233
|
+
const normalizedLineIds = React143__default.useMemo(
|
|
79711
80234
|
() => Array.from(new Set(
|
|
79712
80235
|
(accessibleLineIds || []).filter(Boolean).filter((lineId) => lineId !== factoryViewId)
|
|
79713
80236
|
)).sort(),
|
|
79714
80237
|
[accessibleLineIds, factoryViewId]
|
|
79715
80238
|
);
|
|
79716
|
-
const lineIdsKey =
|
|
80239
|
+
const lineIdsKey = React143__default.useMemo(
|
|
79717
80240
|
() => normalizedLineIds.join(","),
|
|
79718
80241
|
[normalizedLineIds]
|
|
79719
80242
|
);
|
|
79720
|
-
const lineOptions =
|
|
80243
|
+
const lineOptions = React143__default.useMemo(
|
|
79721
80244
|
() => normalizedLineIds.map((lineId) => ({
|
|
79722
80245
|
id: lineId,
|
|
79723
80246
|
name: getLineDisplayName(entityConfig, lineId)
|
|
@@ -79729,7 +80252,7 @@ var PlantHeadView = () => {
|
|
|
79729
80252
|
companyId: entityConfig.companyId,
|
|
79730
80253
|
useBackend: true
|
|
79731
80254
|
});
|
|
79732
|
-
const supervisorOptions =
|
|
80255
|
+
const supervisorOptions = React143__default.useMemo(
|
|
79733
80256
|
() => {
|
|
79734
80257
|
const optionsById = /* @__PURE__ */ new Map();
|
|
79735
80258
|
normalizedLineIds.forEach((lineId) => {
|
|
@@ -79755,7 +80278,7 @@ var PlantHeadView = () => {
|
|
|
79755
80278
|
},
|
|
79756
80279
|
[normalizedLineIds, supervisorsByLineId]
|
|
79757
80280
|
);
|
|
79758
|
-
|
|
80281
|
+
React143__default.useEffect(() => {
|
|
79759
80282
|
if (selectedSupervisorId === "all") {
|
|
79760
80283
|
setSelectedLineIds((previous) => {
|
|
79761
80284
|
if (normalizedLineIds.length === 0) {
|
|
@@ -79781,7 +80304,7 @@ var PlantHeadView = () => {
|
|
|
79781
80304
|
const scopedSupervisorLineIds = normalizedLineIds.filter((lineId) => supervisorLineIdSet.has(lineId));
|
|
79782
80305
|
setSelectedLineIds((previous) => previous.length === scopedSupervisorLineIds.length && previous.every((lineId, index) => lineId === scopedSupervisorLineIds[index]) ? previous : scopedSupervisorLineIds);
|
|
79783
80306
|
}, [lineIdsKey, normalizedLineIds, selectedSupervisorId, supervisorOptions]);
|
|
79784
|
-
const scopedLineIds =
|
|
80307
|
+
const scopedLineIds = React143__default.useMemo(
|
|
79785
80308
|
() => selectedLineIds.length > 0 ? selectedLineIds : normalizedLineIds,
|
|
79786
80309
|
[normalizedLineIds, selectedLineIds]
|
|
79787
80310
|
);
|
|
@@ -79789,7 +80312,7 @@ var PlantHeadView = () => {
|
|
|
79789
80312
|
shiftConfigMap,
|
|
79790
80313
|
isLoading: isShiftConfigLoading
|
|
79791
80314
|
} = useMultiLineShiftConfigs(scopedLineIds, staticShiftConfig);
|
|
79792
|
-
|
|
80315
|
+
React143__default.useEffect(() => {
|
|
79793
80316
|
if (scopedLineIds.length === 0 || isShiftConfigLoading) {
|
|
79794
80317
|
return;
|
|
79795
80318
|
}
|
|
@@ -79800,11 +80323,11 @@ var PlantHeadView = () => {
|
|
|
79800
80323
|
clearInterval(intervalId);
|
|
79801
80324
|
};
|
|
79802
80325
|
}, [isShiftConfigLoading, scopedLineIds.length]);
|
|
79803
|
-
const shiftResolutionNow =
|
|
80326
|
+
const shiftResolutionNow = React143__default.useMemo(
|
|
79804
80327
|
() => /* @__PURE__ */ new Date(),
|
|
79805
80328
|
[shiftResolutionTick]
|
|
79806
80329
|
);
|
|
79807
|
-
const earliestDayShiftStartTime =
|
|
80330
|
+
const earliestDayShiftStartTime = React143__default.useMemo(() => {
|
|
79808
80331
|
const candidateStarts = [];
|
|
79809
80332
|
scopedLineIds.forEach((lineId) => {
|
|
79810
80333
|
const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
|
|
@@ -79840,11 +80363,11 @@ var PlantHeadView = () => {
|
|
|
79840
80363
|
const minutes = earliestMinutes % 60;
|
|
79841
80364
|
return `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
|
|
79842
80365
|
}, [appTimezone, scopedLineIds, shiftConfigMap, staticShiftConfig]);
|
|
79843
|
-
const resolvedOperationalToday =
|
|
80366
|
+
const resolvedOperationalToday = React143__default.useMemo(
|
|
79844
80367
|
() => getOperationalDate(appTimezone, shiftResolutionNow, earliestDayShiftStartTime),
|
|
79845
80368
|
[appTimezone, earliestDayShiftStartTime, shiftResolutionNow]
|
|
79846
80369
|
);
|
|
79847
|
-
const activeLineShiftStates =
|
|
80370
|
+
const activeLineShiftStates = React143__default.useMemo(() => {
|
|
79848
80371
|
return scopedLineIds.flatMap((lineId) => {
|
|
79849
80372
|
const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
|
|
79850
80373
|
const activeShift = getActiveShift(appTimezone, shiftConfig, shiftResolutionNow);
|
|
@@ -79871,16 +80394,16 @@ var PlantHeadView = () => {
|
|
|
79871
80394
|
}];
|
|
79872
80395
|
});
|
|
79873
80396
|
}, [appTimezone, scopedLineIds, shiftConfigMap, shiftResolutionNow, staticShiftConfig]);
|
|
79874
|
-
const hasActiveDayShiftLine =
|
|
80397
|
+
const hasActiveDayShiftLine = React143__default.useMemo(
|
|
79875
80398
|
() => activeLineShiftStates.some((shift) => shift.trendMode === "day" && shift.date === resolvedOperationalToday),
|
|
79876
80399
|
[activeLineShiftStates, resolvedOperationalToday]
|
|
79877
80400
|
);
|
|
79878
|
-
const hasActiveNightShiftLine =
|
|
80401
|
+
const hasActiveNightShiftLine = React143__default.useMemo(
|
|
79879
80402
|
() => activeLineShiftStates.some((shift) => shift.trendMode === "night" && shift.date === resolvedOperationalToday),
|
|
79880
80403
|
[activeLineShiftStates, resolvedOperationalToday]
|
|
79881
80404
|
);
|
|
79882
80405
|
const resolvedTrendMode = isInitialScopeReady ? trendMode : "all";
|
|
79883
|
-
const hourlyWindowStartTime =
|
|
80406
|
+
const hourlyWindowStartTime = React143__default.useMemo(() => {
|
|
79884
80407
|
if (scopedLineIds.length === 0) {
|
|
79885
80408
|
return null;
|
|
79886
80409
|
}
|
|
@@ -79931,12 +80454,12 @@ var PlantHeadView = () => {
|
|
|
79931
80454
|
const minutes = earliestMinutes % 60;
|
|
79932
80455
|
return `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
|
|
79933
80456
|
}, [appTimezone, resolvedTrendMode, scopedLineIds, shiftConfigMap, staticShiftConfig]);
|
|
79934
|
-
const isShiftScopeResolved =
|
|
80457
|
+
const isShiftScopeResolved = React143__default.useMemo(
|
|
79935
80458
|
() => !isShiftConfigLoading,
|
|
79936
80459
|
[isShiftConfigLoading]
|
|
79937
80460
|
);
|
|
79938
|
-
const initializedTimezoneRef =
|
|
79939
|
-
|
|
80461
|
+
const initializedTimezoneRef = React143__default.useRef(appTimezone);
|
|
80462
|
+
React143__default.useEffect(() => {
|
|
79940
80463
|
if (initializedTimezoneRef.current === appTimezone) return;
|
|
79941
80464
|
hasAutoInitializedScopeRef.current = false;
|
|
79942
80465
|
hasUserAdjustedScopeRef.current = false;
|
|
@@ -79949,7 +80472,7 @@ var PlantHeadView = () => {
|
|
|
79949
80472
|
setIsInitialScopeReady(false);
|
|
79950
80473
|
initializedTimezoneRef.current = appTimezone;
|
|
79951
80474
|
}, [appTimezone, fallbackOperationalDate]);
|
|
79952
|
-
|
|
80475
|
+
React143__default.useEffect(() => {
|
|
79953
80476
|
if (hasAutoInitializedScopeRef.current || hasUserAdjustedScopeRef.current) {
|
|
79954
80477
|
return;
|
|
79955
80478
|
}
|
|
@@ -79974,7 +80497,7 @@ var PlantHeadView = () => {
|
|
|
79974
80497
|
hasAutoInitializedScopeRef.current = true;
|
|
79975
80498
|
setIsInitialScopeReady(true);
|
|
79976
80499
|
}, [fallbackOperationalDate, isShiftScopeResolved, resolvedOperationalToday, scopedLineIds.length]);
|
|
79977
|
-
const handleDateRangeChange =
|
|
80500
|
+
const handleDateRangeChange = React143__default.useCallback((range, meta) => {
|
|
79978
80501
|
hasUserAdjustedScopeRef.current = true;
|
|
79979
80502
|
setIsInitialScopeReady(true);
|
|
79980
80503
|
trackCoreEvent("Operations Overview Date Range Changed", {
|
|
@@ -79992,12 +80515,12 @@ var PlantHeadView = () => {
|
|
|
79992
80515
|
return previous;
|
|
79993
80516
|
});
|
|
79994
80517
|
}, []);
|
|
79995
|
-
const handleTrendModeChange =
|
|
80518
|
+
const handleTrendModeChange = React143__default.useCallback((mode) => {
|
|
79996
80519
|
hasUserAdjustedScopeRef.current = true;
|
|
79997
80520
|
setIsInitialScopeReady(true);
|
|
79998
80521
|
setTrendMode(mode);
|
|
79999
80522
|
}, []);
|
|
80000
|
-
const handleSelectedLineIdsChange =
|
|
80523
|
+
const handleSelectedLineIdsChange = React143__default.useCallback((lineIds) => {
|
|
80001
80524
|
setSelectedSupervisorId("all");
|
|
80002
80525
|
if (normalizedLineIds.length === 0) {
|
|
80003
80526
|
setSelectedLineIds([]);
|
|
@@ -80008,10 +80531,10 @@ var PlantHeadView = () => {
|
|
|
80008
80531
|
const next = normalizedLineIds.filter((lineId) => selectedSet.has(lineId));
|
|
80009
80532
|
setSelectedLineIds(next.length > 0 ? next : normalizedLineIds);
|
|
80010
80533
|
}, [normalizedLineIds]);
|
|
80011
|
-
const handleSelectedSupervisorIdChange =
|
|
80534
|
+
const handleSelectedSupervisorIdChange = React143__default.useCallback((supervisorId) => {
|
|
80012
80535
|
setSelectedSupervisorId(supervisorId);
|
|
80013
80536
|
}, []);
|
|
80014
|
-
const buildLineMonthlyHistoryUrl =
|
|
80537
|
+
const buildLineMonthlyHistoryUrl = React143__default.useCallback((lineId) => {
|
|
80015
80538
|
const rangeStartDate = parseDateKeyToDate(dateRange.startKey);
|
|
80016
80539
|
const params = new URLSearchParams();
|
|
80017
80540
|
params.set("tab", "monthly_history");
|
|
@@ -80021,15 +80544,15 @@ var PlantHeadView = () => {
|
|
|
80021
80544
|
params.set("rangeEnd", dateRange.endKey);
|
|
80022
80545
|
return `/kpis/${lineId}?${params.toString()}`;
|
|
80023
80546
|
}, [dateRange.endKey, dateRange.startKey]);
|
|
80024
|
-
const handleViewAllPoorestPerformers =
|
|
80547
|
+
const handleViewAllPoorestPerformers = React143__default.useCallback(() => {
|
|
80025
80548
|
trackCoreEvent("Operations Overview View All Clicked", { section: "poorest_performers" });
|
|
80026
80549
|
navigate("/kpis?tab=leaderboard");
|
|
80027
80550
|
}, [navigate]);
|
|
80028
|
-
const handleViewAllImprovements =
|
|
80551
|
+
const handleViewAllImprovements = React143__default.useCallback(() => {
|
|
80029
80552
|
trackCoreEvent("Operations Overview View All Clicked", { section: "improvements" });
|
|
80030
80553
|
navigate("/improvement-center");
|
|
80031
80554
|
}, [navigate]);
|
|
80032
|
-
const handleOpenImprovement =
|
|
80555
|
+
const handleOpenImprovement = React143__default.useCallback((item) => {
|
|
80033
80556
|
trackCoreEvent("Operations Overview Improvement Clicked", {
|
|
80034
80557
|
issue_id: item.issueId,
|
|
80035
80558
|
issue_number: item.issueNumber,
|
|
@@ -80040,13 +80563,13 @@ var PlantHeadView = () => {
|
|
|
80040
80563
|
});
|
|
80041
80564
|
navigate(`/improvement-center?${params.toString()}`);
|
|
80042
80565
|
}, [navigate]);
|
|
80043
|
-
const comparisonStrategy =
|
|
80566
|
+
const comparisonStrategy = React143__default.useMemo(() => {
|
|
80044
80567
|
if (usesThisWeekComparison && isCurrentWeekToDateRange) {
|
|
80045
80568
|
return "previous_full_week";
|
|
80046
80569
|
}
|
|
80047
80570
|
return void 0;
|
|
80048
80571
|
}, [isCurrentWeekToDateRange, usesThisWeekComparison]);
|
|
80049
|
-
const effectiveDateRange =
|
|
80572
|
+
const effectiveDateRange = React143__default.useMemo(() => {
|
|
80050
80573
|
if (isInitialScopeReady) {
|
|
80051
80574
|
return dateRange;
|
|
80052
80575
|
}
|
|
@@ -80056,21 +80579,21 @@ var PlantHeadView = () => {
|
|
|
80056
80579
|
endKey: nextStartKey
|
|
80057
80580
|
};
|
|
80058
80581
|
}, [dateRange, fallbackOperationalDate, isInitialScopeReady, resolvedOperationalToday]);
|
|
80059
|
-
const effectiveTrendMode =
|
|
80582
|
+
const effectiveTrendMode = React143__default.useMemo(
|
|
80060
80583
|
() => resolvedTrendMode,
|
|
80061
80584
|
[resolvedTrendMode]
|
|
80062
80585
|
);
|
|
80063
|
-
const hourlyLabelStartTime =
|
|
80586
|
+
const hourlyLabelStartTime = React143__default.useMemo(() => {
|
|
80064
80587
|
if (scopedLineIds.length === 0) {
|
|
80065
80588
|
return null;
|
|
80066
80589
|
}
|
|
80067
80590
|
return hourlyWindowStartTime;
|
|
80068
80591
|
}, [hourlyWindowStartTime, scopedLineIds.length]);
|
|
80069
|
-
const isSingleDayScope =
|
|
80592
|
+
const isSingleDayScope = React143__default.useMemo(
|
|
80070
80593
|
() => effectiveDateRange.startKey === effectiveDateRange.endKey,
|
|
80071
80594
|
[effectiveDateRange.endKey, effectiveDateRange.startKey]
|
|
80072
80595
|
);
|
|
80073
|
-
const isLiveScope =
|
|
80596
|
+
const isLiveScope = React143__default.useMemo(
|
|
80074
80597
|
() => isSingleDayScope && effectiveDateRange.startKey === resolvedOperationalToday && (effectiveTrendMode === "all" || effectiveTrendMode === "day" && hasActiveDayShiftLine || effectiveTrendMode === "night" && hasActiveNightShiftLine),
|
|
80075
80598
|
[
|
|
80076
80599
|
effectiveDateRange.startKey,
|
|
@@ -80081,7 +80604,7 @@ var PlantHeadView = () => {
|
|
|
80081
80604
|
resolvedOperationalToday
|
|
80082
80605
|
]
|
|
80083
80606
|
);
|
|
80084
|
-
const handleOpenLineDetails =
|
|
80607
|
+
const handleOpenLineDetails = React143__default.useCallback((lineId, lineName) => {
|
|
80085
80608
|
trackCoreEvent("Operations Overview Line Clicked", {
|
|
80086
80609
|
line_id: lineId,
|
|
80087
80610
|
line_name: lineName,
|
|
@@ -80649,4 +81172,4 @@ var streamProxyConfig = {
|
|
|
80649
81172
|
}
|
|
80650
81173
|
};
|
|
80651
81174
|
|
|
80652
|
-
export { ACTION_FAMILIES, ACTION_NAMES, AIAgentView_default as AIAgentView, AcceptInvite, AcceptInviteView_default as AcceptInviteView, AdvancedFilterDialog, AdvancedFilterPanel, AudioService, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthService, AuthenticatedBottleneckClipsView, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedShiftsView, AuthenticatedTargetsView, AuthenticatedTicketsView, AuthenticatedWorkspaceHealthView, AvatarUpload, AxelNotificationPopup, AxelOrb, BackButton, BackButtonMinimal, BarChart, BaseHistoryCalendar, BottleneckClipsModal, BottleneckClipsView_default as BottleneckClipsView, BottlenecksContent, BreakNotificationPopup, CachePrefetchStatus, Card2 as Card, CardContent2 as CardContent, CardDescription2 as CardDescription, CardFooter2 as CardFooter, CardHeader2 as CardHeader, CardTitle2 as CardTitle, ChangeRoleDialog, ClipFilterProvider, ClipsCostView_default as ClipsCostView, CompactWorkspaceHealthCard, ConfirmRemoveUserDialog, CongratulationsOverlay, CroppedHlsVideoPlayer, CroppedVideoPlayer, CycleTimeChart, CycleTimeOverTimeChart, DEFAULT_ANALYTICS_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_CONFIG, DEFAULT_DATABASE_CONFIG, DEFAULT_DATE_TIME_CONFIG, DEFAULT_ENDPOINTS_CONFIG, DEFAULT_ENTITY_CONFIG, DEFAULT_HOME_VIEW_CONFIG, DEFAULT_MAP_VIEW_CONFIG, DEFAULT_SHIFT_CONFIG, DEFAULT_SHIFT_DATA, DEFAULT_THEME_CONFIG, DEFAULT_VIDEO_CONFIG, DEFAULT_WORKSPACE_CONFIG, DEFAULT_WORKSPACE_POSITIONS, DashboardHeader, DashboardLayout, DashboardOverridesProvider, DashboardProvider, DateDisplay_default as DateDisplay, DateTimeDisplay, DebugAuth, DebugAuthView_default as DebugAuthView, DetailedHealthStatus, DiagnosisVideoModal, EFFICIENCY_ON_TRACK_THRESHOLD, EmptyStateMessage, EncouragementOverlay, FactoryAssignmentDropdown, FactoryView_default as FactoryView, FileManagerFilters, FilterDialogTrigger, FirstTimeLoginDebug, FirstTimeLoginHandler, FittingTitle, GaugeChart, GridComponentsPlaceholder, HamburgerButton, Header, HealthDateShiftSelector, HealthStatusGrid, HealthStatusIndicator, HelpView_default as HelpView, HlsVideoPlayer, HomeView_default as HomeView, HourlyOutputChart2 as HourlyOutputChart, HourlyUptimeChart, ISTTimer_default as ISTTimer, IdleTimeVlmConfigProvider, ImprovementCenterView_default as ImprovementCenterView, InlineEditableText, InteractiveOnboardingTour, InvitationService, InvitationsTable, InviteUserDialog, KPICard, KPIDetailView_default as KPIDetailView, KPIGrid, KPIHeader, KPISection, KPIsOverviewView_default as KPIsOverviewView, LINE_1_UUID, LINE_2_UUID, LargeOutputProgressChart, LeaderboardDetailView_default as LeaderboardDetailView, Legend5 as Legend, LineAssignmentDropdown, LineChart, LineHistoryCalendar, LineMonthlyHistory, LineMonthlyPdfGenerator, LinePdfExportButton, LinePdfGenerator, LineWhatsAppShareButton, LinesService, LiveTimer, LoadingInline, LoadingOverlay_default as LoadingOverlay, LoadingPage_default as LoadingPage, LoadingSkeleton, LoadingState, LoginPage, LoginView_default as LoginView, Logo, MainLayout, MapGridView, MetricCard_default as MetricCard, MinimalOnboardingPopup, MobileMenuProvider, NewClipsNotification, NoWorkspaceData, OnboardingDemo, OnboardingTour, OptifyeAgentClient, OptifyeLogoLoader_default as OptifyeLogoLoader, OutputProgressChart, PageHeader, PieChart4 as PieChart, PlantHeadView_default as PlantHeadView, PlayPauseIndicator, PrefetchConfigurationError, PrefetchError, PrefetchEvents, PrefetchStatus, PrefetchTimeoutError, ProfileView_default as ProfileView, ROOT_DASHBOARD_EVENT_NAMES, RegistryProvider, RoleBadge, S3ClipsSupabaseService as S3ClipsService, S3Service, SKUManagementView, SOPComplianceChart, SSEChatClient, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, SessionTracker, SessionTrackingContext, SessionTrackingProvider, SettingsPopup, ShiftDisplay_default as ShiftDisplay, ShiftsView_default as ShiftsView, SideNavBar, SignupWithInvitation, SilentErrorBoundary, SimpleOnboardingPopup, SingleVideoStream_default as SingleVideoStream, Skeleton, SubscriptionManager, SubscriptionManagerProvider, SupabaseProvider, SupervisorDropdown_default as SupervisorDropdown, SupervisorManagementView_default as SupervisorManagementView, SupervisorService, TargetWorkspaceGrid, TargetsView_default as TargetsView, TeamManagementView_default as TeamManagementView, ThreadSidebar, TicketHistory_default as TicketHistory, TicketHistoryService, TicketsView_default as TicketsView, TimeDisplay_default as TimeDisplay, TimePickerDropdown, Timer_default as Timer, TimezoneProvider, TimezoneService, UptimeDonutChart, UptimeLineChart, UptimeMetricCards, UserAvatar, UserManagementService, UserManagementTable, UserService, UserUsageDetailModal, UserUsageStats, VideoCard, VideoGridView, VideoPlayer, VideoPreloader, WORKSPACE_POSITIONS, WhatsAppShareButton, WorkspaceCard, WorkspaceCycleTimeMetricCards, WorkspaceDetailView_default as WorkspaceDetailView, WorkspaceDisplayNameExample, WorkspaceGrid, WorkspaceGridItem, WorkspaceHealthCard, WorkspaceHealthView_default as WorkspaceHealthView, WorkspaceHistoryCalendar, WorkspaceMetricCards, WorkspaceMetricCardsImpl, WorkspaceMonthlyDataFetcher, WorkspaceMonthlyHistory, WorkspaceMonthlyPdfGenerator, WorkspacePdfExportButton, WorkspacePdfGenerator, WorkspaceWhatsAppShareButton, actionService, aggregateKPIsFromLineMetricsRows, alertsService, apiUtils, areAllLinesOnSameShift, authCoreService, authOTPService, authRateLimitService, awardsService, buildDateKey, buildKPIsFromLineMetricsRow, buildShiftGroupsKey, canRoleAccessDashboardPath, canRoleAccessTeamManagement, canRoleAssignFactories, canRoleAssignLines, canRoleChangeRole, canRoleInviteRole, canRoleManageCompany, canRoleManageTargets, canRoleManageUsers, canRoleRemoveUser, canRoleViewClipsCost, canRoleViewUsageStats, captureSentryException, captureSentryMessage, checkRateLimit2 as checkRateLimit, clearAllRateLimits2 as clearAllRateLimits, clearRateLimit2 as clearRateLimit, clearS3VideoCache, clearS3VideoFromCache, clearSentryContext, clearWorkspaceDisplayNamesCache, cn, createDefaultKPIs, createInvitationService, createLinesService, createSessionTracker, createStorageService, createStreamProxyHandler, createSupabaseClient, createSupervisorService, createThrottledReload, createUserManagementService, createUserService, dashboardService, deleteThread, fetchIdleTimeReasons, filterDataByDateKeyRange, forceRefreshWorkspaceDisplayNames, formatAwardMonth, formatDateInZone, formatDateKeyForDisplay, formatDateTimeInZone, formatDuration2 as formatDuration, formatISTDate, formatIdleTime, formatRangeLabel, formatReasonLabel, formatRelativeTime, formatTimeInZone, fromUrlFriendlyName, getActionDisplayName, getActiveShift, getAllLineDisplayNames, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAllWorkspaceDisplayNamesSnapshot, getAnonClient, getAssignableRoles, getAssignmentColumnLabel, getAvailableShiftIds, getAwardBadgeType, getAwardDescription, getAwardTitle, getBrowserName, getCameraNumber, getCompanyMetricsTableName, getConfigurableShortWorkspaceDisplayName, getConfigurableWorkspaceDisplayName, getConfiguredLineIds, getCoreSessionRecordingProperties, getCoreSessionReplayUrl, getCurrentShift, getCurrentShiftForLine, getCurrentTimeInZone, getCurrentWeekFullRange, getCurrentWeekToDateRange, getDashboardHeaderTimeInZone, getDateKeyFromDate, getDaysDifferenceInZone, getDefaultCameraStreamUrl, getDefaultLineId, getDefaultTabForWorkspace, getInitials, getLineDisplayName, getManufacturingInsights, getMetricsTablePrefix, getMonthKeyBounds, getMonthWeekRanges, getNextUpdateInterval, getOperationalDate, getRoleAssignmentKind, getRoleDescription, getRoleLabel, getRoleMetadata, getRoleNavPaths, getS3SignedUrl, getS3VideoSrc, getShiftData, getShiftNameById, getShiftWorkDurationSeconds, getShortShiftName, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getSubscriptionManager, getThreadMessages, getUniformShiftGroup, getUserThreads, getUserThreadsPaginated, getVisibleRolesForCurrentUser, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, groupLinesByShift, hasAnyShiftData, identifyCoreUser, initializeCoreMixpanel, isEfficiencyOnTrack, isFactoryScopedRole, isFullMonthRange, isLegacyConfiguration, isLoopbackHostname, isPrefetchError, isRecentFlowVideoGridMetricMode, isSafari, isSupervisorRole, isTransitionPeriod, isUrlPermanentlyFailed, isValidFactoryViewConfiguration, isValidLineInfoPayload, isValidPrefetchParams, isValidPrefetchStatus, isValidWorkspaceDetailedMetricsPayload, isValidWorkspaceMetricsPayload, isWipGatedVideoGridMetricMode, isWorkspaceDisplayNamesLoaded, isWorkspaceDisplayNamesLoading, lineLeaderboardService, linesService, mergeWithDefaultConfig, migrateLegacyConfiguration, normalizeActionFamily, normalizeDateKeyRange, normalizeRoleLevel, normalizeVideoGridMetricMode, optifyeAgentClient, parseDateKeyToDate, parseS3Uri, preInitializeWorkspaceDisplayNames, preloadS3Video, preloadS3VideoUrl, preloadS3VideosUrl, preloadVideoUrl, preloadVideosUrl, qualityService, realtimeService, refreshWorkspaceDisplayNames, resetCoreMixpanel, resetFailedUrl, resetSubscriptionManager, s3VideoPreloader, setSentryUserContext, setSentryWorkspaceContext, shouldEnableLocalDevTestLogin, shuffleArray, simulateApiDelay, skuService, startCoreSessionRecording, stopCoreSessionRecording, storeWorkspaceMapping, streamProxyConfig, subscribeWorkspaceDisplayNames, throttledReloadDashboard, toUrlFriendlyName, trackCoreEvent, trackCorePageView, transformToChartData, updateThreadTitle, upsertWorkspaceDisplayNameInCache, useAccessControl, useActiveBreaks, useActiveLineId, useAllWorkspaceMetrics, useAnalyticsConfig, useAppTimezone, useAudioService, useAuth, useAuthConfig, useAxelNotifications, useCanSaveTargets, useClipFilter, useClipTypes, useClipTypesWithCounts, useClipsInit, useCompanyClipsCost, useCompanyFastSlowClipFiltersEnabled, useCompanyHasVlmEnabledLine, useCompanyUsersUsage, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useDynamicShiftConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHasLineAccess, useHideMobileHeader, useHistoricWorkspaceMetrics, useHlsStream, useHlsStreamWithCropping, useHookOverride, useHourEndTimer, useHourlyTargetAchievements, useHourlyTargetMisses, useIdleTimeClipClassifications, useIdleTimeReasons, useIdleTimeVlmConfig, useKpiTrends, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineShiftConfig, useLineSupervisor, useLineWorkspaceMetrics, useLines, useMessages, useMetrics, useMobileMenu, useMonthlyTrend, useMultiLineShiftConfigs, useNavigation, useOperationalShiftKey, useOptionalSupabase, useOverrides, usePageOverride, usePrefetchClipCounts, useRealtimeLineMetrics, useRegistry, useSKUs, useSessionKeepAlive, useSessionTracking, useSessionTrackingContext, useShiftConfig, useShiftGroups, useShifts, useSubscriptionManager, useSubscriptionManagerSafe, useSupabase, useSupabaseClient, useSupervisorsByLineIds, useTargets, useTeamManagementPermissions, useTheme, useThemeConfig, useThreads, useTicketHistory, useTimezoneContext, useUserLineAccess, useUserUsage, useVideoConfig, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceHealthById, useWorkspaceHealthLastSeen, useWorkspaceHealthStatus, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, useWorkspaceUptimeTimeline, useWorkspaceVideoStreams, userService, videoPrefetchManager, videoPreloader, weeklyTopPerformerService, whatsappService, withAccessControl, withAuth, withRegistry, withTimezone, workspaceHealthService, workspaceService };
|
|
81175
|
+
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 };
|