@optifye/dashboard-core 6.0.2 → 6.0.4
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 +3702 -0
- package/dist/index.d.mts +258 -10
- package/dist/index.d.ts +258 -10
- package/dist/index.js +2471 -839
- package/dist/index.mjs +1853 -234
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import
|
|
1
|
+
import * as React19 from 'react';
|
|
2
|
+
import React19__default, { createContext, useRef, useCallback, useState, useMemo, useEffect, memo, useContext, useLayoutEffect, useId, Children, isValidElement, useInsertionEffect, forwardRef, 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 { toZonedTime, formatInTimeZone } from 'date-fns-tz';
|
|
@@ -10,15 +10,15 @@ import Hls2 from 'hls.js';
|
|
|
10
10
|
import useSWR from 'swr';
|
|
11
11
|
import { noop, warning, invariant, progress, secondsToMilliseconds, millisecondsToSeconds, memo as memo$1 } from 'motion-utils';
|
|
12
12
|
import { getValueTransition, hover, press, isPrimaryPointer, GroupPlaybackControls, setDragLock, supportsLinearEasing, attachTimeline, isGenerator, calcGeneratorDuration, isWaapiSupportedEasing, mapEasingToNativeEasing, maxGeneratorDuration, generateLinearEasing, isBezierDefinition } from 'motion-dom';
|
|
13
|
-
import {
|
|
13
|
+
import { BarChart as BarChart$1, CartesianGrid, XAxis, YAxis, Tooltip, Legend, Bar, LabelList, ResponsiveContainer, LineChart as LineChart$1, Line, PieChart, Pie, Cell, ReferenceLine, ComposedChart, Area, ScatterChart, Scatter } from 'recharts';
|
|
14
14
|
import { Slot } from '@radix-ui/react-slot';
|
|
15
|
-
import { Camera, ChevronDown, ChevronUp, Check, ShieldCheck, Star, Award, X, Coffee, Plus, Clock, Minus, ArrowDown, ArrowUp, Search, CheckCircle, AlertTriangle, Info, Share2, Download, User, XCircle, ChevronLeft, ChevronRight, AlertCircle, Sun, Moon, MessageSquare, Trash2, ArrowLeft, RefreshCw, Menu, Send, Copy, Edit2, UserCheck, Save, LogOut, Calendar, Settings, LifeBuoy, Loader2, ArrowLeftIcon as ArrowLeftIcon$1, Settings2, CheckCircle2, EyeOff, Eye, Zap, UserCircle } from 'lucide-react';
|
|
15
|
+
import { Camera, ChevronDown, ChevronUp, Check, ShieldCheck, Star, Award, X, Coffee, Plus, Clock, Minus, ArrowDown, ArrowUp, Search, CheckCircle, AlertTriangle, Info, Share2, Download, User, XCircle, ChevronLeft, ChevronRight, AlertCircle, Sun, Moon, MessageSquare, Trash2, ArrowLeft, RefreshCw, Menu, Send, Copy, Edit2, UserCheck, Save, LogOut, Calendar, Package, Settings, LifeBuoy, Loader2, ArrowLeftIcon as ArrowLeftIcon$1, Settings2, CheckCircle2, EyeOff, Eye, Zap, UserCircle } from 'lucide-react';
|
|
16
16
|
import { DayPicker, useNavigation as useNavigation$1 } from 'react-day-picker';
|
|
17
17
|
import html2canvas from 'html2canvas';
|
|
18
18
|
import jsPDF, { jsPDF as jsPDF$1 } from 'jspdf';
|
|
19
19
|
import * as SelectPrimitive from '@radix-ui/react-select';
|
|
20
20
|
import { S3Client, ListObjectsV2Command, GetObjectCommand } from '@aws-sdk/client-s3';
|
|
21
|
-
import { HomeIcon, TrophyIcon, ChartBarIcon, AdjustmentsHorizontalIcon, ClockIcon, SparklesIcon, QuestionMarkCircleIcon, UserCircleIcon, ArrowRightIcon, ArrowLeftIcon, ChatBubbleLeftRightIcon, CheckCircleIcon, ExclamationCircleIcon, DocumentTextIcon, EnvelopeIcon, InformationCircleIcon, ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/24/outline';
|
|
21
|
+
import { HomeIcon, TrophyIcon, ChartBarIcon, AdjustmentsHorizontalIcon, ClockIcon, CubeIcon, SparklesIcon, QuestionMarkCircleIcon, UserCircleIcon, ArrowRightIcon, ArrowLeftIcon, ChatBubbleLeftRightIcon, CheckCircleIcon, ExclamationCircleIcon, DocumentTextIcon, EnvelopeIcon, InformationCircleIcon, ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/24/outline';
|
|
22
22
|
import { Readable } from 'stream';
|
|
23
23
|
import { toast } from 'sonner';
|
|
24
24
|
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
|
|
@@ -205,14 +205,14 @@ var _getDashboardConfigInstance = () => {
|
|
|
205
205
|
}
|
|
206
206
|
return dashboardConfigInstance;
|
|
207
207
|
};
|
|
208
|
-
var DashboardConfigContext =
|
|
208
|
+
var DashboardConfigContext = React19.createContext(void 0);
|
|
209
209
|
var DashboardProvider = ({ config: userProvidedConfig, children }) => {
|
|
210
|
-
const fullConfig =
|
|
210
|
+
const fullConfig = React19.useMemo(() => mergeWithDefaultConfig(userProvidedConfig), [userProvidedConfig]);
|
|
211
211
|
_setDashboardConfigInstance(fullConfig);
|
|
212
|
-
|
|
212
|
+
React19.useEffect(() => {
|
|
213
213
|
_setDashboardConfigInstance(fullConfig);
|
|
214
214
|
}, [fullConfig]);
|
|
215
|
-
|
|
215
|
+
React19.useEffect(() => {
|
|
216
216
|
if (!fullConfig.theme) return;
|
|
217
217
|
const styleId = "dashboard-core-theme-vars";
|
|
218
218
|
let styleEl = document.getElementById(styleId);
|
|
@@ -238,7 +238,7 @@ var DashboardProvider = ({ config: userProvidedConfig, children }) => {
|
|
|
238
238
|
return /* @__PURE__ */ jsx(DashboardConfigContext.Provider, { value: fullConfig, children });
|
|
239
239
|
};
|
|
240
240
|
var useDashboardConfig = () => {
|
|
241
|
-
const ctx =
|
|
241
|
+
const ctx = React19.useContext(DashboardConfigContext);
|
|
242
242
|
if (!ctx) throw new Error("useDashboardConfig must be used within a DashboardProvider");
|
|
243
243
|
return ctx;
|
|
244
244
|
};
|
|
@@ -331,6 +331,56 @@ var actionService = {
|
|
|
331
331
|
return data || [];
|
|
332
332
|
}
|
|
333
333
|
};
|
|
334
|
+
function createMemoizedFunction(fn, getCacheKey) {
|
|
335
|
+
const cache = /* @__PURE__ */ new Map();
|
|
336
|
+
const CACHE_DURATION3 = 5 * 60 * 1e3;
|
|
337
|
+
return (...args) => {
|
|
338
|
+
const key = getCacheKey(...args);
|
|
339
|
+
const cached = cache.get(key);
|
|
340
|
+
if (cached && Date.now() - cached.timestamp < CACHE_DURATION3) {
|
|
341
|
+
return cached.result;
|
|
342
|
+
}
|
|
343
|
+
const result = fn(...args);
|
|
344
|
+
cache.set(key, { result, timestamp: Date.now() });
|
|
345
|
+
if (cache.size > 100) {
|
|
346
|
+
const firstKey = cache.keys().next().value;
|
|
347
|
+
if (firstKey) cache.delete(firstKey);
|
|
348
|
+
}
|
|
349
|
+
return result;
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
var memoizedEfficiencyFilter = createMemoizedFunction(
|
|
353
|
+
(data, minEfficiency, maxEfficiency) => {
|
|
354
|
+
return data.filter((item) => {
|
|
355
|
+
const eff = item.efficiency ?? 0;
|
|
356
|
+
return eff >= minEfficiency && (maxEfficiency === void 0 || eff < maxEfficiency);
|
|
357
|
+
});
|
|
358
|
+
},
|
|
359
|
+
(data, min, max = void 0) => `${data.length}-${min}-${max}`
|
|
360
|
+
);
|
|
361
|
+
var memoizedAverageEfficiency = createMemoizedFunction(
|
|
362
|
+
(data, minThreshold = 10) => {
|
|
363
|
+
const validItems = data.filter((item) => (item.efficiency ?? 0) >= minThreshold);
|
|
364
|
+
if (validItems.length === 0) return 0;
|
|
365
|
+
const sum = validItems.reduce((acc, item) => acc + (item.efficiency ?? 0), 0);
|
|
366
|
+
return sum / validItems.length;
|
|
367
|
+
},
|
|
368
|
+
(data, threshold) => `${data.length}-${threshold}`
|
|
369
|
+
);
|
|
370
|
+
var memoizedOutputArrayAggregation = createMemoizedFunction(
|
|
371
|
+
(arrays) => {
|
|
372
|
+
if (arrays.length === 0) return [];
|
|
373
|
+
const maxLength = Math.max(...arrays.map((arr) => arr.length));
|
|
374
|
+
const result = new Array(maxLength).fill(0);
|
|
375
|
+
for (const arr of arrays) {
|
|
376
|
+
for (let i = 0; i < arr.length; i++) {
|
|
377
|
+
result[i] += arr[i];
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
return result;
|
|
381
|
+
},
|
|
382
|
+
(arrays) => arrays.map((arr) => arr.length).join("-")
|
|
383
|
+
);
|
|
334
384
|
var getOperationalDate = (timezone = "Asia/Kolkata", date = /* @__PURE__ */ new Date(), shiftStartTime = "06:00") => {
|
|
335
385
|
const zonedDate = toZonedTime(date, timezone);
|
|
336
386
|
const hours = zonedDate.getHours();
|
|
@@ -468,22 +518,32 @@ var dashboardService = {
|
|
|
468
518
|
if (!defaultLineId || !secondaryLineId || !companyId) {
|
|
469
519
|
throw new Error("Factory View requires defaultLineId, secondaryLineId, and companyId to be configured.");
|
|
470
520
|
}
|
|
471
|
-
const
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
521
|
+
const [lineResult, metricsResult, performanceResult] = await Promise.all([
|
|
522
|
+
// Get Line 1's info for general factory details
|
|
523
|
+
supabase.from(linesTable).select(`
|
|
524
|
+
id,
|
|
525
|
+
line_name,
|
|
526
|
+
factory_id,
|
|
527
|
+
factories!lines_factory_id_fkey(factory_name),
|
|
528
|
+
company_id,
|
|
529
|
+
companies!lines_company_id_fkey(company_name:name)
|
|
530
|
+
`).eq("id", defaultLineId).maybeSingle(),
|
|
531
|
+
// Get metrics from line_metrics table for both lines
|
|
532
|
+
supabase.from(lineMetricsTable).select("*").in("line_id", [defaultLineId, secondaryLineId]).eq("shift_id", shiftId).eq("date", date),
|
|
533
|
+
// Get performance data from the dynamic metrics table for both lines
|
|
534
|
+
supabase.from(metricsTable).select("efficiency").in("line_id", [defaultLineId, secondaryLineId]).eq("shift_id", shiftId).eq("date", date)
|
|
535
|
+
]);
|
|
536
|
+
if (lineResult.error) throw lineResult.error;
|
|
537
|
+
if (!lineResult.data) throw new Error(`Configured default line (${defaultLineId}) not found`);
|
|
538
|
+
if (metricsResult.error) throw metricsResult.error;
|
|
539
|
+
if (performanceResult.error) throw performanceResult.error;
|
|
540
|
+
const lineData2 = lineResult.data;
|
|
541
|
+
const metricsData = metricsResult.data;
|
|
542
|
+
const performanceData2 = performanceResult.data;
|
|
543
|
+
const underperformingWorkspaces2 = memoizedEfficiencyFilter(performanceData2 || [], 10, 70);
|
|
544
|
+
const validWorkspaces2 = memoizedEfficiencyFilter(performanceData2 || [], 10);
|
|
545
|
+
const underperformingCount2 = underperformingWorkspaces2.length;
|
|
546
|
+
validWorkspaces2.length;
|
|
487
547
|
const combinedMetrics = (metricsData || []).reduce((acc, m) => {
|
|
488
548
|
acc.avg_efficiency += m.efficiency ?? 0;
|
|
489
549
|
acc.current_output += m.current_output ?? 0;
|
|
@@ -503,13 +563,13 @@ var dashboardService = {
|
|
|
503
563
|
shift_id: shiftId,
|
|
504
564
|
date,
|
|
505
565
|
metrics: {
|
|
506
|
-
avg_efficiency: (performanceData2
|
|
507
|
-
// Use
|
|
566
|
+
avg_efficiency: memoizedAverageEfficiency(performanceData2 || [], 10),
|
|
567
|
+
// Use memoized calculation for efficiency
|
|
508
568
|
avg_cycle_time: 0,
|
|
509
569
|
// Needs calculation logic if required for factory view
|
|
510
570
|
current_output: combinedMetrics.current_output,
|
|
511
571
|
ideal_output: combinedMetrics.ideal_output,
|
|
512
|
-
total_workspaces:
|
|
572
|
+
total_workspaces: 0,
|
|
513
573
|
// SRC ALIGNMENT: Use hardcoded 44 for factory view total_workspaces
|
|
514
574
|
underperforming_workspaces: underperformingCount2,
|
|
515
575
|
underperforming_workspace_names: [],
|
|
@@ -547,9 +607,11 @@ var dashboardService = {
|
|
|
547
607
|
}
|
|
548
608
|
const { data: performanceData, error: performanceError } = await supabase.from(metricsTable).select("efficiency").eq("line_id", lineId).eq("shift_id", shiftId).eq("date", date);
|
|
549
609
|
if (performanceError) throw performanceError;
|
|
550
|
-
const
|
|
551
|
-
const
|
|
552
|
-
const
|
|
610
|
+
const underperformingWorkspaces = memoizedEfficiencyFilter(performanceData || [], 10, 70);
|
|
611
|
+
const validWorkspaces = memoizedEfficiencyFilter(performanceData || [], 10);
|
|
612
|
+
const underperformingCount = underperformingWorkspaces.length;
|
|
613
|
+
validWorkspaces.length;
|
|
614
|
+
const avgEfficiencyFromPerf = memoizedAverageEfficiency(performanceData || [], 10);
|
|
553
615
|
const useFallbackMetrics = !metricsFromDb;
|
|
554
616
|
let metricsForReturn;
|
|
555
617
|
if (useFallbackMetrics) {
|
|
@@ -864,21 +926,29 @@ var dashboardService = {
|
|
|
864
926
|
const queryShiftId = shiftProp !== void 0 ? shiftProp : currentShiftResult.shiftId;
|
|
865
927
|
try {
|
|
866
928
|
if (lineIdToQuery === factoryViewId) {
|
|
867
|
-
if (!defaultLineId || !
|
|
868
|
-
throw new Error("Factory View requires defaultLineId
|
|
929
|
+
if (!defaultLineId || !companyId) {
|
|
930
|
+
throw new Error("Factory View requires at least defaultLineId and companyId to be configured.");
|
|
869
931
|
}
|
|
870
|
-
const
|
|
871
|
-
|
|
872
|
-
|
|
932
|
+
const lineIdsToQuery = [defaultLineId, secondaryLineId].filter((id3) => id3 !== void 0 && id3 !== null);
|
|
933
|
+
const [line1Result, metricsResult2, performanceResult2] = await Promise.all([
|
|
934
|
+
supabase.from(linesTable).select("id, line_name, factory_id, factories!lines_factory_id_fkey(factory_name), company_id, companies!lines_company_id_fkey(company_name:name)").eq("id", defaultLineId).single(),
|
|
935
|
+
supabase.from(lineMetricsTable).select("*").in("line_id", lineIdsToQuery).eq("shift_id", queryShiftId).eq("date", queryDate),
|
|
936
|
+
supabase.from(metricsTable).select("efficiency").in("line_id", lineIdsToQuery).eq("shift_id", queryShiftId).eq("date", queryDate)
|
|
937
|
+
]);
|
|
938
|
+
if (line1Result.error) throw line1Result.error;
|
|
939
|
+
if (!line1Result.data) {
|
|
873
940
|
throw new Error(`Default line ${defaultLineId} for Factory View not found.`);
|
|
874
941
|
}
|
|
875
|
-
|
|
876
|
-
if (
|
|
877
|
-
const
|
|
878
|
-
|
|
879
|
-
const
|
|
880
|
-
const
|
|
881
|
-
const
|
|
942
|
+
if (metricsResult2.error) throw metricsResult2.error;
|
|
943
|
+
if (performanceResult2.error) throw performanceResult2.error;
|
|
944
|
+
const line1Data = line1Result.data;
|
|
945
|
+
const metricsData = metricsResult2.data;
|
|
946
|
+
const performanceData2 = performanceResult2.data;
|
|
947
|
+
const underperformingWorkspaces2 = memoizedEfficiencyFilter(performanceData2 || [], 10, 70);
|
|
948
|
+
const validWorkspaces2 = memoizedEfficiencyFilter(performanceData2 || [], 10);
|
|
949
|
+
const underperformingCount2 = underperformingWorkspaces2.length;
|
|
950
|
+
const totalValidWorkspaces2 = validWorkspaces2.length;
|
|
951
|
+
const avgEfficiencyFromPerf2 = memoizedAverageEfficiency(performanceData2 || [], 10);
|
|
882
952
|
const initialAccumulator = {
|
|
883
953
|
avg_cycle_time: 0,
|
|
884
954
|
current_output: 0,
|
|
@@ -886,7 +956,8 @@ var dashboardService = {
|
|
|
886
956
|
line_threshold: 0,
|
|
887
957
|
threshold_pph: 0,
|
|
888
958
|
total_workspaces: 0,
|
|
889
|
-
output_array: []
|
|
959
|
+
output_array: [],
|
|
960
|
+
outputArrays: []
|
|
890
961
|
};
|
|
891
962
|
const combinedMetricsData = (metricsData || []).reduce((acc, m) => {
|
|
892
963
|
acc.avg_cycle_time += m.avg_cycle_time ?? 0;
|
|
@@ -896,14 +967,7 @@ var dashboardService = {
|
|
|
896
967
|
acc.threshold_pph += m.threshold_pph ?? 0;
|
|
897
968
|
acc.total_workspaces += m.total_workspaces ?? 0;
|
|
898
969
|
if (m.output_array && m.output_array.length > 0) {
|
|
899
|
-
|
|
900
|
-
if (!acc.output_array || acc.output_array.length === 0) acc.output_array = [...currentMOutputArray];
|
|
901
|
-
else {
|
|
902
|
-
acc.output_array = acc.output_array.map((val, i) => val + (currentMOutputArray[i] ?? 0));
|
|
903
|
-
if (currentMOutputArray.length > acc.output_array.length) {
|
|
904
|
-
acc.output_array.push(...currentMOutputArray.slice(acc.output_array.length));
|
|
905
|
-
}
|
|
906
|
-
}
|
|
970
|
+
acc.outputArrays.push(m.output_array);
|
|
907
971
|
}
|
|
908
972
|
return acc;
|
|
909
973
|
}, initialAccumulator);
|
|
@@ -924,7 +988,7 @@ var dashboardService = {
|
|
|
924
988
|
avg_cycle_time: combinedMetricsData.avg_cycle_time / numLines,
|
|
925
989
|
current_output: combinedMetricsData.current_output,
|
|
926
990
|
ideal_output: combinedMetricsData.ideal_output,
|
|
927
|
-
total_workspaces: combinedMetricsData.total_workspaces ||
|
|
991
|
+
total_workspaces: combinedMetricsData.total_workspaces || 0,
|
|
928
992
|
// Use combined or default
|
|
929
993
|
underperforming_workspaces: underperformingCount2,
|
|
930
994
|
line_threshold: combinedMetricsData.line_threshold,
|
|
@@ -932,7 +996,7 @@ var dashboardService = {
|
|
|
932
996
|
shift_start: metricsData?.[0]?.shift_start || shiftConfig.dayShift?.startTime || "06:00",
|
|
933
997
|
shift_end: metricsData?.[0]?.shift_end || shiftConfig.dayShift?.endTime || "18:00",
|
|
934
998
|
last_updated: (/* @__PURE__ */ new Date()).toISOString(),
|
|
935
|
-
output_array: combinedMetricsData.
|
|
999
|
+
output_array: combinedMetricsData.outputArrays.length > 0 ? memoizedOutputArrayAggregation(combinedMetricsData.outputArrays) : [],
|
|
936
1000
|
underperforming_workspace_names: [],
|
|
937
1001
|
underperforming_workspace_uuids: [],
|
|
938
1002
|
poorest_performing_workspaces: []
|
|
@@ -942,18 +1006,25 @@ var dashboardService = {
|
|
|
942
1006
|
if (!companyId) {
|
|
943
1007
|
throw new Error("Company ID must be configured for detailed line requests.");
|
|
944
1008
|
}
|
|
945
|
-
const
|
|
946
|
-
|
|
947
|
-
|
|
1009
|
+
const [lineResult, metricsResult, performanceResult] = await Promise.all([
|
|
1010
|
+
supabase.from(linesTable).select("id, line_name, factory_id, factories!lines_factory_id_fkey(factory_name), company_id, companies!lines_company_id_fkey(company_name:name)").eq("id", lineIdToQuery).single(),
|
|
1011
|
+
supabase.from(lineMetricsTable).select("*").eq("line_id", lineIdToQuery).eq("shift_id", queryShiftId).eq("date", queryDate).maybeSingle(),
|
|
1012
|
+
supabase.from(metricsTable).select("efficiency").eq("line_id", lineIdToQuery).eq("shift_id", queryShiftId).eq("date", queryDate)
|
|
1013
|
+
]);
|
|
1014
|
+
if (lineResult.error) throw lineResult.error;
|
|
1015
|
+
if (!lineResult.data) {
|
|
948
1016
|
throw new Error(`Line ${lineIdToQuery} not found.`);
|
|
949
1017
|
}
|
|
950
|
-
|
|
951
|
-
if (
|
|
952
|
-
const
|
|
953
|
-
|
|
954
|
-
const
|
|
955
|
-
const
|
|
956
|
-
const
|
|
1018
|
+
if (metricsResult.error) throw metricsResult.error;
|
|
1019
|
+
if (performanceResult.error) throw performanceResult.error;
|
|
1020
|
+
const lineData = lineResult.data;
|
|
1021
|
+
const metrics2 = metricsResult.data;
|
|
1022
|
+
const performanceData = performanceResult.data;
|
|
1023
|
+
const underperformingWorkspaces = memoizedEfficiencyFilter(performanceData || [], 10, 70);
|
|
1024
|
+
const validWorkspaces = memoizedEfficiencyFilter(performanceData || [], 10);
|
|
1025
|
+
const underperformingCount = underperformingWorkspaces.length;
|
|
1026
|
+
const totalValidWorkspaces = validWorkspaces.length;
|
|
1027
|
+
const avgEfficiencyFromPerf = memoizedAverageEfficiency(performanceData || [], 10);
|
|
957
1028
|
return {
|
|
958
1029
|
line_id: lineData.id,
|
|
959
1030
|
line_name: lineData.line_name,
|
|
@@ -1640,6 +1711,128 @@ var workspaceService = {
|
|
|
1640
1711
|
}
|
|
1641
1712
|
};
|
|
1642
1713
|
|
|
1714
|
+
// src/lib/services/skuService.ts
|
|
1715
|
+
var getTable4 = (dbConfig, tableName) => {
|
|
1716
|
+
const globalConfig = _getDashboardConfigInstance();
|
|
1717
|
+
const defaults2 = globalConfig?.databaseConfig?.tables;
|
|
1718
|
+
const userValue = dbConfig?.tables?.[tableName];
|
|
1719
|
+
const hardcodedDefaults = {
|
|
1720
|
+
skus: "skus"
|
|
1721
|
+
};
|
|
1722
|
+
return userValue ?? defaults2?.[tableName] ?? hardcodedDefaults[tableName];
|
|
1723
|
+
};
|
|
1724
|
+
var skuService = {
|
|
1725
|
+
/**
|
|
1726
|
+
* Fetch all active SKUs for a company
|
|
1727
|
+
*/
|
|
1728
|
+
async getSKUs(companyId) {
|
|
1729
|
+
const supabase = _getSupabaseInstance();
|
|
1730
|
+
if (!supabase) throw new Error("Supabase client not initialized");
|
|
1731
|
+
const config = _getDashboardConfigInstance();
|
|
1732
|
+
const dbConfig = config?.databaseConfig;
|
|
1733
|
+
const skusTable = getTable4(dbConfig, "skus");
|
|
1734
|
+
const { data, error } = await supabase.from(skusTable).select("*").eq("company_id", companyId).eq("is_active", true).order("created_at", { ascending: false });
|
|
1735
|
+
if (error) {
|
|
1736
|
+
console.error(`Error fetching SKUs from ${skusTable}:`, error);
|
|
1737
|
+
throw error;
|
|
1738
|
+
}
|
|
1739
|
+
return data || [];
|
|
1740
|
+
},
|
|
1741
|
+
/**
|
|
1742
|
+
* Get a single SKU by ID
|
|
1743
|
+
*/
|
|
1744
|
+
async getSKU(skuId) {
|
|
1745
|
+
const supabase = _getSupabaseInstance();
|
|
1746
|
+
if (!supabase) throw new Error("Supabase client not initialized");
|
|
1747
|
+
const config = _getDashboardConfigInstance();
|
|
1748
|
+
const dbConfig = config?.databaseConfig;
|
|
1749
|
+
const skusTable = getTable4(dbConfig, "skus");
|
|
1750
|
+
const { data, error } = await supabase.from(skusTable).select("*").eq("id", skuId).single();
|
|
1751
|
+
if (error) {
|
|
1752
|
+
console.error(`Error fetching SKU from ${skusTable}:`, error);
|
|
1753
|
+
throw error;
|
|
1754
|
+
}
|
|
1755
|
+
return data;
|
|
1756
|
+
},
|
|
1757
|
+
/**
|
|
1758
|
+
* Create a new SKU
|
|
1759
|
+
*/
|
|
1760
|
+
async createSKU(skuData) {
|
|
1761
|
+
const supabase = _getSupabaseInstance();
|
|
1762
|
+
if (!supabase) throw new Error("Supabase client not initialized");
|
|
1763
|
+
const config = _getDashboardConfigInstance();
|
|
1764
|
+
const dbConfig = config?.databaseConfig;
|
|
1765
|
+
const skusTable = getTable4(dbConfig, "skus");
|
|
1766
|
+
const { data, error } = await supabase.from(skusTable).insert([{
|
|
1767
|
+
...skuData,
|
|
1768
|
+
attributes: skuData.attributes || {},
|
|
1769
|
+
is_active: skuData.is_active ?? true
|
|
1770
|
+
}]).select("*").single();
|
|
1771
|
+
if (error) {
|
|
1772
|
+
console.error(`Error creating SKU in ${skusTable}:`, error);
|
|
1773
|
+
throw error;
|
|
1774
|
+
}
|
|
1775
|
+
return data;
|
|
1776
|
+
},
|
|
1777
|
+
/**
|
|
1778
|
+
* Update an existing SKU
|
|
1779
|
+
*/
|
|
1780
|
+
async updateSKU(skuId, updates) {
|
|
1781
|
+
const supabase = _getSupabaseInstance();
|
|
1782
|
+
if (!supabase) throw new Error("Supabase client not initialized");
|
|
1783
|
+
const config = _getDashboardConfigInstance();
|
|
1784
|
+
const dbConfig = config?.databaseConfig;
|
|
1785
|
+
const skusTable = getTable4(dbConfig, "skus");
|
|
1786
|
+
const { data, error } = await supabase.from(skusTable).update({
|
|
1787
|
+
...updates,
|
|
1788
|
+
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
1789
|
+
}).eq("id", skuId).select("*").single();
|
|
1790
|
+
if (error) {
|
|
1791
|
+
console.error(`Error updating SKU in ${skusTable}:`, error);
|
|
1792
|
+
throw error;
|
|
1793
|
+
}
|
|
1794
|
+
return data;
|
|
1795
|
+
},
|
|
1796
|
+
/**
|
|
1797
|
+
* Soft delete a SKU (set is_active to false)
|
|
1798
|
+
*/
|
|
1799
|
+
async deleteSKU(skuId) {
|
|
1800
|
+
const supabase = _getSupabaseInstance();
|
|
1801
|
+
if (!supabase) throw new Error("Supabase client not initialized");
|
|
1802
|
+
const config = _getDashboardConfigInstance();
|
|
1803
|
+
const dbConfig = config?.databaseConfig;
|
|
1804
|
+
const skusTable = getTable4(dbConfig, "skus");
|
|
1805
|
+
const { error } = await supabase.from(skusTable).update({
|
|
1806
|
+
is_active: false,
|
|
1807
|
+
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
1808
|
+
}).eq("id", skuId);
|
|
1809
|
+
if (error) {
|
|
1810
|
+
console.error(`Error deleting SKU from ${skusTable}:`, error);
|
|
1811
|
+
throw error;
|
|
1812
|
+
}
|
|
1813
|
+
},
|
|
1814
|
+
/**
|
|
1815
|
+
* Check if a SKU ID already exists for a company
|
|
1816
|
+
*/
|
|
1817
|
+
async checkSKUExists(companyId, skuId, excludeId) {
|
|
1818
|
+
const supabase = _getSupabaseInstance();
|
|
1819
|
+
if (!supabase) throw new Error("Supabase client not initialized");
|
|
1820
|
+
const config = _getDashboardConfigInstance();
|
|
1821
|
+
const dbConfig = config?.databaseConfig;
|
|
1822
|
+
const skusTable = getTable4(dbConfig, "skus");
|
|
1823
|
+
let query = supabase.from(skusTable).select("id").eq("company_id", companyId).eq("sku_id", skuId).eq("is_active", true);
|
|
1824
|
+
if (excludeId) {
|
|
1825
|
+
query = query.neq("id", excludeId);
|
|
1826
|
+
}
|
|
1827
|
+
const { data, error } = await query;
|
|
1828
|
+
if (error) {
|
|
1829
|
+
console.error(`Error checking SKU existence in ${skusTable}:`, error);
|
|
1830
|
+
throw error;
|
|
1831
|
+
}
|
|
1832
|
+
return data && data.length > 0 || false;
|
|
1833
|
+
}
|
|
1834
|
+
};
|
|
1835
|
+
|
|
1643
1836
|
// src/lib/services/authCoreService.ts
|
|
1644
1837
|
var AUTH_ERROR_MESSAGES = {
|
|
1645
1838
|
"Invalid login credentials": "Invalid email or password",
|
|
@@ -2069,6 +2262,349 @@ async function deleteThread(threadId) {
|
|
|
2069
2262
|
const { error } = await supabase.schema("ai").from("chat_threads").delete().eq("id", threadId);
|
|
2070
2263
|
if (error) throw error;
|
|
2071
2264
|
}
|
|
2265
|
+
|
|
2266
|
+
// src/lib/services/cacheService.ts
|
|
2267
|
+
var CacheService = class {
|
|
2268
|
+
constructor() {
|
|
2269
|
+
this.memoryCache = /* @__PURE__ */ new Map();
|
|
2270
|
+
this.DEFAULT_DURATION = 5 * 60 * 1e3;
|
|
2271
|
+
}
|
|
2272
|
+
// 5 minutes
|
|
2273
|
+
/**
|
|
2274
|
+
* Generate a cache key from multiple parts
|
|
2275
|
+
*/
|
|
2276
|
+
generateKey(...parts) {
|
|
2277
|
+
return parts.filter((p) => p !== void 0 && p !== null).join(":");
|
|
2278
|
+
}
|
|
2279
|
+
/**
|
|
2280
|
+
* Get item from cache
|
|
2281
|
+
*/
|
|
2282
|
+
get(key, options) {
|
|
2283
|
+
const storage = options?.storage || "memory";
|
|
2284
|
+
try {
|
|
2285
|
+
let cacheItem = null;
|
|
2286
|
+
if (storage === "memory") {
|
|
2287
|
+
cacheItem = this.memoryCache.get(key) || null;
|
|
2288
|
+
} else if (storage === "localStorage" || storage === "sessionStorage") {
|
|
2289
|
+
const stored = window[storage].getItem(key);
|
|
2290
|
+
if (stored) {
|
|
2291
|
+
cacheItem = JSON.parse(stored);
|
|
2292
|
+
}
|
|
2293
|
+
}
|
|
2294
|
+
if (!cacheItem) {
|
|
2295
|
+
return null;
|
|
2296
|
+
}
|
|
2297
|
+
if (Date.now() > cacheItem.expiresAt) {
|
|
2298
|
+
this.delete(key, options);
|
|
2299
|
+
return null;
|
|
2300
|
+
}
|
|
2301
|
+
return cacheItem.data;
|
|
2302
|
+
} catch (error) {
|
|
2303
|
+
console.error(`Error getting cache item ${key}:`, error);
|
|
2304
|
+
return null;
|
|
2305
|
+
}
|
|
2306
|
+
}
|
|
2307
|
+
/**
|
|
2308
|
+
* Set item in cache
|
|
2309
|
+
*/
|
|
2310
|
+
set(key, data, options) {
|
|
2311
|
+
const storage = options?.storage || "memory";
|
|
2312
|
+
const duration = options?.duration || this.DEFAULT_DURATION;
|
|
2313
|
+
const cacheItem = {
|
|
2314
|
+
data,
|
|
2315
|
+
timestamp: Date.now(),
|
|
2316
|
+
expiresAt: Date.now() + duration
|
|
2317
|
+
};
|
|
2318
|
+
try {
|
|
2319
|
+
if (storage === "memory") {
|
|
2320
|
+
this.memoryCache.set(key, cacheItem);
|
|
2321
|
+
if (this.memoryCache.size > 100) {
|
|
2322
|
+
const firstKey = this.memoryCache.keys().next().value;
|
|
2323
|
+
if (firstKey) {
|
|
2324
|
+
this.memoryCache.delete(firstKey);
|
|
2325
|
+
}
|
|
2326
|
+
}
|
|
2327
|
+
} else if (storage === "localStorage" || storage === "sessionStorage") {
|
|
2328
|
+
window[storage].setItem(key, JSON.stringify(cacheItem));
|
|
2329
|
+
}
|
|
2330
|
+
} catch (error) {
|
|
2331
|
+
console.error(`Error setting cache item ${key}:`, error);
|
|
2332
|
+
}
|
|
2333
|
+
}
|
|
2334
|
+
/**
|
|
2335
|
+
* Delete item from cache
|
|
2336
|
+
*/
|
|
2337
|
+
delete(key, options) {
|
|
2338
|
+
const storage = options?.storage || "memory";
|
|
2339
|
+
try {
|
|
2340
|
+
if (storage === "memory") {
|
|
2341
|
+
this.memoryCache.delete(key);
|
|
2342
|
+
} else if (storage === "localStorage" || storage === "sessionStorage") {
|
|
2343
|
+
window[storage].removeItem(key);
|
|
2344
|
+
}
|
|
2345
|
+
} catch (error) {
|
|
2346
|
+
console.error(`Error deleting cache item ${key}:`, error);
|
|
2347
|
+
}
|
|
2348
|
+
}
|
|
2349
|
+
/**
|
|
2350
|
+
* Clear all items from cache
|
|
2351
|
+
*/
|
|
2352
|
+
clear(options) {
|
|
2353
|
+
const storage = options?.storage || "memory";
|
|
2354
|
+
try {
|
|
2355
|
+
if (storage === "memory") {
|
|
2356
|
+
this.memoryCache.clear();
|
|
2357
|
+
} else if (storage === "localStorage" || storage === "sessionStorage") {
|
|
2358
|
+
const keys = Object.keys(window[storage]);
|
|
2359
|
+
keys.forEach((key) => {
|
|
2360
|
+
try {
|
|
2361
|
+
const item = window[storage].getItem(key);
|
|
2362
|
+
if (item) {
|
|
2363
|
+
const parsed = JSON.parse(item);
|
|
2364
|
+
if (parsed.timestamp && parsed.expiresAt && parsed.data !== void 0) {
|
|
2365
|
+
window[storage].removeItem(key);
|
|
2366
|
+
}
|
|
2367
|
+
}
|
|
2368
|
+
} catch {
|
|
2369
|
+
}
|
|
2370
|
+
});
|
|
2371
|
+
}
|
|
2372
|
+
} catch (error) {
|
|
2373
|
+
console.error("Error clearing cache:", error);
|
|
2374
|
+
}
|
|
2375
|
+
}
|
|
2376
|
+
/**
|
|
2377
|
+
* Get or set item in cache with a factory function
|
|
2378
|
+
*/
|
|
2379
|
+
async getOrSet(key, factory, options) {
|
|
2380
|
+
const cached = this.get(key, options);
|
|
2381
|
+
if (cached !== null) {
|
|
2382
|
+
return cached;
|
|
2383
|
+
}
|
|
2384
|
+
const data = await factory();
|
|
2385
|
+
this.set(key, data, options);
|
|
2386
|
+
return data;
|
|
2387
|
+
}
|
|
2388
|
+
/**
|
|
2389
|
+
* Invalidate cache entries matching a pattern
|
|
2390
|
+
*/
|
|
2391
|
+
invalidatePattern(pattern, options) {
|
|
2392
|
+
const storage = options?.storage || "memory";
|
|
2393
|
+
const regex = typeof pattern === "string" ? new RegExp(pattern) : pattern;
|
|
2394
|
+
try {
|
|
2395
|
+
if (storage === "memory") {
|
|
2396
|
+
const keysToDelete = [];
|
|
2397
|
+
this.memoryCache.forEach((_, key) => {
|
|
2398
|
+
if (regex.test(key)) {
|
|
2399
|
+
keysToDelete.push(key);
|
|
2400
|
+
}
|
|
2401
|
+
});
|
|
2402
|
+
keysToDelete.forEach((key) => this.memoryCache.delete(key));
|
|
2403
|
+
} else if (storage === "localStorage" || storage === "sessionStorage") {
|
|
2404
|
+
const keys = Object.keys(window[storage]);
|
|
2405
|
+
keys.forEach((key) => {
|
|
2406
|
+
if (regex.test(key)) {
|
|
2407
|
+
window[storage].removeItem(key);
|
|
2408
|
+
}
|
|
2409
|
+
});
|
|
2410
|
+
}
|
|
2411
|
+
} catch (error) {
|
|
2412
|
+
console.error("Error invalidating cache pattern:", error);
|
|
2413
|
+
}
|
|
2414
|
+
}
|
|
2415
|
+
/**
|
|
2416
|
+
* Clean up expired items
|
|
2417
|
+
*/
|
|
2418
|
+
cleanup(options) {
|
|
2419
|
+
const storage = options?.storage || "memory";
|
|
2420
|
+
const now2 = Date.now();
|
|
2421
|
+
try {
|
|
2422
|
+
if (storage === "memory") {
|
|
2423
|
+
const keysToDelete = [];
|
|
2424
|
+
this.memoryCache.forEach((item, key) => {
|
|
2425
|
+
if (now2 > item.expiresAt) {
|
|
2426
|
+
keysToDelete.push(key);
|
|
2427
|
+
}
|
|
2428
|
+
});
|
|
2429
|
+
keysToDelete.forEach((key) => this.memoryCache.delete(key));
|
|
2430
|
+
} else if (storage === "localStorage" || storage === "sessionStorage") {
|
|
2431
|
+
const keys = Object.keys(window[storage]);
|
|
2432
|
+
keys.forEach((key) => {
|
|
2433
|
+
try {
|
|
2434
|
+
const item = window[storage].getItem(key);
|
|
2435
|
+
if (item) {
|
|
2436
|
+
const parsed = JSON.parse(item);
|
|
2437
|
+
if (parsed.expiresAt && now2 > parsed.expiresAt) {
|
|
2438
|
+
window[storage].removeItem(key);
|
|
2439
|
+
}
|
|
2440
|
+
}
|
|
2441
|
+
} catch {
|
|
2442
|
+
}
|
|
2443
|
+
});
|
|
2444
|
+
}
|
|
2445
|
+
} catch (error) {
|
|
2446
|
+
console.error("Error cleaning up cache:", error);
|
|
2447
|
+
}
|
|
2448
|
+
}
|
|
2449
|
+
};
|
|
2450
|
+
var cacheService = new CacheService();
|
|
2451
|
+
if (typeof window !== "undefined") {
|
|
2452
|
+
setInterval(() => {
|
|
2453
|
+
cacheService.cleanup({ storage: "localStorage" });
|
|
2454
|
+
cacheService.cleanup({ storage: "sessionStorage" });
|
|
2455
|
+
cacheService.cleanup({ storage: "memory" });
|
|
2456
|
+
}, 60 * 1e3);
|
|
2457
|
+
}
|
|
2458
|
+
|
|
2459
|
+
// src/lib/services/subscriptionManager.ts
|
|
2460
|
+
var SubscriptionManager = class {
|
|
2461
|
+
constructor(supabase) {
|
|
2462
|
+
this.subscriptions = /* @__PURE__ */ new Map();
|
|
2463
|
+
this.debounceTimers = /* @__PURE__ */ new Map();
|
|
2464
|
+
this.supabase = supabase;
|
|
2465
|
+
}
|
|
2466
|
+
/**
|
|
2467
|
+
* Generate a unique key for a subscription configuration
|
|
2468
|
+
*/
|
|
2469
|
+
generateKey(config) {
|
|
2470
|
+
const { table, schema = "public", event = "*", filter: filter2 = "" } = config;
|
|
2471
|
+
return `${schema}:${table}:${event}:${filter2}`;
|
|
2472
|
+
}
|
|
2473
|
+
/**
|
|
2474
|
+
* Subscribe to real-time changes with automatic deduplication
|
|
2475
|
+
*/
|
|
2476
|
+
subscribe(config) {
|
|
2477
|
+
const key = this.generateKey(config);
|
|
2478
|
+
const existing = this.subscriptions.get(key);
|
|
2479
|
+
if (existing) {
|
|
2480
|
+
existing.configs.push(config);
|
|
2481
|
+
existing.refCount++;
|
|
2482
|
+
console.log(`[SubscriptionManager] Reusing existing subscription for ${key}, refCount: ${existing.refCount}`);
|
|
2483
|
+
return () => this.unsubscribe(key, config.callback);
|
|
2484
|
+
}
|
|
2485
|
+
const channelName = `subscription-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
2486
|
+
const channel = this.supabase.channel(channelName);
|
|
2487
|
+
channel.on(
|
|
2488
|
+
"postgres_changes",
|
|
2489
|
+
{
|
|
2490
|
+
event: config.event || "*",
|
|
2491
|
+
schema: config.schema || "public",
|
|
2492
|
+
table: config.table,
|
|
2493
|
+
...config.filter && { filter: config.filter }
|
|
2494
|
+
},
|
|
2495
|
+
(payload) => {
|
|
2496
|
+
this.debouncedCallback(key, () => {
|
|
2497
|
+
const subscription = this.subscriptions.get(key);
|
|
2498
|
+
if (subscription) {
|
|
2499
|
+
subscription.configs.forEach((cfg) => {
|
|
2500
|
+
try {
|
|
2501
|
+
cfg.callback(payload);
|
|
2502
|
+
} catch (error) {
|
|
2503
|
+
console.error("[SubscriptionManager] Error in callback:", error);
|
|
2504
|
+
}
|
|
2505
|
+
});
|
|
2506
|
+
}
|
|
2507
|
+
});
|
|
2508
|
+
}
|
|
2509
|
+
);
|
|
2510
|
+
channel.subscribe((status) => {
|
|
2511
|
+
console.log(`[SubscriptionManager] Subscription status for ${key}:`, status);
|
|
2512
|
+
});
|
|
2513
|
+
this.subscriptions.set(key, {
|
|
2514
|
+
channel,
|
|
2515
|
+
configs: [config],
|
|
2516
|
+
refCount: 1
|
|
2517
|
+
});
|
|
2518
|
+
console.log(`[SubscriptionManager] Created new subscription for ${key}`);
|
|
2519
|
+
return () => this.unsubscribe(key, config.callback);
|
|
2520
|
+
}
|
|
2521
|
+
/**
|
|
2522
|
+
* Debounce callbacks to prevent excessive updates
|
|
2523
|
+
*/
|
|
2524
|
+
debouncedCallback(key, callback, delay2 = 500) {
|
|
2525
|
+
const existingTimer = this.debounceTimers.get(key);
|
|
2526
|
+
if (existingTimer) {
|
|
2527
|
+
clearTimeout(existingTimer);
|
|
2528
|
+
}
|
|
2529
|
+
const timer = setTimeout(() => {
|
|
2530
|
+
callback();
|
|
2531
|
+
this.debounceTimers.delete(key);
|
|
2532
|
+
}, delay2);
|
|
2533
|
+
this.debounceTimers.set(key, timer);
|
|
2534
|
+
}
|
|
2535
|
+
/**
|
|
2536
|
+
* Unsubscribe from a specific subscription
|
|
2537
|
+
*/
|
|
2538
|
+
unsubscribe(key, callback) {
|
|
2539
|
+
const subscription = this.subscriptions.get(key);
|
|
2540
|
+
if (!subscription) {
|
|
2541
|
+
console.warn(`[SubscriptionManager] No subscription found for key: ${key}`);
|
|
2542
|
+
return;
|
|
2543
|
+
}
|
|
2544
|
+
subscription.configs = subscription.configs.filter((cfg) => cfg.callback !== callback);
|
|
2545
|
+
subscription.refCount--;
|
|
2546
|
+
console.log(`[SubscriptionManager] Unsubscribed from ${key}, refCount: ${subscription.refCount}`);
|
|
2547
|
+
if (subscription.refCount <= 0) {
|
|
2548
|
+
this.supabase.removeChannel(subscription.channel);
|
|
2549
|
+
this.subscriptions.delete(key);
|
|
2550
|
+
const timer = this.debounceTimers.get(key);
|
|
2551
|
+
if (timer) {
|
|
2552
|
+
clearTimeout(timer);
|
|
2553
|
+
this.debounceTimers.delete(key);
|
|
2554
|
+
}
|
|
2555
|
+
console.log(`[SubscriptionManager] Removed subscription for ${key}`);
|
|
2556
|
+
}
|
|
2557
|
+
}
|
|
2558
|
+
/**
|
|
2559
|
+
* Subscribe to multiple tables with a single callback
|
|
2560
|
+
*/
|
|
2561
|
+
subscribeMultiple(configs, callback) {
|
|
2562
|
+
const unsubscribeFunctions = configs.map(
|
|
2563
|
+
(config) => this.subscribe({ ...config, callback })
|
|
2564
|
+
);
|
|
2565
|
+
return () => {
|
|
2566
|
+
unsubscribeFunctions.forEach((fn) => fn());
|
|
2567
|
+
};
|
|
2568
|
+
}
|
|
2569
|
+
/**
|
|
2570
|
+
* Get current subscription statistics
|
|
2571
|
+
*/
|
|
2572
|
+
getStats() {
|
|
2573
|
+
let totalCallbacks = 0;
|
|
2574
|
+
this.subscriptions.forEach((sub) => {
|
|
2575
|
+
totalCallbacks += sub.configs.length;
|
|
2576
|
+
});
|
|
2577
|
+
return {
|
|
2578
|
+
totalSubscriptions: this.subscriptions.size,
|
|
2579
|
+
totalCallbacks
|
|
2580
|
+
};
|
|
2581
|
+
}
|
|
2582
|
+
/**
|
|
2583
|
+
* Clean up all subscriptions
|
|
2584
|
+
*/
|
|
2585
|
+
cleanup() {
|
|
2586
|
+
this.debounceTimers.forEach((timer) => clearTimeout(timer));
|
|
2587
|
+
this.debounceTimers.clear();
|
|
2588
|
+
this.subscriptions.forEach((subscription) => {
|
|
2589
|
+
this.supabase.removeChannel(subscription.channel);
|
|
2590
|
+
});
|
|
2591
|
+
this.subscriptions.clear();
|
|
2592
|
+
console.log("[SubscriptionManager] All subscriptions cleaned up");
|
|
2593
|
+
}
|
|
2594
|
+
};
|
|
2595
|
+
var managerInstance = null;
|
|
2596
|
+
function getSubscriptionManager(supabase) {
|
|
2597
|
+
if (!managerInstance) {
|
|
2598
|
+
managerInstance = new SubscriptionManager(supabase);
|
|
2599
|
+
}
|
|
2600
|
+
return managerInstance;
|
|
2601
|
+
}
|
|
2602
|
+
function resetSubscriptionManager() {
|
|
2603
|
+
if (managerInstance) {
|
|
2604
|
+
managerInstance.cleanup();
|
|
2605
|
+
managerInstance = null;
|
|
2606
|
+
}
|
|
2607
|
+
}
|
|
2072
2608
|
var AuthContext = createContext({
|
|
2073
2609
|
session: null,
|
|
2074
2610
|
user: null,
|
|
@@ -2288,6 +2824,36 @@ var useSupabase = () => {
|
|
|
2288
2824
|
}
|
|
2289
2825
|
return context.supabase;
|
|
2290
2826
|
};
|
|
2827
|
+
var SubscriptionManagerContext = createContext({
|
|
2828
|
+
subscriptionManager: null
|
|
2829
|
+
});
|
|
2830
|
+
var SubscriptionManagerProvider = ({ children }) => {
|
|
2831
|
+
const supabase = useSupabase();
|
|
2832
|
+
const subscriptionManager = useMemo(() => {
|
|
2833
|
+
if (!supabase) return null;
|
|
2834
|
+
return getSubscriptionManager(supabase);
|
|
2835
|
+
}, [supabase]);
|
|
2836
|
+
useEffect(() => {
|
|
2837
|
+
return () => {
|
|
2838
|
+
if (subscriptionManager) {
|
|
2839
|
+
console.log("[SubscriptionManagerProvider] Cleaning up subscriptions");
|
|
2840
|
+
subscriptionManager.cleanup();
|
|
2841
|
+
}
|
|
2842
|
+
};
|
|
2843
|
+
}, [subscriptionManager]);
|
|
2844
|
+
return /* @__PURE__ */ jsx(SubscriptionManagerContext.Provider, { value: { subscriptionManager }, children });
|
|
2845
|
+
};
|
|
2846
|
+
var useSubscriptionManager = () => {
|
|
2847
|
+
const { subscriptionManager } = useContext(SubscriptionManagerContext);
|
|
2848
|
+
if (!subscriptionManager) {
|
|
2849
|
+
throw new Error("useSubscriptionManager must be used within a SubscriptionManagerProvider");
|
|
2850
|
+
}
|
|
2851
|
+
return subscriptionManager;
|
|
2852
|
+
};
|
|
2853
|
+
var useSubscriptionManagerSafe = () => {
|
|
2854
|
+
const { subscriptionManager } = useContext(SubscriptionManagerContext);
|
|
2855
|
+
return subscriptionManager;
|
|
2856
|
+
};
|
|
2291
2857
|
var DEFAULT_COMPANY_ID = "default-company-id";
|
|
2292
2858
|
var useWorkspaceMetrics = (workspaceId) => {
|
|
2293
2859
|
const supabase = useSupabase();
|
|
@@ -2544,7 +3110,7 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
|
|
|
2544
3110
|
const defaultTimezone = dateTimeConfig.defaultTimezone;
|
|
2545
3111
|
const workspaceMetricsBaseTable = databaseConfig.tables?.workspaces ?? "workspace_metrics";
|
|
2546
3112
|
const workspaceActionsTable = databaseConfig.tables?.actions ?? "workspace_actions";
|
|
2547
|
-
const fetchMetrics = useCallback(async () => {
|
|
3113
|
+
const fetchMetrics = useCallback(async (skipCache = false) => {
|
|
2548
3114
|
if (!workspaceId || isFetchingRef.current) return;
|
|
2549
3115
|
try {
|
|
2550
3116
|
isFetchingRef.current = true;
|
|
@@ -2553,6 +3119,28 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
|
|
|
2553
3119
|
const queryShiftId = shiftId !== void 0 ? shiftId : currentShift.shiftId;
|
|
2554
3120
|
console.log("[useWorkspaceDetailedMetrics] Using shift ID:", queryShiftId, "from input shift:", shiftId);
|
|
2555
3121
|
console.log("[useWorkspaceDetailedMetrics] Using date:", queryDate, "from input date:", date);
|
|
3122
|
+
const cacheKey = cacheService.generateKey(
|
|
3123
|
+
"workspace-detailed-metrics",
|
|
3124
|
+
workspaceId,
|
|
3125
|
+
queryDate,
|
|
3126
|
+
queryShiftId,
|
|
3127
|
+
companyId
|
|
3128
|
+
);
|
|
3129
|
+
if (!skipCache) {
|
|
3130
|
+
const cachedData = cacheService.get(cacheKey, {
|
|
3131
|
+
storage: "memory",
|
|
3132
|
+
duration: 5 * 60 * 1e3
|
|
3133
|
+
// 5 minutes
|
|
3134
|
+
});
|
|
3135
|
+
if (cachedData) {
|
|
3136
|
+
console.log("[useWorkspaceDetailedMetrics] Using cached data for:", cacheKey);
|
|
3137
|
+
setMetrics(cachedData);
|
|
3138
|
+
setIsLoading(false);
|
|
3139
|
+
updateQueueRef.current = false;
|
|
3140
|
+
isFetchingRef.current = false;
|
|
3141
|
+
return;
|
|
3142
|
+
}
|
|
3143
|
+
}
|
|
2556
3144
|
console.log(`[useWorkspaceDetailedMetrics] Querying ${metricsTable} for workspace: ${workspaceId}, date: ${queryDate}, shift: ${queryShiftId}`);
|
|
2557
3145
|
const { data, error: fetchError } = await supabase.from(metricsTable).select("*").eq("workspace_id", workspaceId).eq("date", queryDate).eq("shift_id", queryShiftId).maybeSingle();
|
|
2558
3146
|
if (fetchError) throw fetchError;
|
|
@@ -2655,6 +3243,18 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
|
|
|
2655
3243
|
setIsLoading(false);
|
|
2656
3244
|
updateQueueRef.current = false;
|
|
2657
3245
|
isFetchingRef.current = false;
|
|
3246
|
+
const fallbackCacheKey = cacheService.generateKey(
|
|
3247
|
+
"workspace-detailed-metrics",
|
|
3248
|
+
workspaceId,
|
|
3249
|
+
recentData.date,
|
|
3250
|
+
recentData.shift_id,
|
|
3251
|
+
companyId
|
|
3252
|
+
);
|
|
3253
|
+
cacheService.set(fallbackCacheKey, transformedData2, {
|
|
3254
|
+
storage: "memory",
|
|
3255
|
+
duration: 2 * 60 * 1e3
|
|
3256
|
+
// 2 minutes for fallback data
|
|
3257
|
+
});
|
|
2658
3258
|
return;
|
|
2659
3259
|
} else {
|
|
2660
3260
|
console.warn("[useWorkspaceDetailedMetrics] No data found for workspace:", workspaceId, "at all");
|
|
@@ -2768,6 +3368,11 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
|
|
|
2768
3368
|
...data.sop_check !== void 0 && { sop_check: data.sop_check }
|
|
2769
3369
|
};
|
|
2770
3370
|
setMetrics(transformedData);
|
|
3371
|
+
cacheService.set(cacheKey, transformedData, {
|
|
3372
|
+
storage: "memory",
|
|
3373
|
+
duration: 5 * 60 * 1e3
|
|
3374
|
+
// 5 minutes
|
|
3375
|
+
});
|
|
2771
3376
|
} catch (err) {
|
|
2772
3377
|
console.error("Error fetching workspace metrics:", err);
|
|
2773
3378
|
setError({ message: err.message, code: err.code });
|
|
@@ -2802,7 +3407,7 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
|
|
|
2802
3407
|
},
|
|
2803
3408
|
async (payload) => {
|
|
2804
3409
|
console.log(`Received ${metricsTablePrefix} update:`, payload);
|
|
2805
|
-
await fetchMetrics();
|
|
3410
|
+
await fetchMetrics(true);
|
|
2806
3411
|
}
|
|
2807
3412
|
).subscribe((status) => {
|
|
2808
3413
|
console.log(`Workspace detailed metrics subscription status:`, status);
|
|
@@ -2836,6 +3441,14 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
|
|
|
2836
3441
|
matches: payloadData?.date === operationalDate && payloadData?.shift_id === queryShiftId
|
|
2837
3442
|
});
|
|
2838
3443
|
if (payloadData?.date === operationalDate && payloadData?.shift_id === queryShiftId) {
|
|
3444
|
+
const cacheKey = cacheService.generateKey(
|
|
3445
|
+
"workspace-detailed-metrics",
|
|
3446
|
+
workspaceId,
|
|
3447
|
+
operationalDate,
|
|
3448
|
+
queryShiftId,
|
|
3449
|
+
companyId
|
|
3450
|
+
);
|
|
3451
|
+
cacheService.delete(cacheKey, { storage: "memory" });
|
|
2839
3452
|
queueUpdate();
|
|
2840
3453
|
}
|
|
2841
3454
|
}
|
|
@@ -2861,6 +3474,14 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
|
|
|
2861
3474
|
matches: payloadData?.date === operationalDate && payloadData?.shift_id === queryShiftId
|
|
2862
3475
|
});
|
|
2863
3476
|
if (payloadData?.date === operationalDate && payloadData?.shift_id === queryShiftId) {
|
|
3477
|
+
const cacheKey = cacheService.generateKey(
|
|
3478
|
+
"workspace-detailed-metrics",
|
|
3479
|
+
workspaceId,
|
|
3480
|
+
operationalDate,
|
|
3481
|
+
queryShiftId,
|
|
3482
|
+
companyId
|
|
3483
|
+
);
|
|
3484
|
+
cacheService.delete(cacheKey, { storage: "memory" });
|
|
2864
3485
|
queueUpdate();
|
|
2865
3486
|
}
|
|
2866
3487
|
}
|
|
@@ -2886,6 +3507,14 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
|
|
|
2886
3507
|
matches: payloadData?.date === operationalDate && payloadData?.shift_id === queryShiftId
|
|
2887
3508
|
});
|
|
2888
3509
|
if (payloadData?.date === operationalDate && payloadData?.shift_id === queryShiftId) {
|
|
3510
|
+
const cacheKey = cacheService.generateKey(
|
|
3511
|
+
"workspace-detailed-metrics",
|
|
3512
|
+
workspaceId,
|
|
3513
|
+
operationalDate,
|
|
3514
|
+
queryShiftId,
|
|
3515
|
+
companyId
|
|
3516
|
+
);
|
|
3517
|
+
cacheService.delete(cacheKey, { storage: "memory" });
|
|
2889
3518
|
queueUpdate();
|
|
2890
3519
|
}
|
|
2891
3520
|
}
|
|
@@ -2912,7 +3541,8 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
|
|
|
2912
3541
|
metrics: metrics2,
|
|
2913
3542
|
isLoading,
|
|
2914
3543
|
error,
|
|
2915
|
-
refetch: fetchMetrics
|
|
3544
|
+
refetch: () => fetchMetrics(true)
|
|
3545
|
+
// Force refresh without cache
|
|
2916
3546
|
};
|
|
2917
3547
|
};
|
|
2918
3548
|
var useLineWorkspaceMetrics = (lineId, options) => {
|
|
@@ -5129,19 +5759,39 @@ var useActiveBreaks = (lineIds) => {
|
|
|
5129
5759
|
let breaks = [];
|
|
5130
5760
|
if (activeShift.breaks) {
|
|
5131
5761
|
if (Array.isArray(activeShift.breaks)) {
|
|
5132
|
-
breaks = activeShift.breaks.map((breakItem) =>
|
|
5133
|
-
startTime
|
|
5134
|
-
endTime
|
|
5135
|
-
duration
|
|
5136
|
-
|
|
5137
|
-
|
|
5762
|
+
breaks = activeShift.breaks.map((breakItem) => {
|
|
5763
|
+
const startTime = breakItem.start || breakItem.startTime || "00:00";
|
|
5764
|
+
const endTime = breakItem.end || breakItem.endTime || "00:00";
|
|
5765
|
+
let duration = breakItem.duration || 0;
|
|
5766
|
+
if (!duration || duration === 0) {
|
|
5767
|
+
const startMinutes = parseTimeToMinutes2(startTime);
|
|
5768
|
+
const endMinutes = parseTimeToMinutes2(endTime);
|
|
5769
|
+
duration = endMinutes < startMinutes ? endMinutes + 24 * 60 - startMinutes : endMinutes - startMinutes;
|
|
5770
|
+
}
|
|
5771
|
+
return {
|
|
5772
|
+
startTime,
|
|
5773
|
+
endTime,
|
|
5774
|
+
duration,
|
|
5775
|
+
remarks: breakItem.remarks || breakItem.name || ""
|
|
5776
|
+
};
|
|
5777
|
+
});
|
|
5138
5778
|
} else if (activeShift.breaks.breaks && Array.isArray(activeShift.breaks.breaks)) {
|
|
5139
|
-
breaks = activeShift.breaks.breaks.map((breakItem) =>
|
|
5140
|
-
startTime
|
|
5141
|
-
endTime
|
|
5142
|
-
duration
|
|
5143
|
-
|
|
5144
|
-
|
|
5779
|
+
breaks = activeShift.breaks.breaks.map((breakItem) => {
|
|
5780
|
+
const startTime = breakItem.start || breakItem.startTime || "00:00";
|
|
5781
|
+
const endTime = breakItem.end || breakItem.endTime || "00:00";
|
|
5782
|
+
let duration = breakItem.duration || 0;
|
|
5783
|
+
if (!duration || duration === 0) {
|
|
5784
|
+
const startMinutes = parseTimeToMinutes2(startTime);
|
|
5785
|
+
const endMinutes = parseTimeToMinutes2(endTime);
|
|
5786
|
+
duration = endMinutes < startMinutes ? endMinutes + 24 * 60 - startMinutes : endMinutes - startMinutes;
|
|
5787
|
+
}
|
|
5788
|
+
return {
|
|
5789
|
+
startTime,
|
|
5790
|
+
endTime,
|
|
5791
|
+
duration,
|
|
5792
|
+
remarks: breakItem.remarks || breakItem.name || ""
|
|
5793
|
+
};
|
|
5794
|
+
});
|
|
5145
5795
|
}
|
|
5146
5796
|
}
|
|
5147
5797
|
for (const breakItem of breaks) {
|
|
@@ -5203,12 +5853,32 @@ var useAllWorkspaceMetrics = (options) => {
|
|
|
5203
5853
|
return `${metricsTablePrefix}_${companyId.replace(/-/g, "_")}`;
|
|
5204
5854
|
}, [entityConfig.companyId]);
|
|
5205
5855
|
const schema = databaseConfig.schema ?? "public";
|
|
5206
|
-
const fetchWorkspaceMetrics = useCallback(async () => {
|
|
5856
|
+
const fetchWorkspaceMetrics = useCallback(async (skipCache = false) => {
|
|
5207
5857
|
if (!initialized) {
|
|
5208
5858
|
setLoading(true);
|
|
5209
5859
|
}
|
|
5210
5860
|
setError(null);
|
|
5211
5861
|
try {
|
|
5862
|
+
const cacheKey = cacheService.generateKey(
|
|
5863
|
+
"all-workspace-metrics",
|
|
5864
|
+
entityConfig.companyId,
|
|
5865
|
+
queryDate,
|
|
5866
|
+
queryShiftId
|
|
5867
|
+
);
|
|
5868
|
+
if (!skipCache && !loading) {
|
|
5869
|
+
const cachedData = cacheService.get(cacheKey, {
|
|
5870
|
+
storage: "memory",
|
|
5871
|
+
duration: 5 * 60 * 1e3
|
|
5872
|
+
// 5 minutes
|
|
5873
|
+
});
|
|
5874
|
+
if (cachedData) {
|
|
5875
|
+
console.log("[useAllWorkspaceMetrics] Using cached data for:", cacheKey);
|
|
5876
|
+
setWorkspaces(cachedData);
|
|
5877
|
+
setInitialized(true);
|
|
5878
|
+
setLoading(false);
|
|
5879
|
+
return;
|
|
5880
|
+
}
|
|
5881
|
+
}
|
|
5212
5882
|
console.log("Fetching all workspace metrics with params:", {
|
|
5213
5883
|
queryDate,
|
|
5214
5884
|
queryShiftId,
|
|
@@ -5245,6 +5915,11 @@ var useAllWorkspaceMetrics = (options) => {
|
|
|
5245
5915
|
}));
|
|
5246
5916
|
setWorkspaces(transformedData);
|
|
5247
5917
|
setInitialized(true);
|
|
5918
|
+
cacheService.set(cacheKey, transformedData, {
|
|
5919
|
+
storage: "memory",
|
|
5920
|
+
duration: 5 * 60 * 1e3
|
|
5921
|
+
// 5 minutes
|
|
5922
|
+
});
|
|
5248
5923
|
} catch (err) {
|
|
5249
5924
|
console.error("Error fetching all workspace metrics:", err);
|
|
5250
5925
|
setError({ message: err.message, code: err.code || "FETCH_ERROR" });
|
|
@@ -5269,7 +5944,14 @@ var useAllWorkspaceMetrics = (options) => {
|
|
|
5269
5944
|
},
|
|
5270
5945
|
async (payload) => {
|
|
5271
5946
|
console.log("All workspace metrics update received:", payload);
|
|
5272
|
-
|
|
5947
|
+
const cacheKey = cacheService.generateKey(
|
|
5948
|
+
"all-workspace-metrics",
|
|
5949
|
+
entityConfig.companyId,
|
|
5950
|
+
queryDate,
|
|
5951
|
+
queryShiftId
|
|
5952
|
+
);
|
|
5953
|
+
cacheService.delete(cacheKey, { storage: "memory" });
|
|
5954
|
+
await fetchWorkspaceMetrics(true);
|
|
5273
5955
|
}
|
|
5274
5956
|
).subscribe();
|
|
5275
5957
|
return channel2;
|
|
@@ -5280,16 +5962,80 @@ var useAllWorkspaceMetrics = (options) => {
|
|
|
5280
5962
|
supabase.removeChannel(channel);
|
|
5281
5963
|
}
|
|
5282
5964
|
};
|
|
5283
|
-
}, [queryDate, queryShiftId, metricsTable, fetchWorkspaceMetrics, initialized, supabase, schema]);
|
|
5965
|
+
}, [queryDate, queryShiftId, metricsTable, fetchWorkspaceMetrics, initialized, supabase, schema, entityConfig.companyId]);
|
|
5284
5966
|
useEffect(() => {
|
|
5285
5967
|
setInitialized(false);
|
|
5286
5968
|
}, [queryDate, queryShiftId]);
|
|
5287
|
-
const refreshWorkspaces = fetchWorkspaceMetrics;
|
|
5969
|
+
const refreshWorkspaces = useCallback(() => fetchWorkspaceMetrics(true), [fetchWorkspaceMetrics]);
|
|
5288
5970
|
return useMemo(
|
|
5289
5971
|
() => ({ workspaces, loading, error, refreshWorkspaces }),
|
|
5290
5972
|
[workspaces, loading, error, refreshWorkspaces]
|
|
5291
5973
|
);
|
|
5292
5974
|
};
|
|
5975
|
+
var useSKUs = (companyId) => {
|
|
5976
|
+
const [skus, setSKUs] = useState([]);
|
|
5977
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
5978
|
+
const [error, setError] = useState(null);
|
|
5979
|
+
const supabase = useSupabase();
|
|
5980
|
+
const config = useDashboardConfig();
|
|
5981
|
+
const dbConfig = config?.databaseConfig;
|
|
5982
|
+
const skusTable = dbConfig?.tables?.skus || "skus";
|
|
5983
|
+
const fetchSKUs = useCallback(async () => {
|
|
5984
|
+
if (!companyId) {
|
|
5985
|
+
setIsLoading(false);
|
|
5986
|
+
return;
|
|
5987
|
+
}
|
|
5988
|
+
try {
|
|
5989
|
+
setIsLoading(true);
|
|
5990
|
+
setError(null);
|
|
5991
|
+
const data = await skuService.getSKUs(companyId);
|
|
5992
|
+
setSKUs(data);
|
|
5993
|
+
} catch (err) {
|
|
5994
|
+
setError(err instanceof Error ? err : new Error("Failed to fetch SKUs"));
|
|
5995
|
+
console.error("Error fetching SKUs:", err);
|
|
5996
|
+
} finally {
|
|
5997
|
+
setIsLoading(false);
|
|
5998
|
+
}
|
|
5999
|
+
}, [companyId]);
|
|
6000
|
+
useEffect(() => {
|
|
6001
|
+
fetchSKUs();
|
|
6002
|
+
}, [fetchSKUs]);
|
|
6003
|
+
useEffect(() => {
|
|
6004
|
+
if (!supabase || !companyId) return;
|
|
6005
|
+
const channel = supabase.channel(`skus:${companyId}`).on(
|
|
6006
|
+
"postgres_changes",
|
|
6007
|
+
{
|
|
6008
|
+
event: "*",
|
|
6009
|
+
schema: dbConfig?.schema || "public",
|
|
6010
|
+
table: skusTable,
|
|
6011
|
+
filter: `company_id=eq.${companyId}`
|
|
6012
|
+
},
|
|
6013
|
+
(payload) => {
|
|
6014
|
+
console.log("SKU change received:", payload);
|
|
6015
|
+
if (payload.eventType === "INSERT") {
|
|
6016
|
+
setSKUs((prev) => [...prev, payload.new]);
|
|
6017
|
+
} else if (payload.eventType === "UPDATE") {
|
|
6018
|
+
setSKUs(
|
|
6019
|
+
(prev) => prev.map(
|
|
6020
|
+
(sku) => sku.id === payload.new.id ? payload.new : sku
|
|
6021
|
+
)
|
|
6022
|
+
);
|
|
6023
|
+
} else if (payload.eventType === "DELETE") {
|
|
6024
|
+
setSKUs((prev) => prev.filter((sku) => sku.id !== payload.old.id));
|
|
6025
|
+
}
|
|
6026
|
+
}
|
|
6027
|
+
).subscribe();
|
|
6028
|
+
return () => {
|
|
6029
|
+
supabase.removeChannel(channel);
|
|
6030
|
+
};
|
|
6031
|
+
}, [supabase, companyId, dbConfig?.schema, skusTable]);
|
|
6032
|
+
return {
|
|
6033
|
+
skus,
|
|
6034
|
+
isLoading,
|
|
6035
|
+
error,
|
|
6036
|
+
refetch: fetchSKUs
|
|
6037
|
+
};
|
|
6038
|
+
};
|
|
5293
6039
|
var MAX_RETRIES = 10;
|
|
5294
6040
|
var RETRY_DELAY = 500;
|
|
5295
6041
|
function useNavigation(customNavigate) {
|
|
@@ -8521,7 +9267,7 @@ var MotionConfigContext = createContext({
|
|
|
8521
9267
|
});
|
|
8522
9268
|
|
|
8523
9269
|
// ../../node_modules/framer-motion/dist/es/components/AnimatePresence/PopChild.mjs
|
|
8524
|
-
var PopChildMeasure = class extends
|
|
9270
|
+
var PopChildMeasure = class extends React19.Component {
|
|
8525
9271
|
getSnapshotBeforeUpdate(prevProps) {
|
|
8526
9272
|
const element = this.props.childRef.current;
|
|
8527
9273
|
if (element && prevProps.isPresent && !this.props.isPresent) {
|
|
@@ -8576,7 +9322,7 @@ function PopChild({ children, isPresent }) {
|
|
|
8576
9322
|
document.head.removeChild(style);
|
|
8577
9323
|
};
|
|
8578
9324
|
}, [isPresent]);
|
|
8579
|
-
return jsx(PopChildMeasure, { isPresent, childRef: ref, sizeRef: size, children:
|
|
9325
|
+
return jsx(PopChildMeasure, { isPresent, childRef: ref, sizeRef: size, children: React19.cloneElement(children, { ref }) });
|
|
8580
9326
|
}
|
|
8581
9327
|
|
|
8582
9328
|
// ../../node_modules/framer-motion/dist/es/components/AnimatePresence/PresenceChild.mjs
|
|
@@ -8613,7 +9359,7 @@ var PresenceChild = ({ children, initial, isPresent, onExitComplete, custom, pre
|
|
|
8613
9359
|
useMemo(() => {
|
|
8614
9360
|
presenceChildren.forEach((_, key) => presenceChildren.set(key, false));
|
|
8615
9361
|
}, [isPresent]);
|
|
8616
|
-
|
|
9362
|
+
React19.useEffect(() => {
|
|
8617
9363
|
!isPresent && !presenceChildren.size && onExitComplete && onExitComplete();
|
|
8618
9364
|
}, [isPresent]);
|
|
8619
9365
|
if (mode === "popLayout") {
|
|
@@ -10020,7 +10766,7 @@ function removeItem(arr, item) {
|
|
|
10020
10766
|
}
|
|
10021
10767
|
|
|
10022
10768
|
// ../../node_modules/framer-motion/dist/es/utils/subscription-manager.mjs
|
|
10023
|
-
var
|
|
10769
|
+
var SubscriptionManager3 = class {
|
|
10024
10770
|
constructor() {
|
|
10025
10771
|
this.subscriptions = [];
|
|
10026
10772
|
}
|
|
@@ -10149,7 +10895,7 @@ var MotionValue = class {
|
|
|
10149
10895
|
}
|
|
10150
10896
|
on(eventName, callback) {
|
|
10151
10897
|
if (!this.events[eventName]) {
|
|
10152
|
-
this.events[eventName] = new
|
|
10898
|
+
this.events[eventName] = new SubscriptionManager3();
|
|
10153
10899
|
}
|
|
10154
10900
|
const unsubscribe = this.events[eventName].add(callback);
|
|
10155
10901
|
if (eventName === "change") {
|
|
@@ -14143,7 +14889,7 @@ function createProjectionNode2({ attachResizeListener, defaultParent, measureScr
|
|
|
14143
14889
|
}
|
|
14144
14890
|
addEventListener(name, handler) {
|
|
14145
14891
|
if (!this.eventHandlers.has(name)) {
|
|
14146
|
-
this.eventHandlers.set(name, new
|
|
14892
|
+
this.eventHandlers.set(name, new SubscriptionManager3());
|
|
14147
14893
|
}
|
|
14148
14894
|
return this.eventHandlers.get(name).add(handler);
|
|
14149
14895
|
}
|
|
@@ -15733,7 +16479,7 @@ var VisualElement = class {
|
|
|
15733
16479
|
}
|
|
15734
16480
|
on(eventName, callback) {
|
|
15735
16481
|
if (!this.events[eventName]) {
|
|
15736
|
-
this.events[eventName] = new
|
|
16482
|
+
this.events[eventName] = new SubscriptionManager3();
|
|
15737
16483
|
}
|
|
15738
16484
|
return this.events[eventName].add(callback);
|
|
15739
16485
|
}
|
|
@@ -15882,7 +16628,7 @@ var LoadingPage = ({
|
|
|
15882
16628
|
subMessage = "Please wait while we prepare your data",
|
|
15883
16629
|
className
|
|
15884
16630
|
}) => {
|
|
15885
|
-
|
|
16631
|
+
React19__default.useEffect(() => {
|
|
15886
16632
|
console.log("LoadingPage rendered with message:", message);
|
|
15887
16633
|
const timeout = setTimeout(() => {
|
|
15888
16634
|
console.warn("LoadingPage has been visible for more than 8 seconds. This might indicate an issue.");
|
|
@@ -15925,10 +16671,10 @@ var withAuth = (WrappedComponent2, options) => {
|
|
|
15925
16671
|
return function WithAuthComponent(props) {
|
|
15926
16672
|
const { session, loading } = useAuth();
|
|
15927
16673
|
const router = useRouter();
|
|
15928
|
-
|
|
16674
|
+
React19.useEffect(() => {
|
|
15929
16675
|
console.log("withAuth state:", { loading, hasSession: !!session, requireAuth: defaultOptions.requireAuth });
|
|
15930
16676
|
}, [session, loading]);
|
|
15931
|
-
|
|
16677
|
+
React19.useEffect(() => {
|
|
15932
16678
|
if (!loading && defaultOptions.requireAuth && !session) {
|
|
15933
16679
|
console.log("Redirecting to login from withAuth");
|
|
15934
16680
|
router.replace(defaultOptions.redirectTo);
|
|
@@ -16256,7 +17002,7 @@ var DebugAuth = () => {
|
|
|
16256
17002
|
] }) });
|
|
16257
17003
|
};
|
|
16258
17004
|
var DEFAULT_BAR_RADIUS = [4, 4, 0, 0];
|
|
16259
|
-
var
|
|
17005
|
+
var BarChartComponent = ({
|
|
16260
17006
|
data,
|
|
16261
17007
|
bars,
|
|
16262
17008
|
xAxisDataKey = "name",
|
|
@@ -16344,7 +17090,35 @@ var BarChart = ({
|
|
|
16344
17090
|
}
|
|
16345
17091
|
return /* @__PURE__ */ jsx("div", { className: clsx("w-full", className), children: chartContent });
|
|
16346
17092
|
};
|
|
16347
|
-
var
|
|
17093
|
+
var BarChart = React19__default.memo(BarChartComponent, (prevProps, nextProps) => {
|
|
17094
|
+
if (prevProps.xAxisDataKey !== nextProps.xAxisDataKey || prevProps.xAxisLabel !== nextProps.xAxisLabel || prevProps.yAxisLabel !== nextProps.yAxisLabel || prevProps.yAxisUnit !== nextProps.yAxisUnit || 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) {
|
|
17095
|
+
return false;
|
|
17096
|
+
}
|
|
17097
|
+
if (prevProps.data.length !== nextProps.data.length) {
|
|
17098
|
+
return false;
|
|
17099
|
+
}
|
|
17100
|
+
if (!prevProps.data.every((item, idx) => {
|
|
17101
|
+
const nextItem = nextProps.data[idx];
|
|
17102
|
+
return Object.keys(item).every((key) => item[key] === nextItem[key]);
|
|
17103
|
+
})) {
|
|
17104
|
+
return false;
|
|
17105
|
+
}
|
|
17106
|
+
if (prevProps.bars.length !== nextProps.bars.length) {
|
|
17107
|
+
return false;
|
|
17108
|
+
}
|
|
17109
|
+
if (!prevProps.bars.every((bar, idx) => {
|
|
17110
|
+
const nextBar = nextProps.bars[idx];
|
|
17111
|
+
return bar.dataKey === nextBar.dataKey && bar.name === nextBar.name && bar.fill === nextBar.fill && JSON.stringify(bar.radius) === JSON.stringify(nextBar.radius) && bar.labelList === nextBar.labelList;
|
|
17112
|
+
})) {
|
|
17113
|
+
return false;
|
|
17114
|
+
}
|
|
17115
|
+
if (prevProps.tooltipFormatter !== nextProps.tooltipFormatter || JSON.stringify(prevProps.legendPayload) !== JSON.stringify(nextProps.legendPayload)) {
|
|
17116
|
+
return false;
|
|
17117
|
+
}
|
|
17118
|
+
return true;
|
|
17119
|
+
});
|
|
17120
|
+
BarChart.displayName = "BarChart";
|
|
17121
|
+
var LineChartComponent = ({
|
|
16348
17122
|
data,
|
|
16349
17123
|
lines,
|
|
16350
17124
|
xAxisDataKey = "name",
|
|
@@ -16435,7 +17209,35 @@ var LineChart = ({
|
|
|
16435
17209
|
}
|
|
16436
17210
|
return /* @__PURE__ */ jsx("div", { className: clsx("w-full", className), children: chartContent });
|
|
16437
17211
|
};
|
|
16438
|
-
var
|
|
17212
|
+
var LineChart = React19__default.memo(LineChartComponent, (prevProps, nextProps) => {
|
|
17213
|
+
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)) {
|
|
17214
|
+
return false;
|
|
17215
|
+
}
|
|
17216
|
+
if (prevProps.data.length !== nextProps.data.length) {
|
|
17217
|
+
return false;
|
|
17218
|
+
}
|
|
17219
|
+
if (!prevProps.data.every((item, idx) => {
|
|
17220
|
+
const nextItem = nextProps.data[idx];
|
|
17221
|
+
return Object.keys(item).every((key) => item[key] === nextItem[key]);
|
|
17222
|
+
})) {
|
|
17223
|
+
return false;
|
|
17224
|
+
}
|
|
17225
|
+
if (prevProps.lines.length !== nextProps.lines.length) {
|
|
17226
|
+
return false;
|
|
17227
|
+
}
|
|
17228
|
+
if (!prevProps.lines.every((line, idx) => {
|
|
17229
|
+
const nextLine = nextProps.lines[idx];
|
|
17230
|
+
return line.dataKey === nextLine.dataKey && line.name === nextLine.name && line.stroke === nextLine.stroke && line.strokeWidth === nextLine.strokeWidth && line.type === nextLine.type && JSON.stringify(line.dot) === JSON.stringify(nextLine.dot) && JSON.stringify(line.activeDot) === JSON.stringify(nextLine.activeDot) && line.labelList === nextLine.labelList;
|
|
17231
|
+
})) {
|
|
17232
|
+
return false;
|
|
17233
|
+
}
|
|
17234
|
+
if (prevProps.tooltipFormatter !== nextProps.tooltipFormatter || prevProps.xAxisTickFormatter !== nextProps.xAxisTickFormatter || JSON.stringify(prevProps.legendPayload) !== JSON.stringify(nextProps.legendPayload)) {
|
|
17235
|
+
return false;
|
|
17236
|
+
}
|
|
17237
|
+
return true;
|
|
17238
|
+
});
|
|
17239
|
+
LineChart.displayName = "LineChart";
|
|
17240
|
+
var OutputProgressChartComponent = ({
|
|
16439
17241
|
currentOutput,
|
|
16440
17242
|
targetOutput,
|
|
16441
17243
|
className = ""
|
|
@@ -16484,6 +17286,8 @@ var OutputProgressChart = ({
|
|
|
16484
17286
|
] }) })
|
|
16485
17287
|
] }) });
|
|
16486
17288
|
};
|
|
17289
|
+
var OutputProgressChart = React19__default.memo(OutputProgressChartComponent);
|
|
17290
|
+
OutputProgressChart.displayName = "OutputProgressChart";
|
|
16487
17291
|
var LargeOutputProgressChart = ({
|
|
16488
17292
|
currentOutput,
|
|
16489
17293
|
targetOutput,
|
|
@@ -16533,7 +17337,7 @@ var LargeOutputProgressChart = ({
|
|
|
16533
17337
|
] }) })
|
|
16534
17338
|
] }) });
|
|
16535
17339
|
};
|
|
16536
|
-
var
|
|
17340
|
+
var CycleTimeChartComponent = ({
|
|
16537
17341
|
data = [],
|
|
16538
17342
|
className = ""
|
|
16539
17343
|
}) => {
|
|
@@ -16598,6 +17402,25 @@ var CycleTimeChart = ({
|
|
|
16598
17402
|
}
|
|
16599
17403
|
) }) });
|
|
16600
17404
|
};
|
|
17405
|
+
var CycleTimeChart = React19__default.memo(CycleTimeChartComponent, (prevProps, nextProps) => {
|
|
17406
|
+
if (prevProps.className !== nextProps.className) {
|
|
17407
|
+
return false;
|
|
17408
|
+
}
|
|
17409
|
+
if (!prevProps.data && !nextProps.data) {
|
|
17410
|
+
return true;
|
|
17411
|
+
}
|
|
17412
|
+
if (!prevProps.data || !nextProps.data) {
|
|
17413
|
+
return false;
|
|
17414
|
+
}
|
|
17415
|
+
if (prevProps.data.length !== nextProps.data.length) {
|
|
17416
|
+
return false;
|
|
17417
|
+
}
|
|
17418
|
+
return prevProps.data.every((item, index) => {
|
|
17419
|
+
const nextItem = nextProps.data[index];
|
|
17420
|
+
return item.time === nextItem.time && item.value === nextItem.value;
|
|
17421
|
+
});
|
|
17422
|
+
});
|
|
17423
|
+
CycleTimeChart.displayName = "CycleTimeChart";
|
|
16601
17424
|
var CycleTimeOverTimeChart = ({
|
|
16602
17425
|
data,
|
|
16603
17426
|
idealCycleTime,
|
|
@@ -16615,10 +17438,10 @@ var CycleTimeOverTimeChart = ({
|
|
|
16615
17438
|
};
|
|
16616
17439
|
const displayData = getDisplayData(data);
|
|
16617
17440
|
const DURATION = displayData.length;
|
|
16618
|
-
const [animatedData, setAnimatedData] =
|
|
16619
|
-
const prevDataRef =
|
|
16620
|
-
const animationFrameRef =
|
|
16621
|
-
const animateToNewData =
|
|
17441
|
+
const [animatedData, setAnimatedData] = React19__default.useState(Array(DURATION).fill(0));
|
|
17442
|
+
const prevDataRef = React19__default.useRef(Array(DURATION).fill(0));
|
|
17443
|
+
const animationFrameRef = React19__default.useRef(null);
|
|
17444
|
+
const animateToNewData = React19__default.useCallback((targetData) => {
|
|
16622
17445
|
const startData = [...prevDataRef.current];
|
|
16623
17446
|
const startTime = performance.now();
|
|
16624
17447
|
const duration = 1200;
|
|
@@ -16648,7 +17471,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
16648
17471
|
}
|
|
16649
17472
|
animationFrameRef.current = requestAnimationFrame(animate);
|
|
16650
17473
|
}, []);
|
|
16651
|
-
|
|
17474
|
+
React19__default.useEffect(() => {
|
|
16652
17475
|
if (JSON.stringify(data) !== JSON.stringify(prevDataRef.current)) {
|
|
16653
17476
|
const processedData = getDisplayData(data);
|
|
16654
17477
|
animateToNewData(processedData);
|
|
@@ -16872,7 +17695,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
16872
17695
|
renderLegend()
|
|
16873
17696
|
] });
|
|
16874
17697
|
};
|
|
16875
|
-
var Card =
|
|
17698
|
+
var Card = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
16876
17699
|
"div",
|
|
16877
17700
|
{
|
|
16878
17701
|
ref,
|
|
@@ -16884,7 +17707,7 @@ var Card = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
|
16884
17707
|
}
|
|
16885
17708
|
));
|
|
16886
17709
|
Card.displayName = "Card";
|
|
16887
|
-
var CardHeader =
|
|
17710
|
+
var CardHeader = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
16888
17711
|
"div",
|
|
16889
17712
|
{
|
|
16890
17713
|
ref,
|
|
@@ -16893,7 +17716,7 @@ var CardHeader = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
16893
17716
|
}
|
|
16894
17717
|
));
|
|
16895
17718
|
CardHeader.displayName = "CardHeader";
|
|
16896
|
-
var CardTitle =
|
|
17719
|
+
var CardTitle = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
16897
17720
|
"h3",
|
|
16898
17721
|
{
|
|
16899
17722
|
ref,
|
|
@@ -16905,7 +17728,7 @@ var CardTitle = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE_
|
|
|
16905
17728
|
}
|
|
16906
17729
|
));
|
|
16907
17730
|
CardTitle.displayName = "CardTitle";
|
|
16908
|
-
var CardDescription =
|
|
17731
|
+
var CardDescription = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
16909
17732
|
"p",
|
|
16910
17733
|
{
|
|
16911
17734
|
ref,
|
|
@@ -16914,9 +17737,9 @@ var CardDescription = React14.forwardRef(({ className, ...props }, ref) => /* @_
|
|
|
16914
17737
|
}
|
|
16915
17738
|
));
|
|
16916
17739
|
CardDescription.displayName = "CardDescription";
|
|
16917
|
-
var CardContent =
|
|
17740
|
+
var CardContent = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("p-6 pt-0", className), ...props }));
|
|
16918
17741
|
CardContent.displayName = "CardContent";
|
|
16919
|
-
var CardFooter =
|
|
17742
|
+
var CardFooter = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
16920
17743
|
"div",
|
|
16921
17744
|
{
|
|
16922
17745
|
ref,
|
|
@@ -16992,7 +17815,7 @@ var buttonVariants = cva(
|
|
|
16992
17815
|
}
|
|
16993
17816
|
}
|
|
16994
17817
|
);
|
|
16995
|
-
var Button =
|
|
17818
|
+
var Button = React19.forwardRef(
|
|
16996
17819
|
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
16997
17820
|
const Comp = asChild ? Slot : "button";
|
|
16998
17821
|
return /* @__PURE__ */ jsx(
|
|
@@ -17006,7 +17829,7 @@ var Button = React14.forwardRef(
|
|
|
17006
17829
|
}
|
|
17007
17830
|
);
|
|
17008
17831
|
Button.displayName = "Button";
|
|
17009
|
-
var
|
|
17832
|
+
var HourlyOutputChartComponent = ({
|
|
17010
17833
|
data,
|
|
17011
17834
|
pphThreshold,
|
|
17012
17835
|
shiftStart,
|
|
@@ -17023,17 +17846,17 @@ var HourlyOutputChart = ({
|
|
|
17023
17846
|
};
|
|
17024
17847
|
const shiftStartTime = getTimeFromTimeString(shiftStart);
|
|
17025
17848
|
const SHIFT_DURATION = 11;
|
|
17026
|
-
const [animatedData, setAnimatedData] =
|
|
17027
|
-
const prevDataRef =
|
|
17028
|
-
const animationFrameRef =
|
|
17029
|
-
const [idleBarState, setIdleBarState] =
|
|
17849
|
+
const [animatedData, setAnimatedData] = React19__default.useState(Array(SHIFT_DURATION).fill(0));
|
|
17850
|
+
const prevDataRef = React19__default.useRef(Array(SHIFT_DURATION).fill(0));
|
|
17851
|
+
const animationFrameRef = React19__default.useRef(null);
|
|
17852
|
+
const [idleBarState, setIdleBarState] = React19__default.useState({
|
|
17030
17853
|
visible: showIdleTime,
|
|
17031
17854
|
key: 0,
|
|
17032
17855
|
shouldAnimate: false
|
|
17033
17856
|
});
|
|
17034
|
-
const prevShowIdleTimeRef =
|
|
17035
|
-
const stateUpdateTimeoutRef =
|
|
17036
|
-
|
|
17857
|
+
const prevShowIdleTimeRef = React19__default.useRef(showIdleTime);
|
|
17858
|
+
const stateUpdateTimeoutRef = React19__default.useRef(null);
|
|
17859
|
+
React19__default.useEffect(() => {
|
|
17037
17860
|
if (stateUpdateTimeoutRef.current) {
|
|
17038
17861
|
clearTimeout(stateUpdateTimeoutRef.current);
|
|
17039
17862
|
}
|
|
@@ -17058,7 +17881,7 @@ var HourlyOutputChart = ({
|
|
|
17058
17881
|
}
|
|
17059
17882
|
};
|
|
17060
17883
|
}, [showIdleTime]);
|
|
17061
|
-
const animateToNewData =
|
|
17884
|
+
const animateToNewData = React19__default.useCallback((targetData) => {
|
|
17062
17885
|
const startData = [...prevDataRef.current];
|
|
17063
17886
|
const startTime = performance.now();
|
|
17064
17887
|
const duration = 1200;
|
|
@@ -17088,7 +17911,7 @@ var HourlyOutputChart = ({
|
|
|
17088
17911
|
}
|
|
17089
17912
|
animationFrameRef.current = requestAnimationFrame(animate);
|
|
17090
17913
|
}, []);
|
|
17091
|
-
|
|
17914
|
+
React19__default.useEffect(() => {
|
|
17092
17915
|
if (JSON.stringify(data) !== JSON.stringify(prevDataRef.current)) {
|
|
17093
17916
|
const shiftData = data.slice(0, SHIFT_DURATION);
|
|
17094
17917
|
animateToNewData(shiftData);
|
|
@@ -17099,7 +17922,7 @@ var HourlyOutputChart = ({
|
|
|
17099
17922
|
}
|
|
17100
17923
|
};
|
|
17101
17924
|
}, [data, animateToNewData]);
|
|
17102
|
-
const formatHour =
|
|
17925
|
+
const formatHour = React19__default.useCallback((hourIndex) => {
|
|
17103
17926
|
const startDecimalHour = shiftStartTime.decimalHour + hourIndex;
|
|
17104
17927
|
const startHour = Math.floor(startDecimalHour) % 24;
|
|
17105
17928
|
const startMinute = Math.round(startDecimalHour % 1 * 60);
|
|
@@ -17116,7 +17939,7 @@ var HourlyOutputChart = ({
|
|
|
17116
17939
|
};
|
|
17117
17940
|
return `${formatTime2(startHour, startMinute)}-${formatTime2(endHour, endMinute)}`;
|
|
17118
17941
|
}, [shiftStartTime.decimalHour]);
|
|
17119
|
-
const formatTimeRange =
|
|
17942
|
+
const formatTimeRange = React19__default.useCallback((hourIndex) => {
|
|
17120
17943
|
const startDecimalHour = shiftStartTime.decimalHour + hourIndex;
|
|
17121
17944
|
const startHour = Math.floor(startDecimalHour) % 24;
|
|
17122
17945
|
const startMinute = Math.round(startDecimalHour % 1 * 60);
|
|
@@ -17130,7 +17953,7 @@ var HourlyOutputChart = ({
|
|
|
17130
17953
|
};
|
|
17131
17954
|
return `${formatTime2(startHour, startMinute)} - ${formatTime2(endHour, endMinute)}`;
|
|
17132
17955
|
}, [shiftStartTime.decimalHour]);
|
|
17133
|
-
const chartData =
|
|
17956
|
+
const chartData = React19__default.useMemo(() => {
|
|
17134
17957
|
return Array.from({ length: SHIFT_DURATION }, (_, i) => {
|
|
17135
17958
|
const actualHour = (shiftStartTime.hour + i) % 24;
|
|
17136
17959
|
const idleArray = idleTimeHourly?.[actualHour.toString()] || [];
|
|
@@ -17147,7 +17970,7 @@ var HourlyOutputChart = ({
|
|
|
17147
17970
|
};
|
|
17148
17971
|
});
|
|
17149
17972
|
}, [animatedData, data, pphThreshold, idleTimeHourly, shiftStartTime.hour, formatHour, formatTimeRange]);
|
|
17150
|
-
const IdleBar =
|
|
17973
|
+
const IdleBar = React19__default.useMemo(() => {
|
|
17151
17974
|
if (!idleBarState.visible) return null;
|
|
17152
17975
|
return /* @__PURE__ */ jsx(
|
|
17153
17976
|
Bar,
|
|
@@ -17464,6 +18287,33 @@ var HourlyOutputChart = ({
|
|
|
17464
18287
|
renderLegend()
|
|
17465
18288
|
] });
|
|
17466
18289
|
};
|
|
18290
|
+
var HourlyOutputChart = React19__default.memo(HourlyOutputChartComponent, (prevProps, nextProps) => {
|
|
18291
|
+
if (prevProps.pphThreshold !== nextProps.pphThreshold || prevProps.shiftStart !== nextProps.shiftStart || prevProps.showIdleTime !== nextProps.showIdleTime || prevProps.className !== nextProps.className) {
|
|
18292
|
+
return false;
|
|
18293
|
+
}
|
|
18294
|
+
if (prevProps.data.length !== nextProps.data.length) {
|
|
18295
|
+
return false;
|
|
18296
|
+
}
|
|
18297
|
+
if (!prevProps.data.every((val, idx) => val === nextProps.data[idx])) {
|
|
18298
|
+
return false;
|
|
18299
|
+
}
|
|
18300
|
+
const prevIdle = prevProps.idleTimeHourly || {};
|
|
18301
|
+
const nextIdle = nextProps.idleTimeHourly || {};
|
|
18302
|
+
const prevKeys = Object.keys(prevIdle);
|
|
18303
|
+
const nextKeys = Object.keys(nextIdle);
|
|
18304
|
+
if (prevKeys.length !== nextKeys.length) {
|
|
18305
|
+
return false;
|
|
18306
|
+
}
|
|
18307
|
+
for (const key of prevKeys) {
|
|
18308
|
+
if (!nextIdle[key]) return false;
|
|
18309
|
+
const prevArray = prevIdle[key];
|
|
18310
|
+
const nextArray = nextIdle[key];
|
|
18311
|
+
if (prevArray.length !== nextArray.length) return false;
|
|
18312
|
+
if (!prevArray.every((val, idx) => val === nextArray[idx])) return false;
|
|
18313
|
+
}
|
|
18314
|
+
return true;
|
|
18315
|
+
});
|
|
18316
|
+
HourlyOutputChart.displayName = "HourlyOutputChart";
|
|
17467
18317
|
function getTrendArrowAndColor(trend) {
|
|
17468
18318
|
if (trend > 0) {
|
|
17469
18319
|
return { arrow: "\u2191", color: "text-green-400" };
|
|
@@ -17473,7 +18323,7 @@ function getTrendArrowAndColor(trend) {
|
|
|
17473
18323
|
return { arrow: "\u2192", color: "text-gray-400" };
|
|
17474
18324
|
}
|
|
17475
18325
|
}
|
|
17476
|
-
var VideoCard =
|
|
18326
|
+
var VideoCard = React19__default.memo(({
|
|
17477
18327
|
workspace,
|
|
17478
18328
|
hlsUrl,
|
|
17479
18329
|
shouldPlay,
|
|
@@ -17616,7 +18466,7 @@ var VideoCard = React14__default.memo(({
|
|
|
17616
18466
|
});
|
|
17617
18467
|
VideoCard.displayName = "VideoCard";
|
|
17618
18468
|
var DEFAULT_HLS_URL = "https://192.168.5.9:8443/cam1.m3u8";
|
|
17619
|
-
var VideoGridView =
|
|
18469
|
+
var VideoGridView = React19__default.memo(({
|
|
17620
18470
|
workspaces,
|
|
17621
18471
|
selectedLine,
|
|
17622
18472
|
className = "",
|
|
@@ -18418,7 +19268,7 @@ var EmptyStateMessage = ({
|
|
|
18418
19268
|
iconClassName
|
|
18419
19269
|
}) => {
|
|
18420
19270
|
let IconContent = null;
|
|
18421
|
-
if (
|
|
19271
|
+
if (React19__default.isValidElement(iconType)) {
|
|
18422
19272
|
IconContent = iconType;
|
|
18423
19273
|
} else if (typeof iconType === "string") {
|
|
18424
19274
|
const MappedIcon = IconMap[iconType];
|
|
@@ -18551,7 +19401,10 @@ var BreakNotificationPopup = ({
|
|
|
18551
19401
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-3 flex-1", children: [
|
|
18552
19402
|
/* @__PURE__ */ jsx("div", { className: "w-2 h-2 bg-amber-500 rounded-full animate-pulse flex-shrink-0 mt-2" }),
|
|
18553
19403
|
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
18554
|
-
/* @__PURE__ */
|
|
19404
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-1", children: [
|
|
19405
|
+
/* @__PURE__ */ jsx("h4", { className: "font-semibold text-sm text-gray-900", children: breakItem.remarks || "Break" }),
|
|
19406
|
+
(activeBreaks.length > 1 || lineNames[breakItem.lineId]) && /* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500 mt-0.5", children: lineNames[breakItem.lineId] || `Line ${breakItem.lineId.substring(0, 8)}` })
|
|
19407
|
+
] }),
|
|
18555
19408
|
/* @__PURE__ */ jsx("div", { className: "mb-2", children: /* @__PURE__ */ jsxs("div", { className: "text-xs text-gray-600 font-medium", children: [
|
|
18556
19409
|
breakItem.startTime,
|
|
18557
19410
|
" - ",
|
|
@@ -18560,8 +19413,7 @@ var BreakNotificationPopup = ({
|
|
|
18560
19413
|
/* @__PURE__ */ jsx("div", { className: "mb-2", children: /* @__PURE__ */ jsxs("div", { className: "text-xs text-gray-500", children: [
|
|
18561
19414
|
formatTime2(breakItem.elapsedMinutes),
|
|
18562
19415
|
" / ",
|
|
18563
|
-
breakItem.duration
|
|
18564
|
-
" min"
|
|
19416
|
+
formatTime2(breakItem.duration)
|
|
18565
19417
|
] }) }),
|
|
18566
19418
|
/* @__PURE__ */ jsx("div", { className: "mt-2", children: /* @__PURE__ */ jsx("div", { className: "w-full bg-gray-200 rounded-full h-1.5", children: /* @__PURE__ */ jsx(
|
|
18567
19419
|
"div",
|
|
@@ -21000,7 +21852,7 @@ function Skeleton({ className, ...props }) {
|
|
|
21000
21852
|
var Select = SelectPrimitive.Root;
|
|
21001
21853
|
var SelectGroup = SelectPrimitive.Group;
|
|
21002
21854
|
var SelectValue = SelectPrimitive.Value;
|
|
21003
|
-
var SelectTrigger =
|
|
21855
|
+
var SelectTrigger = React19.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
21004
21856
|
SelectPrimitive.Trigger,
|
|
21005
21857
|
{
|
|
21006
21858
|
ref,
|
|
@@ -21016,7 +21868,7 @@ var SelectTrigger = React14.forwardRef(({ className, children, ...props }, ref)
|
|
|
21016
21868
|
}
|
|
21017
21869
|
));
|
|
21018
21870
|
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
|
|
21019
|
-
var SelectScrollUpButton =
|
|
21871
|
+
var SelectScrollUpButton = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
21020
21872
|
SelectPrimitive.ScrollUpButton,
|
|
21021
21873
|
{
|
|
21022
21874
|
ref,
|
|
@@ -21026,7 +21878,7 @@ var SelectScrollUpButton = React14.forwardRef(({ className, ...props }, ref) =>
|
|
|
21026
21878
|
}
|
|
21027
21879
|
));
|
|
21028
21880
|
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
|
|
21029
|
-
var SelectScrollDownButton =
|
|
21881
|
+
var SelectScrollDownButton = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
21030
21882
|
SelectPrimitive.ScrollDownButton,
|
|
21031
21883
|
{
|
|
21032
21884
|
ref,
|
|
@@ -21036,7 +21888,7 @@ var SelectScrollDownButton = React14.forwardRef(({ className, ...props }, ref) =
|
|
|
21036
21888
|
}
|
|
21037
21889
|
));
|
|
21038
21890
|
SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
|
|
21039
|
-
var SelectContent =
|
|
21891
|
+
var SelectContent = React19.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
|
|
21040
21892
|
SelectPrimitive.Content,
|
|
21041
21893
|
{
|
|
21042
21894
|
ref,
|
|
@@ -21064,7 +21916,7 @@ var SelectContent = React14.forwardRef(({ className, children, position = "poppe
|
|
|
21064
21916
|
}
|
|
21065
21917
|
) }));
|
|
21066
21918
|
SelectContent.displayName = SelectPrimitive.Content.displayName;
|
|
21067
|
-
var SelectLabel =
|
|
21919
|
+
var SelectLabel = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
21068
21920
|
SelectPrimitive.Label,
|
|
21069
21921
|
{
|
|
21070
21922
|
ref,
|
|
@@ -21073,7 +21925,7 @@ var SelectLabel = React14.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
21073
21925
|
}
|
|
21074
21926
|
));
|
|
21075
21927
|
SelectLabel.displayName = SelectPrimitive.Label.displayName;
|
|
21076
|
-
var SelectItem =
|
|
21928
|
+
var SelectItem = React19.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
21077
21929
|
SelectPrimitive.Item,
|
|
21078
21930
|
{
|
|
21079
21931
|
ref,
|
|
@@ -21089,7 +21941,7 @@ var SelectItem = React14.forwardRef(({ className, children, ...props }, ref) =>
|
|
|
21089
21941
|
}
|
|
21090
21942
|
));
|
|
21091
21943
|
SelectItem.displayName = SelectPrimitive.Item.displayName;
|
|
21092
|
-
var SelectSeparator =
|
|
21944
|
+
var SelectSeparator = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
21093
21945
|
SelectPrimitive.Separator,
|
|
21094
21946
|
{
|
|
21095
21947
|
ref,
|
|
@@ -21454,7 +22306,7 @@ function parseS3Uri(s3Uri, sopCategories) {
|
|
|
21454
22306
|
break;
|
|
21455
22307
|
case "long_cycle_time":
|
|
21456
22308
|
severity = "high";
|
|
21457
|
-
type = "
|
|
22309
|
+
type = "long_cycle_time";
|
|
21458
22310
|
description = "Long Cycle Time Detected";
|
|
21459
22311
|
break;
|
|
21460
22312
|
case "best_cycle_time":
|
|
@@ -21498,7 +22350,7 @@ function parseS3Uri(s3Uri, sopCategories) {
|
|
|
21498
22350
|
severity = "low";
|
|
21499
22351
|
description = "Best Cycle Time Performance";
|
|
21500
22352
|
} else if (normalizedViolationType.includes("long") && normalizedViolationType.includes("cycle")) {
|
|
21501
|
-
type = "
|
|
22353
|
+
type = "long_cycle_time";
|
|
21502
22354
|
severity = "high";
|
|
21503
22355
|
description = "Long Cycle Time Detected";
|
|
21504
22356
|
} else if (normalizedViolationType.includes("cycle") && (normalizedViolationType.includes("completion") || normalizedViolationType.includes("complete"))) {
|
|
@@ -21964,7 +22816,7 @@ var BottlenecksContent = ({
|
|
|
21964
22816
|
className
|
|
21965
22817
|
}) => {
|
|
21966
22818
|
const dashboardConfig = useDashboardConfig();
|
|
21967
|
-
const sopCategories =
|
|
22819
|
+
const sopCategories = React19__default.useMemo(() => {
|
|
21968
22820
|
const sopConfig = dashboardConfig?.s3Config?.sopCategories;
|
|
21969
22821
|
if (!sopConfig) return null;
|
|
21970
22822
|
if (sopConfig.workspaceOverrides && sopConfig.workspaceOverrides[workspaceId]) {
|
|
@@ -22047,6 +22899,7 @@ var BottlenecksContent = ({
|
|
|
22047
22899
|
const firstWorstCycle = videos.find((v) => v.type === "worst_cycle_time");
|
|
22048
22900
|
const firstSOPDeviation = videos.find((v) => v.type === "missing_quality_check");
|
|
22049
22901
|
const firstCycleCompletion = videos.find((v) => v.type === "cycle_completions");
|
|
22902
|
+
const firstLongCycleTime = videos.find((v) => v.type === "long_cycle_time");
|
|
22050
22903
|
preloadVideosUrl2([
|
|
22051
22904
|
firstHigh?.src,
|
|
22052
22905
|
firstMed?.src,
|
|
@@ -22055,7 +22908,8 @@ var BottlenecksContent = ({
|
|
|
22055
22908
|
firstBestCycle?.src,
|
|
22056
22909
|
firstWorstCycle?.src,
|
|
22057
22910
|
firstSOPDeviation?.src,
|
|
22058
|
-
firstCycleCompletion?.src
|
|
22911
|
+
firstCycleCompletion?.src,
|
|
22912
|
+
firstLongCycleTime?.src
|
|
22059
22913
|
].filter(Boolean));
|
|
22060
22914
|
}
|
|
22061
22915
|
setAllVideos(videos);
|
|
@@ -22081,7 +22935,7 @@ var BottlenecksContent = ({
|
|
|
22081
22935
|
if (activeFilter === "worst_cycle_time") return video.type === "worst_cycle_time";
|
|
22082
22936
|
if (activeFilter === "cycle_completions") return video.type === "cycle_completions";
|
|
22083
22937
|
if (activeFilter === "long_cycle_time") {
|
|
22084
|
-
return video.type === "
|
|
22938
|
+
return video.type === "long_cycle_time";
|
|
22085
22939
|
}
|
|
22086
22940
|
return video.type === "bottleneck" && video.severity === activeFilter;
|
|
22087
22941
|
});
|
|
@@ -22099,11 +22953,6 @@ var BottlenecksContent = ({
|
|
|
22099
22953
|
const selectedCategory = sopCategories.find((cat) => cat.id === activeFilter);
|
|
22100
22954
|
if (selectedCategory) {
|
|
22101
22955
|
filtered = allVideos.filter((video) => video.type === selectedCategory.id);
|
|
22102
|
-
if (selectedCategory.id === "long_cycle_time") {
|
|
22103
|
-
filtered = allVideos.filter(
|
|
22104
|
-
(video) => video.type === "bottleneck" && video.description.toLowerCase().includes("cycle time")
|
|
22105
|
-
);
|
|
22106
|
-
}
|
|
22107
22956
|
}
|
|
22108
22957
|
} else {
|
|
22109
22958
|
if (activeFilter === "low_value") {
|
|
@@ -22117,9 +22966,7 @@ var BottlenecksContent = ({
|
|
|
22117
22966
|
} else if (activeFilter === "cycle_completions") {
|
|
22118
22967
|
filtered = allVideos.filter((video) => video.type === "cycle_completions");
|
|
22119
22968
|
} else if (activeFilter === "long_cycle_time") {
|
|
22120
|
-
filtered = allVideos.filter(
|
|
22121
|
-
(video) => video.type === "bottleneck" && video.description.toLowerCase().includes("cycle time")
|
|
22122
|
-
);
|
|
22969
|
+
filtered = allVideos.filter((video) => video.type === "long_cycle_time");
|
|
22123
22970
|
} else {
|
|
22124
22971
|
filtered = allVideos.filter((video) => video.type === "bottleneck" && video.severity === activeFilter);
|
|
22125
22972
|
}
|
|
@@ -22406,13 +23253,7 @@ var BottlenecksContent = ({
|
|
|
22406
23253
|
const counts = { total: allVideos.length };
|
|
22407
23254
|
if (sopCategories && sopCategories.length > 0) {
|
|
22408
23255
|
sopCategories.forEach((category) => {
|
|
22409
|
-
|
|
22410
|
-
counts[category.id] = allVideos.filter(
|
|
22411
|
-
(video) => video.type === "bottleneck" && video.description.toLowerCase().includes("cycle time")
|
|
22412
|
-
).length;
|
|
22413
|
-
} else {
|
|
22414
|
-
counts[category.id] = allVideos.filter((video) => video.type === category.id).length;
|
|
22415
|
-
}
|
|
23256
|
+
counts[category.id] = allVideos.filter((video) => video.type === category.id).length;
|
|
22416
23257
|
});
|
|
22417
23258
|
} else {
|
|
22418
23259
|
counts.bottlenecks = allVideos.filter((video) => video.type === "bottleneck").length;
|
|
@@ -22423,9 +23264,7 @@ var BottlenecksContent = ({
|
|
|
22423
23264
|
counts.sopDeviations = allVideos.filter((video) => video.type === "missing_quality_check").length;
|
|
22424
23265
|
counts.bestCycleTimes = allVideos.filter((video) => video.type === "best_cycle_time").length;
|
|
22425
23266
|
counts.worstCycleTimes = allVideos.filter((video) => video.type === "worst_cycle_time").length;
|
|
22426
|
-
counts.longCycleTimes = allVideos.filter(
|
|
22427
|
-
(video) => video.type === "bottleneck" && video.description.toLowerCase().includes("cycle time")
|
|
22428
|
-
).length;
|
|
23267
|
+
counts.longCycleTimes = allVideos.filter((video) => video.type === "long_cycle_time").length;
|
|
22429
23268
|
counts.cycleCompletions = allVideos.filter((video) => video.type === "cycle_completions").length;
|
|
22430
23269
|
}
|
|
22431
23270
|
return counts;
|
|
@@ -22956,7 +23795,7 @@ var arePropsEqual = (prevProps, nextProps) => {
|
|
|
22956
23795
|
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 && // Position doesn't need deep equality check as it's generally static
|
|
22957
23796
|
prevProps.position.id === nextProps.position.id;
|
|
22958
23797
|
};
|
|
22959
|
-
var WorkspaceGridItem =
|
|
23798
|
+
var WorkspaceGridItem = React19__default.memo(({
|
|
22960
23799
|
data,
|
|
22961
23800
|
position,
|
|
22962
23801
|
isBottleneck = false,
|
|
@@ -23049,7 +23888,7 @@ var WorkspaceGridItem = React14__default.memo(({
|
|
|
23049
23888
|
);
|
|
23050
23889
|
}, arePropsEqual);
|
|
23051
23890
|
WorkspaceGridItem.displayName = "WorkspaceGridItem";
|
|
23052
|
-
var WorkspaceGrid =
|
|
23891
|
+
var WorkspaceGrid = React19__default.memo(({
|
|
23053
23892
|
workspaces,
|
|
23054
23893
|
isPdfMode = false,
|
|
23055
23894
|
customWorkspacePositions,
|
|
@@ -23239,7 +24078,7 @@ var KPICard = ({
|
|
|
23239
24078
|
}) => {
|
|
23240
24079
|
useThemeConfig();
|
|
23241
24080
|
const { formatNumber } = useFormatNumber();
|
|
23242
|
-
const trendInfo =
|
|
24081
|
+
const trendInfo = React19__default.useMemo(() => {
|
|
23243
24082
|
let trendValue = trend || "neutral";
|
|
23244
24083
|
if (change !== void 0 && trend === void 0) {
|
|
23245
24084
|
trendValue = change > 0 ? "up" : change < 0 ? "down" : "neutral";
|
|
@@ -23262,7 +24101,7 @@ var KPICard = ({
|
|
|
23262
24101
|
const shouldShowTrend = !(change === 0 && trend === void 0);
|
|
23263
24102
|
return { trendValue, Icon: Icon2, colorClass, shouldShowTrend };
|
|
23264
24103
|
}, [trend, change]);
|
|
23265
|
-
const formattedValue =
|
|
24104
|
+
const formattedValue = React19__default.useMemo(() => {
|
|
23266
24105
|
if (title === "Quality Compliance" && typeof value === "number") {
|
|
23267
24106
|
return value.toFixed(1);
|
|
23268
24107
|
}
|
|
@@ -23276,7 +24115,7 @@ var KPICard = ({
|
|
|
23276
24115
|
}
|
|
23277
24116
|
return value;
|
|
23278
24117
|
}, [value, title]);
|
|
23279
|
-
const formattedChange =
|
|
24118
|
+
const formattedChange = React19__default.useMemo(() => {
|
|
23280
24119
|
if (change === void 0 || change === 0) return null;
|
|
23281
24120
|
const absChange = Math.abs(change);
|
|
23282
24121
|
return formatNumber(absChange, { minimumFractionDigits: 0, maximumFractionDigits: 1 });
|
|
@@ -23763,7 +24602,7 @@ var Breadcrumbs = ({ items }) => {
|
|
|
23763
24602
|
}
|
|
23764
24603
|
}
|
|
23765
24604
|
};
|
|
23766
|
-
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(
|
|
24605
|
+
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(React19__default.Fragment, { children: [
|
|
23767
24606
|
index > 0 && /* @__PURE__ */ jsx(ChevronRight, { className: "h-3 w-3 text-gray-400 dark:text-gray-500" }),
|
|
23768
24607
|
/* @__PURE__ */ jsxs(
|
|
23769
24608
|
"span",
|
|
@@ -23955,7 +24794,9 @@ var SideNavBar = memo(({
|
|
|
23955
24794
|
const router = useRouter();
|
|
23956
24795
|
const { navigate } = useNavigation();
|
|
23957
24796
|
const entityConfig = useEntityConfig();
|
|
24797
|
+
const dashboardConfig = useDashboardConfig();
|
|
23958
24798
|
const lineId = entityConfig.defaultLineId || LINE_1_UUID;
|
|
24799
|
+
const skuEnabled = dashboardConfig?.skuConfig?.enabled || false;
|
|
23959
24800
|
const pathname = propPathname || router.pathname;
|
|
23960
24801
|
const getButtonClasses = useCallback((path) => {
|
|
23961
24802
|
const isActive = pathname === path || pathname.startsWith(path + "/");
|
|
@@ -24030,6 +24871,14 @@ var SideNavBar = memo(({
|
|
|
24030
24871
|
}
|
|
24031
24872
|
}
|
|
24032
24873
|
}), [navigate]);
|
|
24874
|
+
const handleSKUsClick = useCallback(() => navigate("/skus", {
|
|
24875
|
+
trackingEvent: {
|
|
24876
|
+
name: "SKU Management Page Clicked",
|
|
24877
|
+
properties: {
|
|
24878
|
+
source: "side_nav"
|
|
24879
|
+
}
|
|
24880
|
+
}
|
|
24881
|
+
}), [navigate]);
|
|
24033
24882
|
const homeButtonClasses = useMemo(() => getButtonClasses("/"), [getButtonClasses, pathname]);
|
|
24034
24883
|
const leaderboardButtonClasses = useMemo(() => getButtonClasses("/leaderboard"), [getButtonClasses, pathname]);
|
|
24035
24884
|
const kpisButtonClasses = useMemo(() => getButtonClasses("/kpis"), [getButtonClasses, pathname]);
|
|
@@ -24038,6 +24887,7 @@ var SideNavBar = memo(({
|
|
|
24038
24887
|
const aiAgentButtonClasses = useMemo(() => getButtonClasses("/ai-agent"), [getButtonClasses, pathname]);
|
|
24039
24888
|
const profileButtonClasses = useMemo(() => getButtonClasses("/profile"), [getButtonClasses, pathname]);
|
|
24040
24889
|
const helpButtonClasses = useMemo(() => getButtonClasses("/help"), [getButtonClasses, pathname]);
|
|
24890
|
+
const skusButtonClasses = useMemo(() => getButtonClasses("/skus"), [getButtonClasses, pathname]);
|
|
24041
24891
|
return /* @__PURE__ */ jsxs("aside", { className: `w-20 h-screen bg-white shadow-lg border-r border-gray-100 flex flex-col items-center fixed ${className}`, children: [
|
|
24042
24892
|
/* @__PURE__ */ jsx("div", { className: "w-full py-6 px-4 flex-shrink-0", children: /* @__PURE__ */ jsx(
|
|
24043
24893
|
"button",
|
|
@@ -24138,6 +24988,21 @@ var SideNavBar = memo(({
|
|
|
24138
24988
|
]
|
|
24139
24989
|
}
|
|
24140
24990
|
),
|
|
24991
|
+
skuEnabled && /* @__PURE__ */ jsxs(
|
|
24992
|
+
"button",
|
|
24993
|
+
{
|
|
24994
|
+
onClick: handleSKUsClick,
|
|
24995
|
+
className: skusButtonClasses,
|
|
24996
|
+
"aria-label": "SKU Management",
|
|
24997
|
+
tabIndex: 0,
|
|
24998
|
+
role: "tab",
|
|
24999
|
+
"aria-selected": pathname === "/skus" || pathname.startsWith("/skus/"),
|
|
25000
|
+
children: [
|
|
25001
|
+
/* @__PURE__ */ jsx(CubeIcon, { className: "w-5 h-5 mb-1" }),
|
|
25002
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium leading-tight", children: "SKUs" })
|
|
25003
|
+
]
|
|
25004
|
+
}
|
|
25005
|
+
),
|
|
24141
25006
|
/* @__PURE__ */ jsxs(
|
|
24142
25007
|
"button",
|
|
24143
25008
|
{
|
|
@@ -24322,6 +25187,103 @@ var Header = ({
|
|
|
24322
25187
|
] })
|
|
24323
25188
|
] }) });
|
|
24324
25189
|
};
|
|
25190
|
+
var LoadingState = ({
|
|
25191
|
+
message = "Loading...",
|
|
25192
|
+
subMessage,
|
|
25193
|
+
size = "lg",
|
|
25194
|
+
className = ""
|
|
25195
|
+
}) => {
|
|
25196
|
+
return /* @__PURE__ */ jsx("div", { className: `flex h-full w-full items-center justify-center bg-gray-50/50 ${className}`, children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center space-y-4 text-center", children: [
|
|
25197
|
+
/* @__PURE__ */ jsx(LoadingSpinner_default, { size }),
|
|
25198
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
25199
|
+
/* @__PURE__ */ jsx("h3", { className: "text-lg font-medium text-gray-900", children: message }),
|
|
25200
|
+
subMessage && /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-gray-600", children: subMessage })
|
|
25201
|
+
] })
|
|
25202
|
+
] }) });
|
|
25203
|
+
};
|
|
25204
|
+
var LoadingSkeleton = ({
|
|
25205
|
+
type,
|
|
25206
|
+
count = 1,
|
|
25207
|
+
className = "",
|
|
25208
|
+
showLoadingIndicator = true
|
|
25209
|
+
}) => {
|
|
25210
|
+
const renderSkeleton = () => {
|
|
25211
|
+
switch (type) {
|
|
25212
|
+
case "card":
|
|
25213
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-3 p-4 border rounded-lg relative", children: [
|
|
25214
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-3/4" }),
|
|
25215
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-8 w-1/2" }),
|
|
25216
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-full" }),
|
|
25217
|
+
showLoadingIndicator && /* @__PURE__ */ jsx("div", { className: "absolute top-2 right-2", children: /* @__PURE__ */ jsxs("div", { className: "flex space-x-1", children: [
|
|
25218
|
+
/* @__PURE__ */ jsx("div", { className: "w-1.5 h-1.5 bg-blue-500 rounded-full animate-bounce", style: { animationDelay: "0ms" } }),
|
|
25219
|
+
/* @__PURE__ */ jsx("div", { className: "w-1.5 h-1.5 bg-blue-500 rounded-full animate-bounce", style: { animationDelay: "150ms" } }),
|
|
25220
|
+
/* @__PURE__ */ jsx("div", { className: "w-1.5 h-1.5 bg-blue-500 rounded-full animate-bounce", style: { animationDelay: "300ms" } })
|
|
25221
|
+
] }) })
|
|
25222
|
+
] });
|
|
25223
|
+
case "chart":
|
|
25224
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-3 p-4 relative", children: [
|
|
25225
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-6 w-1/3" }),
|
|
25226
|
+
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
25227
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-64 w-full" }),
|
|
25228
|
+
showLoadingIndicator && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsx("div", { className: "bg-white/80 rounded-lg p-3 shadow-sm", children: /* @__PURE__ */ jsxs("svg", { className: "animate-spin h-6 w-6 text-blue-500", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [
|
|
25229
|
+
/* @__PURE__ */ jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
|
|
25230
|
+
/* @__PURE__ */ jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })
|
|
25231
|
+
] }) }) })
|
|
25232
|
+
] })
|
|
25233
|
+
] });
|
|
25234
|
+
case "table":
|
|
25235
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
25236
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-10 w-full" }),
|
|
25237
|
+
[...Array(5)].map((_, i) => /* @__PURE__ */ jsx(Skeleton, { className: "h-12 w-full" }, i))
|
|
25238
|
+
] });
|
|
25239
|
+
case "list":
|
|
25240
|
+
return /* @__PURE__ */ jsx("div", { className: "space-y-2", children: [...Array(5)].map((_, i) => /* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-3", children: [
|
|
25241
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-10 w-10 rounded-full" }),
|
|
25242
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 space-y-2", children: [
|
|
25243
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-3/4" }),
|
|
25244
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-1/2" })
|
|
25245
|
+
] })
|
|
25246
|
+
] }, i)) });
|
|
25247
|
+
case "kpi":
|
|
25248
|
+
return /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-4", children: [...Array(4)].map((_, i) => /* @__PURE__ */ jsxs("div", { className: "p-4 border rounded-lg space-y-2", children: [
|
|
25249
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-2/3" }),
|
|
25250
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-8 w-1/2" }),
|
|
25251
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-full" })
|
|
25252
|
+
] }, i)) });
|
|
25253
|
+
case "workspace-card":
|
|
25254
|
+
return /* @__PURE__ */ jsxs("div", { className: "p-4 border rounded-lg space-y-3", children: [
|
|
25255
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-between items-start", children: [
|
|
25256
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-1/3" }),
|
|
25257
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-16" })
|
|
25258
|
+
] }),
|
|
25259
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-32 w-full" }),
|
|
25260
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
|
|
25261
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-8 w-full" }),
|
|
25262
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-8 w-full" })
|
|
25263
|
+
] })
|
|
25264
|
+
] });
|
|
25265
|
+
case "video-grid":
|
|
25266
|
+
return /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4", children: [...Array(6)].map((_, i) => /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
25267
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-48 w-full rounded-lg" }),
|
|
25268
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-3/4" }),
|
|
25269
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-1/2" })
|
|
25270
|
+
] }, i)) });
|
|
25271
|
+
default:
|
|
25272
|
+
return /* @__PURE__ */ jsx(Skeleton, { className: "h-20 w-full" });
|
|
25273
|
+
}
|
|
25274
|
+
};
|
|
25275
|
+
return /* @__PURE__ */ jsx("div", { className, children: [...Array(count)].map((_, index) => /* @__PURE__ */ jsx("div", { children: renderSkeleton() }, index)) });
|
|
25276
|
+
};
|
|
25277
|
+
var LoadingInline = ({
|
|
25278
|
+
message,
|
|
25279
|
+
size = "sm",
|
|
25280
|
+
className = ""
|
|
25281
|
+
}) => {
|
|
25282
|
+
return /* @__PURE__ */ jsxs("div", { className: `inline-flex items-center space-x-2 ${className}`, children: [
|
|
25283
|
+
/* @__PURE__ */ jsx(LoadingSpinner_default, { size }),
|
|
25284
|
+
message && /* @__PURE__ */ jsx("span", { className: "text-sm text-gray-600", children: message })
|
|
25285
|
+
] });
|
|
25286
|
+
};
|
|
24325
25287
|
var DEFAULT_HLS_CONFIG = {
|
|
24326
25288
|
maxBufferLength: 15,
|
|
24327
25289
|
// Moderate buffer length for faster startup
|
|
@@ -24581,7 +25543,7 @@ var ThreadSidebar = ({
|
|
|
24581
25543
|
] });
|
|
24582
25544
|
};
|
|
24583
25545
|
var axelProfilePng = "/axel-profile.png";
|
|
24584
|
-
var ProfilePicture =
|
|
25546
|
+
var ProfilePicture = React19__default.memo(({ alt = "Axel", className = "w-12 h-12" }) => {
|
|
24585
25547
|
return /* @__PURE__ */ jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsx("div", { className: `${className} rounded-xl overflow-hidden shadow-sm`, children: /* @__PURE__ */ jsx(
|
|
24586
25548
|
"img",
|
|
24587
25549
|
{
|
|
@@ -24699,6 +25661,7 @@ var AIAgentView = () => {
|
|
|
24699
25661
|
const textareaRef = useRef(null);
|
|
24700
25662
|
const messagesEndRef = useRef(null);
|
|
24701
25663
|
const containerRef = useRef(null);
|
|
25664
|
+
const renderedContentCache = useRef(/* @__PURE__ */ new Map());
|
|
24702
25665
|
const { createThread, mutate: mutateThreads } = useThreads();
|
|
24703
25666
|
const { messages, addMessage, setMessages } = useMessages(activeThreadId);
|
|
24704
25667
|
const agnoApiUrl = config.endpoints?.agnoApiUrl || "https://optifye-agent-production.up.railway.app";
|
|
@@ -25184,6 +26147,10 @@ var AIAgentView = () => {
|
|
|
25184
26147
|
});
|
|
25185
26148
|
}
|
|
25186
26149
|
const renderAssistantContent = (content) => {
|
|
26150
|
+
const cached = renderedContentCache.current.get(content);
|
|
26151
|
+
if (cached) {
|
|
26152
|
+
return cached;
|
|
26153
|
+
}
|
|
25187
26154
|
const parseChartPatterns = (text) => {
|
|
25188
26155
|
const chartElements = [];
|
|
25189
26156
|
let lastIndex = 0;
|
|
@@ -26048,16 +27015,20 @@ var AIAgentView = () => {
|
|
|
26048
27015
|
}
|
|
26049
27016
|
};
|
|
26050
27017
|
const chartContent = parseChartPatterns(content);
|
|
27018
|
+
let finalNode;
|
|
26051
27019
|
if (chartContent) {
|
|
26052
|
-
|
|
27020
|
+
finalNode = /* @__PURE__ */ jsx("div", { className: "formatted-content", children: chartContent });
|
|
27021
|
+
} else {
|
|
27022
|
+
finalNode = /* @__PURE__ */ jsx(
|
|
27023
|
+
"div",
|
|
27024
|
+
{
|
|
27025
|
+
className: "formatted-content",
|
|
27026
|
+
dangerouslySetInnerHTML: { __html: formatMessage(content) }
|
|
27027
|
+
}
|
|
27028
|
+
);
|
|
26053
27029
|
}
|
|
26054
|
-
|
|
26055
|
-
|
|
26056
|
-
{
|
|
26057
|
-
className: "formatted-content",
|
|
26058
|
-
dangerouslySetInnerHTML: { __html: formatMessage(content) }
|
|
26059
|
-
}
|
|
26060
|
-
);
|
|
27030
|
+
renderedContentCache.current.set(content, finalNode);
|
|
27031
|
+
return finalNode;
|
|
26061
27032
|
};
|
|
26062
27033
|
return /* @__PURE__ */ jsxs("div", { className: "flex h-screen bg-white", children: [
|
|
26063
27034
|
/* @__PURE__ */ jsx("style", { dangerouslySetInnerHTML: {
|
|
@@ -27299,8 +28270,6 @@ var HelpView = ({
|
|
|
27299
28270
|
var AuthenticatedHelpView = withAuth(HelpView);
|
|
27300
28271
|
var HelpView_default = HelpView;
|
|
27301
28272
|
var KPISection2 = KPISection;
|
|
27302
|
-
var LoadingPageCmp = LoadingPage_default;
|
|
27303
|
-
var LoadingOverlayCmp = LoadingOverlay_default;
|
|
27304
28273
|
function HomeView({
|
|
27305
28274
|
defaultLineId,
|
|
27306
28275
|
factoryViewId,
|
|
@@ -27319,6 +28288,7 @@ function HomeView({
|
|
|
27319
28288
|
const [isChangingFilter, setIsChangingFilter] = useState(false);
|
|
27320
28289
|
const [errorMessage, setErrorMessage] = useState(null);
|
|
27321
28290
|
const [displayNamesInitialized, setDisplayNamesInitialized] = useState(false);
|
|
28291
|
+
const [hasInitialDataLoaded, setHasInitialDataLoaded] = useState(false);
|
|
27322
28292
|
useEffect(() => {
|
|
27323
28293
|
const initDisplayNames = async () => {
|
|
27324
28294
|
try {
|
|
@@ -27369,17 +28339,17 @@ function HomeView({
|
|
|
27369
28339
|
lineId: selectedLineId,
|
|
27370
28340
|
onLineMetricsUpdate
|
|
27371
28341
|
});
|
|
27372
|
-
const lineIdsForBreaks = useMemo(() => {
|
|
27373
|
-
if (selectedLineId === factoryViewId) {
|
|
27374
|
-
return allLineIds;
|
|
27375
|
-
}
|
|
27376
|
-
return [selectedLineId];
|
|
27377
|
-
}, [selectedLineId, factoryViewId, allLineIds]);
|
|
27378
28342
|
const {
|
|
27379
|
-
activeBreaks,
|
|
28343
|
+
activeBreaks: allActiveBreaks,
|
|
27380
28344
|
isLoading: breaksLoading,
|
|
27381
28345
|
error: breaksError
|
|
27382
|
-
} = useActiveBreaks(
|
|
28346
|
+
} = useActiveBreaks(allLineIds);
|
|
28347
|
+
const activeBreaks = useMemo(() => {
|
|
28348
|
+
if (selectedLineId === factoryViewId) {
|
|
28349
|
+
return allActiveBreaks;
|
|
28350
|
+
}
|
|
28351
|
+
return allActiveBreaks.filter((breakItem) => breakItem.lineId === selectedLineId);
|
|
28352
|
+
}, [allActiveBreaks, selectedLineId, factoryViewId]);
|
|
27383
28353
|
const memoizedWorkspaceMetrics = useMemo(() => workspaceMetrics, [
|
|
27384
28354
|
// Only update reference if meaningful properties change
|
|
27385
28355
|
workspaceMetrics.length,
|
|
@@ -27419,6 +28389,11 @@ function HomeView({
|
|
|
27419
28389
|
}
|
|
27420
28390
|
}
|
|
27421
28391
|
}, [metricsLoading, kpisLoading, workspaceMetrics, isChangingFilter, selectedLineId, factoryViewId]);
|
|
28392
|
+
useEffect(() => {
|
|
28393
|
+
if (!metricsLoading && !kpisLoading && !hasInitialDataLoaded) {
|
|
28394
|
+
setHasInitialDataLoaded(true);
|
|
28395
|
+
}
|
|
28396
|
+
}, [metricsLoading, kpisLoading, hasInitialDataLoaded]);
|
|
27422
28397
|
const lineTitle = useMemo(() => {
|
|
27423
28398
|
return factoryName;
|
|
27424
28399
|
}, [factoryName]);
|
|
@@ -27431,9 +28406,56 @@ function HomeView({
|
|
|
27431
28406
|
/* @__PURE__ */ jsx(SelectContent, { className: "z-50 bg-white shadow-lg border border-gray-200 rounded-md", children: availableLineIds.map((id3) => /* @__PURE__ */ jsx(SelectItem, { value: id3, children: lineNames[id3] || (id3 === factoryViewId ? "All Lines" : `Line ${id3.substring(0, 4)}`) }, id3)) })
|
|
27432
28407
|
] });
|
|
27433
28408
|
}, [availableLineIds, handleLineChange, selectedLineId, lineNames, factoryViewId, allLineIds.length]);
|
|
27434
|
-
const
|
|
27435
|
-
|
|
27436
|
-
|
|
28409
|
+
const isInitialLoading = !isHydrated || !displayNamesInitialized && displayNamesLoading;
|
|
28410
|
+
const isDataLoading = metricsLoading || kpisLoading;
|
|
28411
|
+
if (isInitialLoading) {
|
|
28412
|
+
return /* @__PURE__ */ jsx("div", { className: "min-h-screen bg-gradient-to-br from-slate-50 via-blue-50 to-slate-50 flex items-center justify-center", children: /* @__PURE__ */ jsx(
|
|
28413
|
+
motion.div,
|
|
28414
|
+
{
|
|
28415
|
+
className: "text-center",
|
|
28416
|
+
initial: { opacity: 0, scale: 0.9 },
|
|
28417
|
+
animate: { opacity: 1, scale: 1 },
|
|
28418
|
+
transition: { duration: 0.5 },
|
|
28419
|
+
children: /* @__PURE__ */ jsxs("div", { className: "bg-white rounded-2xl shadow-2xl p-12 max-w-md mx-auto", children: [
|
|
28420
|
+
/* @__PURE__ */ jsx("div", { className: "relative mb-8", children: /* @__PURE__ */ jsxs("div", { className: "w-24 h-24 mx-auto", children: [
|
|
28421
|
+
/* @__PURE__ */ jsxs("svg", { className: "animate-spin", viewBox: "0 0 100 100", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
28422
|
+
/* @__PURE__ */ jsx("circle", { cx: "50", cy: "50", r: "45", fill: "none", stroke: "#e5e7eb", strokeWidth: "8" }),
|
|
28423
|
+
/* @__PURE__ */ jsx(
|
|
28424
|
+
"circle",
|
|
28425
|
+
{
|
|
28426
|
+
cx: "50",
|
|
28427
|
+
cy: "50",
|
|
28428
|
+
r: "45",
|
|
28429
|
+
fill: "none",
|
|
28430
|
+
stroke: "#3b82f6",
|
|
28431
|
+
strokeWidth: "8",
|
|
28432
|
+
strokeDasharray: "150 283",
|
|
28433
|
+
strokeLinecap: "round",
|
|
28434
|
+
className: "transform -rotate-90 origin-center"
|
|
28435
|
+
}
|
|
28436
|
+
)
|
|
28437
|
+
] }),
|
|
28438
|
+
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsx("div", { className: "w-16 h-16 bg-gradient-to-br from-blue-500 to-blue-600 rounded-full animate-pulse" }) })
|
|
28439
|
+
] }) }),
|
|
28440
|
+
/* @__PURE__ */ jsx("h2", { className: "text-2xl font-bold text-gray-800 mb-2", children: "Loading Dashboard" }),
|
|
28441
|
+
/* @__PURE__ */ jsx("p", { className: "text-gray-600 mb-6", children: "Initializing your workspace..." }),
|
|
28442
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
28443
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center space-x-2 text-sm text-gray-500", children: [
|
|
28444
|
+
/* @__PURE__ */ jsx("div", { className: "w-2 h-2 bg-blue-500 rounded-full animate-pulse" }),
|
|
28445
|
+
/* @__PURE__ */ jsx("span", { children: "Connecting to services" })
|
|
28446
|
+
] }),
|
|
28447
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center space-x-2 text-sm text-gray-500", children: [
|
|
28448
|
+
/* @__PURE__ */ jsx("div", { className: "w-2 h-2 bg-blue-500 rounded-full animate-pulse", style: { animationDelay: "0.2s" } }),
|
|
28449
|
+
/* @__PURE__ */ jsx("span", { children: "Loading workspace configurations" })
|
|
28450
|
+
] }),
|
|
28451
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center space-x-2 text-sm text-gray-500", children: [
|
|
28452
|
+
/* @__PURE__ */ jsx("div", { className: "w-2 h-2 bg-blue-500 rounded-full animate-pulse", style: { animationDelay: "0.4s" } }),
|
|
28453
|
+
/* @__PURE__ */ jsx("span", { children: "Preparing dashboard view" })
|
|
28454
|
+
] })
|
|
28455
|
+
] })
|
|
28456
|
+
] })
|
|
28457
|
+
}
|
|
28458
|
+
) });
|
|
27437
28459
|
}
|
|
27438
28460
|
if (errorMessage || displayNamesError) {
|
|
27439
28461
|
return /* @__PURE__ */ jsx("div", { className: "flex h-screen items-center justify-center", children: /* @__PURE__ */ jsx("div", { className: "rounded-lg bg-white p-6 shadow-lg", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-3 text-red-500", children: [
|
|
@@ -27444,52 +28466,64 @@ function HomeView({
|
|
|
27444
28466
|
] })
|
|
27445
28467
|
] }) }) });
|
|
27446
28468
|
}
|
|
27447
|
-
|
|
27448
|
-
return /* @__PURE__ */ jsx("div", { className: "min-h-screen bg-slate-50", children: /* @__PURE__ */ jsx(LoadingPageCmp, { message: "Loading metrics..." }) });
|
|
27449
|
-
}
|
|
27450
|
-
return /* @__PURE__ */ jsxs(
|
|
28469
|
+
return /* @__PURE__ */ jsx(
|
|
27451
28470
|
motion.div,
|
|
27452
28471
|
{
|
|
27453
28472
|
className: "flex min-h-screen bg-slate-50",
|
|
27454
28473
|
initial: { opacity: 1 },
|
|
27455
28474
|
animate: { opacity: 1 },
|
|
27456
|
-
children: [
|
|
27457
|
-
/* @__PURE__ */
|
|
27458
|
-
|
|
27459
|
-
|
|
27460
|
-
/* @__PURE__ */ jsx("div", { className: "sticky top-0 z-30 sm:static bg-white shadow-sm border-b border-gray-200/80", children: /* @__PURE__ */ jsx("div", { className: "flex flex-col sm:flex-row sm:items-center sm:justify-between px-3 sm:px-6 lg:px-8 py-1.5 sm:py-2.5", children: /* @__PURE__ */ jsx(
|
|
27461
|
-
DashboardHeader,
|
|
27462
|
-
{
|
|
27463
|
-
lineTitle,
|
|
27464
|
-
className: "w-full",
|
|
27465
|
-
headerControls: memoizedKPIs ? /* @__PURE__ */ jsx(KPISection2, { kpis: memoizedKPIs, className: "w-full sm:w-auto" }) : null
|
|
27466
|
-
}
|
|
27467
|
-
) }) }),
|
|
27468
|
-
/* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-y-auto sm:overflow-hidden relative", children: [
|
|
27469
|
-
lineSelectorComponent && /* @__PURE__ */ jsx("div", { className: "absolute right-3 top-2 sm:right-6 sm:top-3 z-30", children: lineSelectorComponent }),
|
|
27470
|
-
memoizedWorkspaceMetrics.length > 0 ? /* @__PURE__ */ jsx("div", { className: "h-full sm:h-full min-h-[calc(100vh-80px)] sm:min-h-0", children: React14__default.createElement(WorkspaceGrid, {
|
|
27471
|
-
workspaces: memoizedWorkspaceMetrics,
|
|
27472
|
-
lineNames,
|
|
27473
|
-
factoryView: factoryViewId,
|
|
27474
|
-
videoSources,
|
|
27475
|
-
className: "h-full"
|
|
27476
|
-
}) }) : /* @__PURE__ */ jsx(NoWorkspaceData, { message: "No workspace data available. Select another line or check configurations." })
|
|
27477
|
-
] })
|
|
27478
|
-
] }),
|
|
27479
|
-
/* @__PURE__ */ jsx(
|
|
27480
|
-
BreakNotificationPopup,
|
|
28475
|
+
children: /* @__PURE__ */ jsxs("div", { className: "relative flex flex-1", children: [
|
|
28476
|
+
/* @__PURE__ */ jsxs("main", { className: "flex flex-1 flex-col", children: [
|
|
28477
|
+
/* @__PURE__ */ jsx("div", { className: "sticky top-0 z-30 sm:static bg-white shadow-sm border-b border-gray-200/80", children: /* @__PURE__ */ jsx("div", { className: "flex flex-col sm:flex-row sm:items-center sm:justify-between px-3 sm:px-6 lg:px-8 py-1.5 sm:py-2.5", children: /* @__PURE__ */ jsx(
|
|
28478
|
+
DashboardHeader,
|
|
27481
28479
|
{
|
|
27482
|
-
|
|
27483
|
-
|
|
27484
|
-
|
|
28480
|
+
lineTitle,
|
|
28481
|
+
className: "w-full",
|
|
28482
|
+
headerControls: memoizedKPIs ? /* @__PURE__ */ jsx(KPISection2, { kpis: memoizedKPIs, className: "w-full sm:w-auto" }) : null
|
|
27485
28483
|
}
|
|
27486
|
-
)
|
|
27487
|
-
|
|
27488
|
-
|
|
28484
|
+
) }) }),
|
|
28485
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-y-auto sm:overflow-hidden relative", children: [
|
|
28486
|
+
lineSelectorComponent && /* @__PURE__ */ jsx("div", { className: "absolute right-3 top-2 sm:right-6 sm:top-3 z-30", children: lineSelectorComponent }),
|
|
28487
|
+
/* @__PURE__ */ jsx("div", { className: "h-full sm:h-full min-h-[calc(100vh-80px)] sm:min-h-0", children: isDataLoading && hasInitialDataLoaded && memoizedWorkspaceMetrics.length === 0 ? /* @__PURE__ */ jsx("div", { className: "px-3 sm:px-6 lg:px-8 py-4", children: /* @__PURE__ */ jsx(LoadingSkeleton, { type: "workspace-card", count: 8, className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4" }) }) : memoizedWorkspaceMetrics.length > 0 ? /* @__PURE__ */ jsx(
|
|
28488
|
+
motion.div,
|
|
28489
|
+
{
|
|
28490
|
+
initial: { opacity: 0, scale: 0.98 },
|
|
28491
|
+
animate: { opacity: 1, scale: 1 },
|
|
28492
|
+
transition: { duration: 0.3 },
|
|
28493
|
+
className: "h-full",
|
|
28494
|
+
children: React19__default.createElement(WorkspaceGrid, {
|
|
28495
|
+
workspaces: memoizedWorkspaceMetrics,
|
|
28496
|
+
lineNames,
|
|
28497
|
+
factoryView: factoryViewId,
|
|
28498
|
+
videoSources,
|
|
28499
|
+
className: "h-full"
|
|
28500
|
+
})
|
|
28501
|
+
},
|
|
28502
|
+
selectedLineId
|
|
28503
|
+
) : /* @__PURE__ */ jsx(
|
|
28504
|
+
motion.div,
|
|
28505
|
+
{
|
|
28506
|
+
initial: { opacity: 0 },
|
|
28507
|
+
animate: { opacity: 1 },
|
|
28508
|
+
transition: { duration: 0.3 },
|
|
28509
|
+
children: /* @__PURE__ */ jsx(NoWorkspaceData, { message: "No workspace data available. Select another line or check configurations." })
|
|
28510
|
+
}
|
|
28511
|
+
) })
|
|
28512
|
+
] })
|
|
28513
|
+
] }),
|
|
28514
|
+
/* @__PURE__ */ jsx(
|
|
28515
|
+
BreakNotificationPopup,
|
|
28516
|
+
{
|
|
28517
|
+
activeBreaks,
|
|
28518
|
+
lineNames,
|
|
28519
|
+
isVisible: !breaksLoading && !breaksError
|
|
28520
|
+
}
|
|
28521
|
+
)
|
|
28522
|
+
] })
|
|
27489
28523
|
}
|
|
27490
28524
|
);
|
|
27491
28525
|
}
|
|
27492
|
-
var AuthenticatedHomeView = withAuth(
|
|
28526
|
+
var AuthenticatedHomeView = withAuth(React19__default.memo(HomeView));
|
|
27493
28527
|
var HomeView_default = HomeView;
|
|
27494
28528
|
|
|
27495
28529
|
// src/views/kpi-detail-view.types.ts
|
|
@@ -28322,7 +29356,7 @@ var LineCard = ({ line, onClick }) => {
|
|
|
28322
29356
|
const { kpis, isLoading, error } = useLineKPIs({ lineId: line.id });
|
|
28323
29357
|
const shiftConfig = useShiftConfig();
|
|
28324
29358
|
const dateTimeConfig = useDateTimeConfig();
|
|
28325
|
-
const isOnTrack =
|
|
29359
|
+
const isOnTrack = React19__default.useMemo(() => {
|
|
28326
29360
|
if (!kpis) return null;
|
|
28327
29361
|
const currentTime = /* @__PURE__ */ new Date();
|
|
28328
29362
|
const timezone = dateTimeConfig.defaultTimezone || "Asia/Kolkata";
|
|
@@ -30347,7 +31381,7 @@ var BulkConfigureModal = ({
|
|
|
30347
31381
|
},
|
|
30348
31382
|
className: "w-full rounded-lg border border-gray-300 bg-white px-3 py-2 text-sm\n shadow-sm focus:border-blue-500 focus:ring-blue-500 \n transition-all duration-200 hover:border-blue-400",
|
|
30349
31383
|
min: "0",
|
|
30350
|
-
step: "
|
|
31384
|
+
step: "0.01",
|
|
30351
31385
|
placeholder: "Enter cycle time"
|
|
30352
31386
|
}
|
|
30353
31387
|
),
|
|
@@ -30468,6 +31502,343 @@ var BulkConfigureModal = ({
|
|
|
30468
31502
|
);
|
|
30469
31503
|
};
|
|
30470
31504
|
var BulkConfigureModal_default = BulkConfigureModal;
|
|
31505
|
+
var SKUModal = ({
|
|
31506
|
+
isOpen,
|
|
31507
|
+
onClose,
|
|
31508
|
+
onSave,
|
|
31509
|
+
editingSKU
|
|
31510
|
+
}) => {
|
|
31511
|
+
const config = useDashboardConfig();
|
|
31512
|
+
const defaultProductionTarget = config?.skuConfig?.defaultProductionTarget || 1e3;
|
|
31513
|
+
const [formData, setFormData] = useState({
|
|
31514
|
+
sku_id: "",
|
|
31515
|
+
production_target: defaultProductionTarget,
|
|
31516
|
+
attributes: {}
|
|
31517
|
+
});
|
|
31518
|
+
const [isSaving, setIsSaving] = useState(false);
|
|
31519
|
+
const [error, setError] = useState(null);
|
|
31520
|
+
useEffect(() => {
|
|
31521
|
+
if (editingSKU) {
|
|
31522
|
+
setFormData({
|
|
31523
|
+
sku_id: editingSKU.sku_id,
|
|
31524
|
+
production_target: editingSKU.production_target,
|
|
31525
|
+
attributes: editingSKU.attributes || {}
|
|
31526
|
+
});
|
|
31527
|
+
} else {
|
|
31528
|
+
setFormData({
|
|
31529
|
+
sku_id: "",
|
|
31530
|
+
production_target: defaultProductionTarget,
|
|
31531
|
+
attributes: {}
|
|
31532
|
+
});
|
|
31533
|
+
}
|
|
31534
|
+
setError(null);
|
|
31535
|
+
}, [editingSKU, defaultProductionTarget]);
|
|
31536
|
+
const handleSubmit = async (e) => {
|
|
31537
|
+
e.preventDefault();
|
|
31538
|
+
setError(null);
|
|
31539
|
+
if (!formData.sku_id.trim()) {
|
|
31540
|
+
setError("SKU ID is required");
|
|
31541
|
+
return;
|
|
31542
|
+
}
|
|
31543
|
+
if (formData.production_target <= 0) {
|
|
31544
|
+
setError("Production target must be greater than 0");
|
|
31545
|
+
return;
|
|
31546
|
+
}
|
|
31547
|
+
setIsSaving(true);
|
|
31548
|
+
try {
|
|
31549
|
+
const skuData = {
|
|
31550
|
+
sku_id: formData.sku_id.trim(),
|
|
31551
|
+
production_target: formData.production_target,
|
|
31552
|
+
attributes: formData.attributes,
|
|
31553
|
+
company_id: config?.entityConfig?.companyId || ""
|
|
31554
|
+
};
|
|
31555
|
+
await onSave(skuData);
|
|
31556
|
+
onClose();
|
|
31557
|
+
} catch (err) {
|
|
31558
|
+
setError(err instanceof Error ? err.message : "Failed to save SKU");
|
|
31559
|
+
} finally {
|
|
31560
|
+
setIsSaving(false);
|
|
31561
|
+
}
|
|
31562
|
+
};
|
|
31563
|
+
if (!isOpen) return null;
|
|
31564
|
+
return /* @__PURE__ */ jsx("div", { className: "fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50 p-4", children: /* @__PURE__ */ jsxs("div", { className: "bg-white rounded-xl shadow-2xl max-w-md w-full transform transition-all", children: [
|
|
31565
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between p-6 border-b border-gray-200", children: [
|
|
31566
|
+
/* @__PURE__ */ jsx("h2", { className: "text-xl font-semibold text-gray-900", children: editingSKU ? "Edit SKU" : "Add New SKU" }),
|
|
31567
|
+
/* @__PURE__ */ jsx(
|
|
31568
|
+
"button",
|
|
31569
|
+
{
|
|
31570
|
+
onClick: onClose,
|
|
31571
|
+
className: "text-gray-400 hover:text-gray-600 transition-colors p-1 hover:bg-gray-100 rounded-lg",
|
|
31572
|
+
disabled: isSaving,
|
|
31573
|
+
children: /* @__PURE__ */ jsx(X, { className: "w-5 h-5" })
|
|
31574
|
+
}
|
|
31575
|
+
)
|
|
31576
|
+
] }),
|
|
31577
|
+
/* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className: "p-6", children: [
|
|
31578
|
+
error && /* @__PURE__ */ jsx("div", { className: "mb-4 p-3 bg-red-50 border border-red-200 text-red-700 rounded-lg text-sm", children: error }),
|
|
31579
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-5", children: [
|
|
31580
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
31581
|
+
/* @__PURE__ */ jsxs("label", { htmlFor: "sku_id", className: "block text-sm font-medium text-gray-700 mb-2", children: [
|
|
31582
|
+
"SKU ID ",
|
|
31583
|
+
/* @__PURE__ */ jsx("span", { className: "text-red-500", children: "*" })
|
|
31584
|
+
] }),
|
|
31585
|
+
/* @__PURE__ */ jsx(
|
|
31586
|
+
"input",
|
|
31587
|
+
{
|
|
31588
|
+
type: "text",
|
|
31589
|
+
id: "sku_id",
|
|
31590
|
+
value: formData.sku_id,
|
|
31591
|
+
onChange: (e) => setFormData({ ...formData, sku_id: e.target.value }),
|
|
31592
|
+
className: "w-full px-4 py-2.5 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all duration-200",
|
|
31593
|
+
placeholder: "Enter SKU ID",
|
|
31594
|
+
disabled: isSaving || !!editingSKU,
|
|
31595
|
+
required: true
|
|
31596
|
+
}
|
|
31597
|
+
)
|
|
31598
|
+
] }),
|
|
31599
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
31600
|
+
/* @__PURE__ */ jsxs("label", { htmlFor: "production_target", className: "block text-sm font-medium text-gray-700 mb-2", children: [
|
|
31601
|
+
"Production Target ",
|
|
31602
|
+
/* @__PURE__ */ jsx("span", { className: "text-red-500", children: "*" })
|
|
31603
|
+
] }),
|
|
31604
|
+
/* @__PURE__ */ jsx(
|
|
31605
|
+
"input",
|
|
31606
|
+
{
|
|
31607
|
+
type: "number",
|
|
31608
|
+
id: "production_target",
|
|
31609
|
+
value: formData.production_target,
|
|
31610
|
+
onChange: (e) => setFormData({ ...formData, production_target: parseInt(e.target.value) || 0 }),
|
|
31611
|
+
className: "w-full px-4 py-2.5 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all duration-200",
|
|
31612
|
+
placeholder: "Enter production target",
|
|
31613
|
+
min: "1",
|
|
31614
|
+
disabled: isSaving,
|
|
31615
|
+
required: true
|
|
31616
|
+
}
|
|
31617
|
+
),
|
|
31618
|
+
/* @__PURE__ */ jsx("p", { className: "mt-1.5 text-sm text-gray-500", children: "Units per day for this SKU" })
|
|
31619
|
+
] }),
|
|
31620
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
31621
|
+
/* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: "Additional Attributes (Optional)" }),
|
|
31622
|
+
/* @__PURE__ */ jsx(
|
|
31623
|
+
"textarea",
|
|
31624
|
+
{
|
|
31625
|
+
value: JSON.stringify(formData.attributes, null, 2),
|
|
31626
|
+
onChange: (e) => {
|
|
31627
|
+
try {
|
|
31628
|
+
const parsed = JSON.parse(e.target.value);
|
|
31629
|
+
setFormData({ ...formData, attributes: parsed });
|
|
31630
|
+
} catch {
|
|
31631
|
+
}
|
|
31632
|
+
},
|
|
31633
|
+
className: "w-full px-4 py-2.5 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent font-mono text-sm transition-all duration-200",
|
|
31634
|
+
rows: 4,
|
|
31635
|
+
placeholder: '{"color": "red", "size": "large"}',
|
|
31636
|
+
disabled: isSaving
|
|
31637
|
+
}
|
|
31638
|
+
),
|
|
31639
|
+
/* @__PURE__ */ jsx("p", { className: "mt-1.5 text-sm text-gray-500", children: "Enter valid JSON for additional SKU attributes" })
|
|
31640
|
+
] })
|
|
31641
|
+
] }),
|
|
31642
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-end space-x-3 mt-6 pt-4 border-t border-gray-200", children: [
|
|
31643
|
+
/* @__PURE__ */ jsx(
|
|
31644
|
+
"button",
|
|
31645
|
+
{
|
|
31646
|
+
type: "button",
|
|
31647
|
+
onClick: onClose,
|
|
31648
|
+
className: "px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500 transition-all duration-200",
|
|
31649
|
+
disabled: isSaving,
|
|
31650
|
+
children: "Cancel"
|
|
31651
|
+
}
|
|
31652
|
+
),
|
|
31653
|
+
/* @__PURE__ */ jsx(
|
|
31654
|
+
"button",
|
|
31655
|
+
{
|
|
31656
|
+
type: "submit",
|
|
31657
|
+
className: "px-4 py-2 text-sm font-medium text-white bg-blue-600 border border-transparent rounded-lg hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-200 shadow-sm",
|
|
31658
|
+
disabled: isSaving,
|
|
31659
|
+
children: isSaving ? "Saving..." : editingSKU ? "Update" : "Create"
|
|
31660
|
+
}
|
|
31661
|
+
)
|
|
31662
|
+
] })
|
|
31663
|
+
] })
|
|
31664
|
+
] }) });
|
|
31665
|
+
};
|
|
31666
|
+
var SKUSelector = ({
|
|
31667
|
+
onSelect,
|
|
31668
|
+
selectedSKU,
|
|
31669
|
+
availableSKUs,
|
|
31670
|
+
className = "",
|
|
31671
|
+
lineId,
|
|
31672
|
+
disabled = false,
|
|
31673
|
+
required = false
|
|
31674
|
+
}) => {
|
|
31675
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
31676
|
+
const [searchTerm, setSearchTerm] = useState("");
|
|
31677
|
+
const dropdownRef = useRef(null);
|
|
31678
|
+
useEffect(() => {
|
|
31679
|
+
const handleClickOutside = (event) => {
|
|
31680
|
+
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
|
|
31681
|
+
setIsOpen(false);
|
|
31682
|
+
}
|
|
31683
|
+
};
|
|
31684
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
31685
|
+
return () => {
|
|
31686
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
31687
|
+
};
|
|
31688
|
+
}, []);
|
|
31689
|
+
const filteredSKUs = availableSKUs.filter(
|
|
31690
|
+
(sku) => sku.sku_id.toLowerCase().includes(searchTerm.toLowerCase()) || JSON.stringify(sku.attributes).toLowerCase().includes(searchTerm.toLowerCase())
|
|
31691
|
+
);
|
|
31692
|
+
const handleSelect = (sku) => {
|
|
31693
|
+
onSelect(sku);
|
|
31694
|
+
setIsOpen(false);
|
|
31695
|
+
setSearchTerm("");
|
|
31696
|
+
};
|
|
31697
|
+
return /* @__PURE__ */ jsxs("div", { className: `relative ${className}`, ref: dropdownRef, children: [
|
|
31698
|
+
/* @__PURE__ */ jsx(
|
|
31699
|
+
"button",
|
|
31700
|
+
{
|
|
31701
|
+
type: "button",
|
|
31702
|
+
onClick: () => !disabled && setIsOpen(!isOpen),
|
|
31703
|
+
className: `
|
|
31704
|
+
w-full px-3 py-2 text-left bg-white border rounded-md shadow-sm
|
|
31705
|
+
${disabled ? "bg-gray-100 cursor-not-allowed" : "hover:bg-gray-50 cursor-pointer"}
|
|
31706
|
+
${required && !selectedSKU ? "border-red-300" : "border-gray-300"}
|
|
31707
|
+
focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500
|
|
31708
|
+
`,
|
|
31709
|
+
disabled,
|
|
31710
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
31711
|
+
/* @__PURE__ */ jsx("span", { className: selectedSKU ? "text-gray-900" : "text-gray-500", children: selectedSKU ? /* @__PURE__ */ jsxs("div", { children: [
|
|
31712
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: selectedSKU.sku_id }),
|
|
31713
|
+
/* @__PURE__ */ jsxs("span", { className: "text-sm text-gray-500 ml-2", children: [
|
|
31714
|
+
"(Target: ",
|
|
31715
|
+
selectedSKU.production_target,
|
|
31716
|
+
" units/day)"
|
|
31717
|
+
] })
|
|
31718
|
+
] }) : "Select SKU" }),
|
|
31719
|
+
/* @__PURE__ */ jsx(ChevronDown, { className: `w-4 h-4 text-gray-400 transition-transform ${isOpen ? "rotate-180" : ""}` })
|
|
31720
|
+
] })
|
|
31721
|
+
}
|
|
31722
|
+
),
|
|
31723
|
+
isOpen && /* @__PURE__ */ jsxs("div", { className: "absolute z-10 w-full mt-1 bg-white border border-gray-300 rounded-md shadow-lg", children: [
|
|
31724
|
+
/* @__PURE__ */ jsx("div", { className: "p-2 border-b", children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
31725
|
+
/* @__PURE__ */ jsx(Search, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 w-4 h-4 text-gray-400" }),
|
|
31726
|
+
/* @__PURE__ */ jsx(
|
|
31727
|
+
"input",
|
|
31728
|
+
{
|
|
31729
|
+
type: "text",
|
|
31730
|
+
value: searchTerm,
|
|
31731
|
+
onChange: (e) => setSearchTerm(e.target.value),
|
|
31732
|
+
placeholder: "Search SKUs...",
|
|
31733
|
+
className: "w-full pl-9 pr-3 py-2 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500",
|
|
31734
|
+
onClick: (e) => e.stopPropagation()
|
|
31735
|
+
}
|
|
31736
|
+
)
|
|
31737
|
+
] }) }),
|
|
31738
|
+
/* @__PURE__ */ jsxs("div", { className: "max-h-60 overflow-y-auto", children: [
|
|
31739
|
+
!required && /* @__PURE__ */ jsx(
|
|
31740
|
+
"button",
|
|
31741
|
+
{
|
|
31742
|
+
onClick: () => handleSelect(null),
|
|
31743
|
+
className: "w-full px-3 py-2 text-left text-sm hover:bg-gray-100 focus:outline-none focus:bg-gray-100",
|
|
31744
|
+
children: /* @__PURE__ */ jsx("span", { className: "text-gray-500", children: "No SKU" })
|
|
31745
|
+
}
|
|
31746
|
+
),
|
|
31747
|
+
filteredSKUs.length === 0 ? /* @__PURE__ */ jsx("div", { className: "px-3 py-2 text-sm text-gray-500", children: "No SKUs found" }) : filteredSKUs.map((sku) => /* @__PURE__ */ jsx(
|
|
31748
|
+
"button",
|
|
31749
|
+
{
|
|
31750
|
+
onClick: () => handleSelect(sku),
|
|
31751
|
+
className: `
|
|
31752
|
+
w-full px-3 py-2 text-left text-sm hover:bg-gray-100 focus:outline-none focus:bg-gray-100
|
|
31753
|
+
${selectedSKU?.id === sku.id ? "bg-blue-50" : ""}
|
|
31754
|
+
`,
|
|
31755
|
+
children: /* @__PURE__ */ jsxs("div", { children: [
|
|
31756
|
+
/* @__PURE__ */ jsx("div", { className: "font-medium", children: sku.sku_id }),
|
|
31757
|
+
/* @__PURE__ */ jsxs("div", { className: "text-xs text-gray-500", children: [
|
|
31758
|
+
"Target: ",
|
|
31759
|
+
sku.production_target,
|
|
31760
|
+
" units/day",
|
|
31761
|
+
Object.keys(sku.attributes || {}).length > 0 && /* @__PURE__ */ jsxs("span", { className: "ml-2", children: [
|
|
31762
|
+
"\u2022 ",
|
|
31763
|
+
Object.entries(sku.attributes).map(([key, value]) => `${key}: ${value}`).join(", ")
|
|
31764
|
+
] })
|
|
31765
|
+
] })
|
|
31766
|
+
] })
|
|
31767
|
+
},
|
|
31768
|
+
sku.id
|
|
31769
|
+
))
|
|
31770
|
+
] })
|
|
31771
|
+
] })
|
|
31772
|
+
] });
|
|
31773
|
+
};
|
|
31774
|
+
var SKUList = ({
|
|
31775
|
+
skus,
|
|
31776
|
+
onEdit,
|
|
31777
|
+
onDelete,
|
|
31778
|
+
isLoading = false
|
|
31779
|
+
}) => {
|
|
31780
|
+
if (isLoading) {
|
|
31781
|
+
return /* @__PURE__ */ jsx("div", { className: "bg-white rounded-xl shadow-sm border border-gray-200 p-8", children: /* @__PURE__ */ jsxs("div", { className: "flex justify-center items-center", children: [
|
|
31782
|
+
/* @__PURE__ */ jsx("div", { className: "animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600" }),
|
|
31783
|
+
/* @__PURE__ */ jsx("span", { className: "ml-3 text-gray-600", children: "Loading SKUs..." })
|
|
31784
|
+
] }) });
|
|
31785
|
+
}
|
|
31786
|
+
if (skus.length === 0) {
|
|
31787
|
+
return /* @__PURE__ */ jsx("div", { className: "bg-white rounded-xl shadow-sm border border-gray-200 p-12", children: /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
31788
|
+
/* @__PURE__ */ jsx(Package, { className: "mx-auto h-12 w-12 text-gray-400" }),
|
|
31789
|
+
/* @__PURE__ */ jsx("h3", { className: "mt-2 text-lg font-medium text-gray-900", children: "No SKUs found" }),
|
|
31790
|
+
/* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-gray-500", children: "Get started by creating a new SKU for production planning." })
|
|
31791
|
+
] }) });
|
|
31792
|
+
}
|
|
31793
|
+
return /* @__PURE__ */ jsx("div", { className: "bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden", children: /* @__PURE__ */ jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs("table", { className: "min-w-full divide-y divide-gray-200", children: [
|
|
31794
|
+
/* @__PURE__ */ jsx("thead", { className: "bg-gray-50", children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
31795
|
+
/* @__PURE__ */ jsx("th", { scope: "col", className: "px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider", children: "SKU ID" }),
|
|
31796
|
+
/* @__PURE__ */ jsx("th", { scope: "col", className: "px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider", children: "Production Target" }),
|
|
31797
|
+
/* @__PURE__ */ jsx("th", { scope: "col", className: "px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider", children: "Attributes" }),
|
|
31798
|
+
/* @__PURE__ */ jsx("th", { scope: "col", className: "px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider", children: "Status" }),
|
|
31799
|
+
/* @__PURE__ */ jsx("th", { scope: "col", className: "px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider", children: "Created" }),
|
|
31800
|
+
/* @__PURE__ */ jsx("th", { scope: "col", className: "relative px-6 py-3", children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Actions" }) })
|
|
31801
|
+
] }) }),
|
|
31802
|
+
/* @__PURE__ */ jsx("tbody", { className: "bg-white divide-y divide-gray-200", children: skus.map((sku) => /* @__PURE__ */ jsxs("tr", { className: "hover:bg-gray-50 transition-colors duration-150", children: [
|
|
31803
|
+
/* @__PURE__ */ jsx("td", { className: "px-6 py-4 whitespace-nowrap", children: /* @__PURE__ */ jsx("div", { className: "text-sm font-semibold text-gray-900", children: sku.sku_id }) }),
|
|
31804
|
+
/* @__PURE__ */ jsx("td", { className: "px-6 py-4 whitespace-nowrap", children: /* @__PURE__ */ jsxs("div", { className: "text-sm font-medium text-gray-700", children: [
|
|
31805
|
+
sku.production_target.toLocaleString(),
|
|
31806
|
+
" units/day"
|
|
31807
|
+
] }) }),
|
|
31808
|
+
/* @__PURE__ */ jsx("td", { className: "px-6 py-4", children: /* @__PURE__ */ jsx("div", { className: "text-sm text-gray-500", children: Object.keys(sku.attributes || {}).length === 0 ? /* @__PURE__ */ jsx("span", { className: "text-gray-400", children: "No attributes" }) : /* @__PURE__ */ jsx("div", { className: "max-w-xs truncate", children: Object.entries(sku.attributes).map(([key, value], index) => /* @__PURE__ */ jsxs("span", { children: [
|
|
31809
|
+
index > 0 && ", ",
|
|
31810
|
+
/* @__PURE__ */ jsxs("span", { className: "font-medium", children: [
|
|
31811
|
+
key,
|
|
31812
|
+
":"
|
|
31813
|
+
] }),
|
|
31814
|
+
" ",
|
|
31815
|
+
String(value)
|
|
31816
|
+
] }, key)) }) }) }),
|
|
31817
|
+
/* @__PURE__ */ jsx("td", { className: "px-6 py-4 whitespace-nowrap", children: /* @__PURE__ */ jsx("span", { className: `inline-flex px-2 py-1 text-xs font-semibold rounded-full ${sku.is_active ? "bg-green-100 text-green-800" : "bg-gray-100 text-gray-800"}`, children: sku.is_active ? "Active" : "Inactive" }) }),
|
|
31818
|
+
/* @__PURE__ */ jsx("td", { className: "px-6 py-4 whitespace-nowrap text-sm text-gray-500", children: new Date(sku.created_at).toLocaleDateString() }),
|
|
31819
|
+
/* @__PURE__ */ jsxs("td", { className: "px-6 py-4 whitespace-nowrap text-right text-sm font-medium", children: [
|
|
31820
|
+
/* @__PURE__ */ jsx(
|
|
31821
|
+
"button",
|
|
31822
|
+
{
|
|
31823
|
+
onClick: () => onEdit(sku),
|
|
31824
|
+
className: "text-blue-600 hover:text-blue-800 mr-3 transition-colors duration-150 p-1 hover:bg-blue-50 rounded",
|
|
31825
|
+
title: "Edit SKU",
|
|
31826
|
+
children: /* @__PURE__ */ jsx(Edit2, { className: "w-4 h-4" })
|
|
31827
|
+
}
|
|
31828
|
+
),
|
|
31829
|
+
/* @__PURE__ */ jsx(
|
|
31830
|
+
"button",
|
|
31831
|
+
{
|
|
31832
|
+
onClick: () => onDelete(sku),
|
|
31833
|
+
className: "text-red-600 hover:text-red-800 transition-colors duration-150 p-1 hover:bg-red-50 rounded",
|
|
31834
|
+
title: "Delete SKU",
|
|
31835
|
+
children: /* @__PURE__ */ jsx(Trash2, { className: "w-4 h-4" })
|
|
31836
|
+
}
|
|
31837
|
+
)
|
|
31838
|
+
] })
|
|
31839
|
+
] }, sku.id)) })
|
|
31840
|
+
] }) }) });
|
|
31841
|
+
};
|
|
30471
31842
|
var TargetsViewUI = ({
|
|
30472
31843
|
isLoading,
|
|
30473
31844
|
lineWorkspaces,
|
|
@@ -30486,7 +31857,12 @@ var TargetsViewUI = ({
|
|
|
30486
31857
|
onShiftChange,
|
|
30487
31858
|
onSaveLine,
|
|
30488
31859
|
onToggleBulkConfigure,
|
|
30489
|
-
onBulkConfigure
|
|
31860
|
+
onBulkConfigure,
|
|
31861
|
+
// SKU props
|
|
31862
|
+
skuEnabled = false,
|
|
31863
|
+
skus = [],
|
|
31864
|
+
onUpdateSelectedSKU,
|
|
31865
|
+
skuRequired = false
|
|
30490
31866
|
}) => {
|
|
30491
31867
|
if (isLoading) {
|
|
30492
31868
|
return /* @__PURE__ */ jsx("div", { className: "flex h-screen bg-gray-50", children: /* @__PURE__ */ jsx("div", { className: "flex-1 flex items-center justify-center", children: /* @__PURE__ */ jsx(Loader2, { className: "w-8 h-8 animate-spin text-blue-600" }) }) });
|
|
@@ -30602,6 +31978,26 @@ var TargetsViewUI = ({
|
|
|
30602
31978
|
] })
|
|
30603
31979
|
] }) }),
|
|
30604
31980
|
line.isOpen && /* @__PURE__ */ jsxs("div", { id: `line-${lineId}-content`, className: "border-t border-gray-200", children: [
|
|
31981
|
+
skuEnabled && /* @__PURE__ */ jsx("div", { className: "px-6 py-4 border-b border-gray-200 bg-gray-50/50", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4", children: [
|
|
31982
|
+
/* @__PURE__ */ jsx("label", { htmlFor: `sku-${lineId}`, className: "text-sm font-medium text-gray-700", children: "Select SKU:" }),
|
|
31983
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 max-w-md", children: /* @__PURE__ */ jsx(
|
|
31984
|
+
SKUSelector,
|
|
31985
|
+
{
|
|
31986
|
+
onSelect: (sku) => onUpdateSelectedSKU?.(lineId, sku),
|
|
31987
|
+
selectedSKU: line.selectedSKU || null,
|
|
31988
|
+
availableSKUs: skus,
|
|
31989
|
+
lineId,
|
|
31990
|
+
required: skuRequired,
|
|
31991
|
+
className: "w-full"
|
|
31992
|
+
}
|
|
31993
|
+
) }),
|
|
31994
|
+
line.selectedSKU && /* @__PURE__ */ jsxs("div", { className: "text-sm text-gray-600", children: [
|
|
31995
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: "Production Target:" }),
|
|
31996
|
+
" ",
|
|
31997
|
+
line.selectedSKU.production_target.toLocaleString(),
|
|
31998
|
+
" units/day"
|
|
31999
|
+
] })
|
|
32000
|
+
] }) }),
|
|
30605
32001
|
/* @__PURE__ */ jsx("div", { className: "px-6 py-3 bg-gray-50 border-b border-gray-200", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-12 gap-6 text-sm font-medium text-gray-600", children: [
|
|
30606
32002
|
/* @__PURE__ */ jsx("div", { className: "col-span-2", children: "Workspace" }),
|
|
30607
32003
|
/* @__PURE__ */ jsx("div", { className: "col-span-2", children: "Action Type" }),
|
|
@@ -30648,7 +32044,7 @@ var TargetsViewUI = ({
|
|
|
30648
32044
|
onChange: (e) => onUpdateWorkspaceTarget(lineId, workspace.id, "targetCycleTime", Number(e.target.value) || ""),
|
|
30649
32045
|
className: "block w-full rounded-lg border border-gray-300 bg-white px-3 py-2 text-sm\n shadow-sm focus:border-blue-500 focus:ring-blue-500 \n transition-all duration-200 hover:border-gray-400",
|
|
30650
32046
|
min: "0",
|
|
30651
|
-
step: "
|
|
32047
|
+
step: "0.01",
|
|
30652
32048
|
placeholder: "Enter cycle time"
|
|
30653
32049
|
}
|
|
30654
32050
|
) }),
|
|
@@ -30739,6 +32135,9 @@ var TargetsView = ({
|
|
|
30739
32135
|
const supabase = useSupabase();
|
|
30740
32136
|
const auth = useAuth();
|
|
30741
32137
|
userId || auth?.user?.id;
|
|
32138
|
+
const dashboardConfig = useDashboardConfig();
|
|
32139
|
+
const { skus, isLoading: skusLoading } = useSKUs(companyId);
|
|
32140
|
+
const skuEnabled = dashboardConfig?.skuConfig?.enabled || false;
|
|
30742
32141
|
useEffect(() => {
|
|
30743
32142
|
const fetchLineDetails = async () => {
|
|
30744
32143
|
if (!supabase || lineIds.length === 0) return;
|
|
@@ -31106,6 +32505,41 @@ var TargetsView = ({
|
|
|
31106
32505
|
}
|
|
31107
32506
|
}));
|
|
31108
32507
|
};
|
|
32508
|
+
const updateSelectedSKU = (lineId, sku) => {
|
|
32509
|
+
setLineWorkspaces((prev) => ({
|
|
32510
|
+
...prev,
|
|
32511
|
+
[lineId]: {
|
|
32512
|
+
...prev[lineId],
|
|
32513
|
+
selectedSKU: sku,
|
|
32514
|
+
productId: sku?.sku_id || prev[lineId].productId
|
|
32515
|
+
// Update productId with SKU ID
|
|
32516
|
+
}
|
|
32517
|
+
}));
|
|
32518
|
+
if (sku && sku.production_target > 0) {
|
|
32519
|
+
const lineData = lineWorkspaces[lineId];
|
|
32520
|
+
const workspaceCount = lineData.workspaces.length;
|
|
32521
|
+
if (workspaceCount > 0) {
|
|
32522
|
+
const targetPerWorkspace = Math.floor(sku.production_target / workspaceCount);
|
|
32523
|
+
const pphPerWorkspace = calculatePPH(
|
|
32524
|
+
lineData.shiftHours > 0 ? lineData.shiftHours * 3600 / targetPerWorkspace : 0,
|
|
32525
|
+
lineData.breaks,
|
|
32526
|
+
lineData.shiftHours
|
|
32527
|
+
);
|
|
32528
|
+
setLineWorkspaces((prev) => ({
|
|
32529
|
+
...prev,
|
|
32530
|
+
[lineId]: {
|
|
32531
|
+
...prev[lineId],
|
|
32532
|
+
workspaces: prev[lineId].workspaces.map((ws) => ({
|
|
32533
|
+
...ws,
|
|
32534
|
+
targetDayOutput: targetPerWorkspace,
|
|
32535
|
+
targetPPH: pphPerWorkspace,
|
|
32536
|
+
targetCycleTime: lineData.shiftHours > 0 ? parseFloat((lineData.shiftHours * 3600 / targetPerWorkspace).toFixed(2)) : ""
|
|
32537
|
+
}))
|
|
32538
|
+
}
|
|
32539
|
+
}));
|
|
32540
|
+
}
|
|
32541
|
+
}
|
|
32542
|
+
};
|
|
31109
32543
|
const updateWorkspaceTarget = (lineId, workspaceId, field, value) => {
|
|
31110
32544
|
setLineWorkspaces((prev) => {
|
|
31111
32545
|
const shiftHours = prev[lineId].shiftHours;
|
|
@@ -31238,6 +32672,11 @@ var TargetsView = ({
|
|
|
31238
32672
|
return;
|
|
31239
32673
|
}
|
|
31240
32674
|
console.log(`[handleSaveLine] factoryId for ${lineId}: ${lineDataToSave.factoryId}`);
|
|
32675
|
+
if (skuEnabled && dashboardConfig?.skuConfig?.requireSKUSelection && !lineDataToSave.selectedSKU) {
|
|
32676
|
+
console.log(`[handleSaveLine] Exiting: SKU selection required but not selected for lineId: ${lineId}`);
|
|
32677
|
+
toast.error("Please select a SKU before saving.");
|
|
32678
|
+
return;
|
|
32679
|
+
}
|
|
31241
32680
|
const currentFactoryId = lineDataToSave.factoryId;
|
|
31242
32681
|
const currentDate = getOperationalDate();
|
|
31243
32682
|
console.log(`[handleSaveLine] currentDate: ${currentDate}, selectedShift: ${selectedShift}`);
|
|
@@ -31251,8 +32690,9 @@ var TargetsView = ({
|
|
|
31251
32690
|
ideal_cycle_time: Number(ws.targetCycleTime) || 0,
|
|
31252
32691
|
total_day_output: Number(ws.targetDayOutput) || 0,
|
|
31253
32692
|
action_name: ws.actionType === "assembly" ? ACTION_NAMES.ASSEMBLY : ACTION_NAMES.PACKAGING,
|
|
31254
|
-
updated_by: currentEffectiveUserId
|
|
32693
|
+
updated_by: currentEffectiveUserId,
|
|
31255
32694
|
// Use the potentially hardcoded ID
|
|
32695
|
+
...skuEnabled && lineDataToSave.selectedSKU ? { sku_id: lineDataToSave.selectedSKU.id } : {}
|
|
31256
32696
|
}));
|
|
31257
32697
|
console.log(`[handleSaveLine] workspaceThresholdUpdates for ${lineId}:`, workspaceThresholdUpdates);
|
|
31258
32698
|
await workspaceService.updateActionThresholds(workspaceThresholdUpdates);
|
|
@@ -31264,7 +32704,8 @@ var TargetsView = ({
|
|
|
31264
32704
|
shift_id: selectedShift,
|
|
31265
32705
|
product_code: lineDataToSave.productId,
|
|
31266
32706
|
threshold_day_output: lineDataToSave.workspaces.reduce((acc, ws) => acc + (Number(ws.targetDayOutput) || 0), 0),
|
|
31267
|
-
threshold_pph: lineDataToSave.workspaces.reduce((acc, ws) => acc + (Number(ws.targetPPH) || 0), 0)
|
|
32707
|
+
threshold_pph: lineDataToSave.workspaces.reduce((acc, ws) => acc + (Number(ws.targetPPH) || 0), 0),
|
|
32708
|
+
...skuEnabled && lineDataToSave.selectedSKU ? { sku_id: lineDataToSave.selectedSKU.id } : {}
|
|
31268
32709
|
};
|
|
31269
32710
|
console.log(`[handleSaveLine] lineThresholdData for upsert on ${lineId}:`, lineThresholdData);
|
|
31270
32711
|
const { error: lineUpsertError } = await supabase.from("line_thresholds").upsert(lineThresholdData, { onConflict: "factory_id,line_id,date,shift_id" });
|
|
@@ -31359,7 +32800,7 @@ var TargetsView = ({
|
|
|
31359
32800
|
return /* @__PURE__ */ jsx(
|
|
31360
32801
|
TargetsViewUI_default,
|
|
31361
32802
|
{
|
|
31362
|
-
isLoading,
|
|
32803
|
+
isLoading: isLoading || skusLoading,
|
|
31363
32804
|
lineWorkspaces,
|
|
31364
32805
|
lineNames,
|
|
31365
32806
|
savingLines,
|
|
@@ -31376,7 +32817,11 @@ var TargetsView = ({
|
|
|
31376
32817
|
onShiftChange: handleShiftChange,
|
|
31377
32818
|
onSaveLine: handleSaveLine,
|
|
31378
32819
|
onToggleBulkConfigure: handleToggleBulkConfigure,
|
|
31379
|
-
onBulkConfigure: handleBulkConfigure
|
|
32820
|
+
onBulkConfigure: handleBulkConfigure,
|
|
32821
|
+
skuEnabled,
|
|
32822
|
+
skus,
|
|
32823
|
+
onUpdateSelectedSKU: updateSelectedSKU,
|
|
32824
|
+
skuRequired: dashboardConfig?.skuConfig?.requireSKUSelection || false
|
|
31380
32825
|
}
|
|
31381
32826
|
);
|
|
31382
32827
|
};
|
|
@@ -31635,7 +33080,43 @@ var WorkspaceDetailView = ({
|
|
|
31635
33080
|
}
|
|
31636
33081
|
};
|
|
31637
33082
|
if (loading) {
|
|
31638
|
-
return /* @__PURE__ */ jsx(
|
|
33083
|
+
return /* @__PURE__ */ jsx(
|
|
33084
|
+
motion.div,
|
|
33085
|
+
{
|
|
33086
|
+
className: "min-h-screen bg-slate-50",
|
|
33087
|
+
initial: { opacity: 0 },
|
|
33088
|
+
animate: { opacity: 1 },
|
|
33089
|
+
transition: { duration: 0.3 },
|
|
33090
|
+
children: /* @__PURE__ */ jsxs("div", { className: "min-h-screen w-full flex flex-col bg-slate-50", children: [
|
|
33091
|
+
/* @__PURE__ */ jsx("header", { className: "sticky top-0 z-10 px-2 sm:px-2.5 lg:px-3 py-1.5 sm:py-2 lg:py-3 flex flex-col shadow-sm bg-white", children: /* @__PURE__ */ jsxs("div", { className: "relative flex items-center", children: [
|
|
33092
|
+
/* @__PURE__ */ jsx("div", { className: "absolute left-0 animate-pulse", children: /* @__PURE__ */ jsx("div", { className: "h-8 w-20 bg-gray-200 rounded" }) }),
|
|
33093
|
+
/* @__PURE__ */ jsx("div", { className: "absolute left-1/2 transform -translate-x-1/2 animate-pulse", children: /* @__PURE__ */ jsx("div", { className: "h-6 w-40 bg-gray-200 rounded" }) }),
|
|
33094
|
+
/* @__PURE__ */ jsx("div", { className: "w-full h-8" })
|
|
33095
|
+
] }) }),
|
|
33096
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 p-4 sm:p-6 lg:p-8", children: [
|
|
33097
|
+
/* @__PURE__ */ jsx("div", { className: "mb-6", children: /* @__PURE__ */ jsxs("div", { className: "flex space-x-4 justify-center animate-pulse", children: [
|
|
33098
|
+
/* @__PURE__ */ jsx("div", { className: "h-10 w-32 bg-gray-200 rounded-lg" }),
|
|
33099
|
+
/* @__PURE__ */ jsx("div", { className: "h-10 w-32 bg-gray-200 rounded-lg" }),
|
|
33100
|
+
/* @__PURE__ */ jsx("div", { className: "h-10 w-32 bg-gray-200 rounded-lg" })
|
|
33101
|
+
] }) }),
|
|
33102
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-4 mb-6", children: [1, 2, 3, 4].map((i) => /* @__PURE__ */ jsx("div", { className: "bg-white rounded-lg p-4 shadow-sm", children: /* @__PURE__ */ jsxs("div", { className: "animate-pulse", children: [
|
|
33103
|
+
/* @__PURE__ */ jsx("div", { className: "h-4 w-20 bg-gray-200 rounded mb-2" }),
|
|
33104
|
+
/* @__PURE__ */ jsx("div", { className: "h-8 w-16 bg-gray-200 rounded" })
|
|
33105
|
+
] }) }, i)) }),
|
|
33106
|
+
/* @__PURE__ */ jsx("div", { className: "bg-white rounded-lg p-6 shadow-sm", children: /* @__PURE__ */ jsxs("div", { className: "animate-pulse", children: [
|
|
33107
|
+
/* @__PURE__ */ jsx("div", { className: "h-6 w-40 bg-gray-200 rounded mb-4" }),
|
|
33108
|
+
/* @__PURE__ */ jsx("div", { className: "h-64 bg-gray-100 rounded relative overflow-hidden", children: /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsxs("div", { className: "bg-white/80 rounded-lg p-4 shadow-sm", children: [
|
|
33109
|
+
/* @__PURE__ */ jsxs("svg", { className: "animate-spin h-8 w-8 text-blue-500", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [
|
|
33110
|
+
/* @__PURE__ */ jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
|
|
33111
|
+
/* @__PURE__ */ jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })
|
|
33112
|
+
] }),
|
|
33113
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-gray-600 mt-2", children: "Loading chart data..." })
|
|
33114
|
+
] }) }) })
|
|
33115
|
+
] }) })
|
|
33116
|
+
] })
|
|
33117
|
+
] })
|
|
33118
|
+
}
|
|
33119
|
+
);
|
|
31639
33120
|
}
|
|
31640
33121
|
if (error) {
|
|
31641
33122
|
return /* @__PURE__ */ jsxs("div", { className: "min-h-screen p-8 bg-slate-50", children: [
|
|
@@ -32075,6 +33556,144 @@ var WorkspaceDetailView = ({
|
|
|
32075
33556
|
};
|
|
32076
33557
|
var WrappedComponent = withAuth(WorkspaceDetailView);
|
|
32077
33558
|
var WorkspaceDetailView_default = WrappedComponent;
|
|
33559
|
+
var SKUManagementView = () => {
|
|
33560
|
+
const config = useDashboardConfig();
|
|
33561
|
+
const companyId = config?.entityConfig?.companyId || "";
|
|
33562
|
+
const router = useRouter();
|
|
33563
|
+
const { skus, isLoading, error, refetch } = useSKUs(companyId);
|
|
33564
|
+
const [isModalOpen, setIsModalOpen] = useState(false);
|
|
33565
|
+
const [editingSKU, setEditingSKU] = useState(null);
|
|
33566
|
+
const [deleteConfirmSKU, setDeleteConfirmSKU] = useState(null);
|
|
33567
|
+
useEffect(() => {
|
|
33568
|
+
trackCoreEvent("SKU Management Page Viewed");
|
|
33569
|
+
}, []);
|
|
33570
|
+
const handleCreateOrUpdate = async (skuData) => {
|
|
33571
|
+
try {
|
|
33572
|
+
if (editingSKU) {
|
|
33573
|
+
await skuService.updateSKU(editingSKU.id, {
|
|
33574
|
+
production_target: skuData.production_target,
|
|
33575
|
+
attributes: skuData.attributes
|
|
33576
|
+
});
|
|
33577
|
+
trackCoreEvent("SKU Updated", {
|
|
33578
|
+
sku_id: editingSKU.sku_id,
|
|
33579
|
+
production_target: skuData.production_target
|
|
33580
|
+
});
|
|
33581
|
+
} else {
|
|
33582
|
+
const exists = await skuService.checkSKUExists(companyId, skuData.sku_id);
|
|
33583
|
+
if (exists) {
|
|
33584
|
+
throw new Error("SKU ID already exists");
|
|
33585
|
+
}
|
|
33586
|
+
await skuService.createSKU(skuData);
|
|
33587
|
+
trackCoreEvent("SKU Created", {
|
|
33588
|
+
sku_id: skuData.sku_id,
|
|
33589
|
+
production_target: skuData.production_target
|
|
33590
|
+
});
|
|
33591
|
+
}
|
|
33592
|
+
setIsModalOpen(false);
|
|
33593
|
+
setEditingSKU(null);
|
|
33594
|
+
refetch();
|
|
33595
|
+
} catch (error2) {
|
|
33596
|
+
console.error("Error saving SKU:", error2);
|
|
33597
|
+
throw error2;
|
|
33598
|
+
}
|
|
33599
|
+
};
|
|
33600
|
+
const handleEdit = (sku) => {
|
|
33601
|
+
setEditingSKU(sku);
|
|
33602
|
+
setIsModalOpen(true);
|
|
33603
|
+
};
|
|
33604
|
+
const handleDelete = async (sku) => {
|
|
33605
|
+
if (deleteConfirmSKU?.id === sku.id) {
|
|
33606
|
+
try {
|
|
33607
|
+
await skuService.deleteSKU(sku.id);
|
|
33608
|
+
trackCoreEvent("SKU Deleted", { sku_id: sku.sku_id });
|
|
33609
|
+
setDeleteConfirmSKU(null);
|
|
33610
|
+
refetch();
|
|
33611
|
+
} catch (error2) {
|
|
33612
|
+
console.error("Error deleting SKU:", error2);
|
|
33613
|
+
}
|
|
33614
|
+
} else {
|
|
33615
|
+
setDeleteConfirmSKU(sku);
|
|
33616
|
+
setTimeout(() => setDeleteConfirmSKU(null), 3e3);
|
|
33617
|
+
}
|
|
33618
|
+
};
|
|
33619
|
+
const handleAddNew = () => {
|
|
33620
|
+
setEditingSKU(null);
|
|
33621
|
+
setIsModalOpen(true);
|
|
33622
|
+
};
|
|
33623
|
+
const handleBack = () => {
|
|
33624
|
+
router.push("/");
|
|
33625
|
+
};
|
|
33626
|
+
if (!config?.skuConfig?.enabled) {
|
|
33627
|
+
return /* @__PURE__ */ jsx("div", { className: "min-h-screen bg-slate-50 flex items-center justify-center", children: /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
33628
|
+
/* @__PURE__ */ jsx(Package, { className: "mx-auto h-12 w-12 text-gray-400" }),
|
|
33629
|
+
/* @__PURE__ */ jsx("h3", { className: "mt-2 text-sm font-medium text-gray-900", children: "SKU Management Disabled" }),
|
|
33630
|
+
/* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-gray-500", children: "SKU management is not enabled for this workspace." })
|
|
33631
|
+
] }) });
|
|
33632
|
+
}
|
|
33633
|
+
return /* @__PURE__ */ jsxs("div", { className: "min-h-screen bg-slate-50", children: [
|
|
33634
|
+
/* @__PURE__ */ jsx("div", { className: "sticky top-0 z-10 bg-white border-b border-gray-200/80 shadow-sm", children: /* @__PURE__ */ jsx("div", { className: "px-4 sm:px-8 py-4", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center relative", children: [
|
|
33635
|
+
/* @__PURE__ */ jsxs(
|
|
33636
|
+
"button",
|
|
33637
|
+
{
|
|
33638
|
+
onClick: handleBack,
|
|
33639
|
+
className: "absolute left-0 flex items-center gap-2 text-gray-600 hover:text-gray-900 transition-colors",
|
|
33640
|
+
children: [
|
|
33641
|
+
/* @__PURE__ */ jsx(ArrowLeft, { className: "h-5 w-5" }),
|
|
33642
|
+
/* @__PURE__ */ jsx("span", { children: "Back" })
|
|
33643
|
+
]
|
|
33644
|
+
}
|
|
33645
|
+
),
|
|
33646
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 text-center mx-auto", children: [
|
|
33647
|
+
/* @__PURE__ */ jsx("h1", { className: "text-2xl font-semibold text-gray-900", children: "SKU Management" }),
|
|
33648
|
+
/* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-gray-500", children: "Manage Stock Keeping Units (SKUs) for production planning" })
|
|
33649
|
+
] }),
|
|
33650
|
+
/* @__PURE__ */ jsxs(
|
|
33651
|
+
"button",
|
|
33652
|
+
{
|
|
33653
|
+
onClick: handleAddNew,
|
|
33654
|
+
className: "absolute right-0 inline-flex items-center px-4 py-2 bg-blue-600 text-white text-sm font-medium rounded-lg hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 transition-all duration-200 shadow-sm",
|
|
33655
|
+
children: [
|
|
33656
|
+
/* @__PURE__ */ jsx(Plus, { className: "w-4 h-4 mr-2" }),
|
|
33657
|
+
"Add SKU"
|
|
33658
|
+
]
|
|
33659
|
+
}
|
|
33660
|
+
)
|
|
33661
|
+
] }) }) }),
|
|
33662
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 overflow-auto", children: /* @__PURE__ */ jsxs("div", { className: "px-4 sm:px-8 py-6", children: [
|
|
33663
|
+
/* @__PURE__ */ jsx("div", { className: "mb-6 bg-gradient-to-r from-blue-50 to-blue-50/50 p-4 rounded-xl border border-blue-100", children: /* @__PURE__ */ jsx("p", { className: "text-sm text-blue-700 font-medium", children: "Create and manage SKUs with production targets. These will be available for selection in the production targets page." }) }),
|
|
33664
|
+
error ? /* @__PURE__ */ jsxs("div", { className: "bg-red-50 border border-red-200 text-red-700 p-4 rounded-lg", children: [
|
|
33665
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: "Error loading SKUs" }),
|
|
33666
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm mt-1", children: error.message })
|
|
33667
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
33668
|
+
/* @__PURE__ */ jsx(
|
|
33669
|
+
SKUList,
|
|
33670
|
+
{
|
|
33671
|
+
skus,
|
|
33672
|
+
onEdit: handleEdit,
|
|
33673
|
+
onDelete: handleDelete,
|
|
33674
|
+
isLoading
|
|
33675
|
+
}
|
|
33676
|
+
),
|
|
33677
|
+
deleteConfirmSKU && /* @__PURE__ */ jsx("div", { className: "mt-4 bg-yellow-50 border border-yellow-200 text-yellow-800 p-4 rounded-lg", children: /* @__PURE__ */ jsxs("p", { className: "text-sm", children: [
|
|
33678
|
+
"Click delete again to confirm deletion of SKU: ",
|
|
33679
|
+
/* @__PURE__ */ jsx("strong", { children: deleteConfirmSKU.sku_id })
|
|
33680
|
+
] }) })
|
|
33681
|
+
] })
|
|
33682
|
+
] }) }),
|
|
33683
|
+
/* @__PURE__ */ jsx(
|
|
33684
|
+
SKUModal,
|
|
33685
|
+
{
|
|
33686
|
+
isOpen: isModalOpen,
|
|
33687
|
+
onClose: () => {
|
|
33688
|
+
setIsModalOpen(false);
|
|
33689
|
+
setEditingSKU(null);
|
|
33690
|
+
},
|
|
33691
|
+
onSave: handleCreateOrUpdate,
|
|
33692
|
+
editingSKU
|
|
33693
|
+
}
|
|
33694
|
+
)
|
|
33695
|
+
] });
|
|
33696
|
+
};
|
|
32078
33697
|
var S3Service = class {
|
|
32079
33698
|
constructor(config) {
|
|
32080
33699
|
this.s3Client = null;
|
|
@@ -32313,4 +33932,4 @@ var S3Service = class {
|
|
|
32313
33932
|
}
|
|
32314
33933
|
};
|
|
32315
33934
|
|
|
32316
|
-
export { ACTION_NAMES, AIAgentView_default as AIAgentView, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedTargetsView, BarChart, BaseHistoryCalendar, BottlenecksContent, BreakNotificationPopup, Card2 as Card, CardContent2 as CardContent, CardDescription2 as CardDescription, CardFooter2 as CardFooter, CardHeader2 as CardHeader, CardTitle2 as CardTitle, CycleTimeChart, CycleTimeOverTimeChart, DEFAULT_ANALYTICS_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_CONFIG, DEFAULT_DATABASE_CONFIG, DEFAULT_DATE_TIME_CONFIG, DEFAULT_ENDPOINTS_CONFIG, DEFAULT_ENTITY_CONFIG, DEFAULT_SHIFT_CONFIG, DEFAULT_THEME_CONFIG, DEFAULT_VIDEO_CONFIG, DEFAULT_WORKSPACE_CONFIG, DEFAULT_WORKSPACE_POSITIONS, DashboardHeader, DashboardLayout, DashboardOverridesProvider, DashboardProvider, DateDisplay_default as DateDisplay, DateTimeDisplay, DebugAuth, DebugAuthView_default as DebugAuthView, EmptyStateMessage, FactoryView_default as FactoryView, GaugeChart, GridComponentsPlaceholder, Header, HelpView_default as HelpView, HomeView_default as HomeView, HourlyOutputChart2 as HourlyOutputChart, ISTTimer_default as ISTTimer, KPICard, KPIDetailView_default as KPIDetailView, KPIGrid, KPIHeader, KPISection, KPIsOverviewView_default as KPIsOverviewView, LINE_1_UUID, LINE_2_UUID, LargeOutputProgressChart, LeaderboardDetailView_default as LeaderboardDetailView, Legend6 as Legend, LineChart, LineHistoryCalendar, LineMonthlyHistory, LineMonthlyPdfGenerator, LinePdfExportButton, LinePdfGenerator, LineWhatsAppShareButton, LiveTimer, LoadingOverlay_default as LoadingOverlay, LoadingPage_default as LoadingPage, LoadingSpinner_default as LoadingSpinner, LoginPage, LoginView_default as LoginView, MainLayout, MetricCard_default as MetricCard, NoWorkspaceData, OptifyeAgentClient, OutputProgressChart, PageHeader, PieChart4 as PieChart, ProfileView_default as ProfileView, RegistryProvider, S3Service, SOPComplianceChart, SSEChatClient, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, ShiftDisplay_default as ShiftDisplay, ShiftsView_default as ShiftsView, SideNavBar, SingleVideoStream_default as SingleVideoStream, Skeleton, SlackAPI, SupabaseProvider, TargetWorkspaceGrid, TargetsView_default as TargetsView, ThreadSidebar, TimeDisplay_default as TimeDisplay, TimePickerDropdown, VideoCard, VideoGridView, VideoPreloader, WORKSPACE_POSITIONS, WhatsAppShareButton, WorkspaceCard, WorkspaceDetailView_default as WorkspaceDetailView, WorkspaceDisplayNameExample, WorkspaceGrid, WorkspaceGridItem, WorkspaceHistoryCalendar, WorkspaceMetricCards, WorkspaceMonthlyDataFetcher, WorkspaceMonthlyPdfGenerator, WorkspacePdfExportButton, WorkspacePdfGenerator, WorkspaceWhatsAppShareButton, actionService, apiUtils, authCoreService, authOTPService, authRateLimitService, checkRateLimit2 as checkRateLimit, clearAllRateLimits2 as clearAllRateLimits, clearRateLimit2 as clearRateLimit, clearS3VideoCache, clearS3VideoFromCache, clearWorkspaceDisplayNamesCache, cn, createStreamProxyHandler, createSupabaseClient, createThrottledReload, dashboardService, deleteThread, forceRefreshWorkspaceDisplayNames, formatDateInZone, formatDateTimeInZone, formatISTDate, formatIdleTime, formatTimeInZone, fromUrlFriendlyName, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAnonClient, getCameraNumber, getCompanyMetricsTableName, getConfigurableShortWorkspaceDisplayName, getConfigurableWorkspaceDisplayName, getCurrentShift, getCurrentTimeInZone, getDashboardHeaderTimeInZone, getDaysDifferenceInZone, getDefaultCameraStreamUrl, getDefaultTabForWorkspace, getManufacturingInsights, getMetricsTablePrefix, getOperationalDate, getS3SignedUrl, getS3VideoSrc, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getThreadMessages, getUserThreads, getUserThreadsPaginated, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, identifyCoreUser, initializeCoreMixpanel, isTransitionPeriod, isValidLineInfoPayload, isValidWorkspaceDetailedMetricsPayload, isValidWorkspaceMetricsPayload, isWorkspaceDisplayNamesLoaded, isWorkspaceDisplayNamesLoading, mergeWithDefaultConfig, optifyeAgentClient, preInitializeWorkspaceDisplayNames, preloadS3Video, preloadS3VideoUrl, preloadS3VideosUrl, preloadVideoUrl, preloadVideosUrl, qualityService, realtimeService, refreshWorkspaceDisplayNames, resetCoreMixpanel, s3VideoPreloader, storeWorkspaceMapping, streamProxyConfig, throttledReloadDashboard, toUrlFriendlyName, trackCoreEvent, trackCorePageView, updateThreadTitle, useActiveBreaks, useAllWorkspaceMetrics, useAnalyticsConfig, useAuth, useAuthConfig, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHistoricWorkspaceMetrics, useHlsStream, useHlsStreamWithCropping, useHookOverride, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineWorkspaceMetrics, useMessages, useMetrics, useNavigation, useOverrides, usePageOverride, useRealtimeLineMetrics, useRegistry, useShiftConfig, useShifts, useSupabase, useSupabaseClient, useTargets, useTheme, useThemeConfig, useThreads, useVideoConfig, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, videoPreloader, whatsappService, withAuth, withRegistry, workspaceService };
|
|
33935
|
+
export { ACTION_NAMES, AIAgentView_default as AIAgentView, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedTargetsView, BarChart, BaseHistoryCalendar, BottlenecksContent, BreakNotificationPopup, Card2 as Card, CardContent2 as CardContent, CardDescription2 as CardDescription, CardFooter2 as CardFooter, CardHeader2 as CardHeader, CardTitle2 as CardTitle, CycleTimeChart, CycleTimeOverTimeChart, DEFAULT_ANALYTICS_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_CONFIG, DEFAULT_DATABASE_CONFIG, DEFAULT_DATE_TIME_CONFIG, DEFAULT_ENDPOINTS_CONFIG, DEFAULT_ENTITY_CONFIG, DEFAULT_SHIFT_CONFIG, DEFAULT_THEME_CONFIG, DEFAULT_VIDEO_CONFIG, DEFAULT_WORKSPACE_CONFIG, DEFAULT_WORKSPACE_POSITIONS, DashboardHeader, DashboardLayout, DashboardOverridesProvider, DashboardProvider, DateDisplay_default as DateDisplay, DateTimeDisplay, DebugAuth, DebugAuthView_default as DebugAuthView, EmptyStateMessage, FactoryView_default as FactoryView, GaugeChart, GridComponentsPlaceholder, Header, HelpView_default as HelpView, HomeView_default as HomeView, HourlyOutputChart2 as HourlyOutputChart, ISTTimer_default as ISTTimer, KPICard, KPIDetailView_default as KPIDetailView, KPIGrid, KPIHeader, KPISection, KPIsOverviewView_default as KPIsOverviewView, LINE_1_UUID, LINE_2_UUID, LargeOutputProgressChart, LeaderboardDetailView_default as LeaderboardDetailView, Legend6 as Legend, LineChart, LineHistoryCalendar, LineMonthlyHistory, LineMonthlyPdfGenerator, LinePdfExportButton, LinePdfGenerator, LineWhatsAppShareButton, LiveTimer, LoadingInline, LoadingOverlay_default as LoadingOverlay, LoadingPage_default as LoadingPage, LoadingSkeleton, LoadingSpinner_default as LoadingSpinner, LoadingState, LoginPage, LoginView_default as LoginView, MainLayout, MetricCard_default as MetricCard, NoWorkspaceData, OptifyeAgentClient, OutputProgressChart, PageHeader, PieChart4 as PieChart, ProfileView_default as ProfileView, RegistryProvider, S3Service, SKUManagementView, SOPComplianceChart, SSEChatClient, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, ShiftDisplay_default as ShiftDisplay, ShiftsView_default as ShiftsView, SideNavBar, SingleVideoStream_default as SingleVideoStream, Skeleton, SlackAPI, SubscriptionManager, SubscriptionManagerProvider, SupabaseProvider, TargetWorkspaceGrid, TargetsView_default as TargetsView, ThreadSidebar, TimeDisplay_default as TimeDisplay, TimePickerDropdown, VideoCard, VideoGridView, VideoPreloader, WORKSPACE_POSITIONS, WhatsAppShareButton, WorkspaceCard, WorkspaceDetailView_default as WorkspaceDetailView, WorkspaceDisplayNameExample, WorkspaceGrid, WorkspaceGridItem, WorkspaceHistoryCalendar, WorkspaceMetricCards, WorkspaceMonthlyDataFetcher, WorkspaceMonthlyPdfGenerator, WorkspacePdfExportButton, WorkspacePdfGenerator, WorkspaceWhatsAppShareButton, actionService, apiUtils, authCoreService, authOTPService, authRateLimitService, cacheService, checkRateLimit2 as checkRateLimit, clearAllRateLimits2 as clearAllRateLimits, clearRateLimit2 as clearRateLimit, clearS3VideoCache, clearS3VideoFromCache, clearWorkspaceDisplayNamesCache, cn, createStreamProxyHandler, createSupabaseClient, createThrottledReload, dashboardService, deleteThread, forceRefreshWorkspaceDisplayNames, formatDateInZone, formatDateTimeInZone, formatISTDate, formatIdleTime, formatTimeInZone, fromUrlFriendlyName, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAnonClient, getCameraNumber, getCompanyMetricsTableName, getConfigurableShortWorkspaceDisplayName, getConfigurableWorkspaceDisplayName, getCurrentShift, getCurrentTimeInZone, getDashboardHeaderTimeInZone, getDaysDifferenceInZone, getDefaultCameraStreamUrl, getDefaultTabForWorkspace, getManufacturingInsights, getMetricsTablePrefix, getOperationalDate, getS3SignedUrl, getS3VideoSrc, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getSubscriptionManager, getThreadMessages, getUserThreads, getUserThreadsPaginated, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, identifyCoreUser, initializeCoreMixpanel, isTransitionPeriod, isValidLineInfoPayload, isValidWorkspaceDetailedMetricsPayload, isValidWorkspaceMetricsPayload, isWorkspaceDisplayNamesLoaded, isWorkspaceDisplayNamesLoading, mergeWithDefaultConfig, optifyeAgentClient, preInitializeWorkspaceDisplayNames, preloadS3Video, preloadS3VideoUrl, preloadS3VideosUrl, preloadVideoUrl, preloadVideosUrl, qualityService, realtimeService, refreshWorkspaceDisplayNames, resetCoreMixpanel, resetSubscriptionManager, s3VideoPreloader, skuService, storeWorkspaceMapping, streamProxyConfig, throttledReloadDashboard, toUrlFriendlyName, trackCoreEvent, trackCorePageView, updateThreadTitle, useActiveBreaks, useAllWorkspaceMetrics, useAnalyticsConfig, useAuth, useAuthConfig, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHistoricWorkspaceMetrics, useHlsStream, useHlsStreamWithCropping, useHookOverride, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineWorkspaceMetrics, useMessages, useMetrics, useNavigation, useOverrides, usePageOverride, useRealtimeLineMetrics, useRegistry, useSKUs, useShiftConfig, useShifts, useSubscriptionManager, useSubscriptionManagerSafe, useSupabase, useSupabaseClient, useTargets, useTheme, useThemeConfig, useThreads, useVideoConfig, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, videoPreloader, whatsappService, withAuth, withRegistry, workspaceService };
|