@optifye/dashboard-core 6.0.4 → 6.0.5

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.js CHANGED
@@ -516,6 +516,76 @@ var getMetricsTablePrefix = (companyId) => {
516
516
  return "performance_metrics";
517
517
  };
518
518
 
519
+ // src/lib/utils/lineConfig.ts
520
+ function getConfiguredLineIds(entityConfig) {
521
+ if (entityConfig.lines && Object.keys(entityConfig.lines).length > 0) {
522
+ return Object.keys(entityConfig.lines);
523
+ }
524
+ const lineIds = [];
525
+ if (entityConfig.defaultLineId) {
526
+ lineIds.push(entityConfig.defaultLineId);
527
+ }
528
+ if (entityConfig.secondaryLineId && entityConfig.secondaryLineId !== entityConfig.defaultLineId) {
529
+ lineIds.push(entityConfig.secondaryLineId);
530
+ }
531
+ return lineIds;
532
+ }
533
+ function getLineDisplayName(entityConfig, lineId) {
534
+ if (entityConfig.lines && entityConfig.lines[lineId]) {
535
+ return entityConfig.lines[lineId];
536
+ }
537
+ if (entityConfig.lineNames && entityConfig.lineNames[lineId]) {
538
+ return entityConfig.lineNames[lineId];
539
+ }
540
+ return `Line ${lineId.substring(0, 8)}`;
541
+ }
542
+ function getAllLineDisplayNames(entityConfig) {
543
+ const displayNames = {};
544
+ if (entityConfig.lineNames) {
545
+ Object.assign(displayNames, entityConfig.lineNames);
546
+ }
547
+ if (entityConfig.lines) {
548
+ Object.assign(displayNames, entityConfig.lines);
549
+ }
550
+ return displayNames;
551
+ }
552
+ function getDefaultLineId(entityConfig) {
553
+ if (entityConfig.lines && Object.keys(entityConfig.lines).length > 0) {
554
+ return Object.keys(entityConfig.lines)[0];
555
+ }
556
+ return entityConfig.defaultLineId;
557
+ }
558
+ function isLegacyConfiguration(entityConfig) {
559
+ return !entityConfig.lines || Object.keys(entityConfig.lines).length === 0;
560
+ }
561
+ function migrateLegacyConfiguration(entityConfig) {
562
+ if (!isLegacyConfiguration(entityConfig)) {
563
+ return entityConfig;
564
+ }
565
+ const lines = {};
566
+ if (entityConfig.defaultLineId) {
567
+ lines[entityConfig.defaultLineId] = getLineDisplayName(entityConfig, entityConfig.defaultLineId);
568
+ }
569
+ if (entityConfig.secondaryLineId && entityConfig.secondaryLineId !== entityConfig.defaultLineId) {
570
+ lines[entityConfig.secondaryLineId] = getLineDisplayName(entityConfig, entityConfig.secondaryLineId);
571
+ }
572
+ if (entityConfig.lineNames) {
573
+ Object.entries(entityConfig.lineNames).forEach(([id3, name]) => {
574
+ if (!lines[id3]) {
575
+ lines[id3] = name;
576
+ }
577
+ });
578
+ }
579
+ return {
580
+ ...entityConfig,
581
+ lines
582
+ };
583
+ }
584
+ function isValidFactoryViewConfiguration(entityConfig) {
585
+ const lineIds = getConfiguredLineIds(entityConfig);
586
+ return lineIds.length > 0;
587
+ }
588
+
519
589
  // src/lib/services/dashboardService.ts
520
590
  var getTable2 = (dbConfig, tableName) => {
521
591
  const defaults2 = DEFAULT_DATABASE_CONFIG.tables;
@@ -537,15 +607,15 @@ var dashboardService = {
537
607
  const companyId = entityConfig.companyId;
538
608
  const metricsTablePrefixStr = getMetricsTablePrefix();
539
609
  const metricsTable = `${metricsTablePrefixStr}_${companyId ? companyId.replace(/-/g, "_") : "unknown_company"}`;
540
- const defaultLineId = entityConfig.defaultLineId;
541
- const secondaryLineId = entityConfig.secondaryLineId;
610
+ const configuredLineIds = getConfiguredLineIds(entityConfig);
611
+ const defaultLineId = configuredLineIds[0];
542
612
  const factoryViewId = entityConfig.factoryViewId ?? "factory";
543
613
  const defaultTimezone = dateTimeConfig.defaultTimezone;
544
614
  const { shiftId, date } = getCurrentShift(defaultTimezone, shiftConfig);
545
615
  const lineId = lineIdInput;
546
616
  if (lineId === factoryViewId) {
547
- if (!defaultLineId || !secondaryLineId || !companyId) {
548
- throw new Error("Factory View requires defaultLineId, secondaryLineId, and companyId to be configured.");
617
+ if (!isValidFactoryViewConfiguration(entityConfig) || !companyId) {
618
+ throw new Error("Factory View requires at least one configured line and companyId to be configured.");
549
619
  }
550
620
  const [lineResult, metricsResult, performanceResult] = await Promise.all([
551
621
  // Get Line 1's info for general factory details
@@ -557,10 +627,10 @@ var dashboardService = {
557
627
  company_id,
558
628
  companies!lines_company_id_fkey(company_name:name)
559
629
  `).eq("id", defaultLineId).maybeSingle(),
560
- // Get metrics from line_metrics table for both lines
561
- supabase.from(lineMetricsTable).select("*").in("line_id", [defaultLineId, secondaryLineId]).eq("shift_id", shiftId).eq("date", date),
562
- // Get performance data from the dynamic metrics table for both lines
563
- supabase.from(metricsTable).select("efficiency").in("line_id", [defaultLineId, secondaryLineId]).eq("shift_id", shiftId).eq("date", date)
630
+ // Get metrics from line_metrics table for all configured lines
631
+ supabase.from(lineMetricsTable).select("*").in("line_id", configuredLineIds).eq("shift_id", shiftId).eq("date", date),
632
+ // Get performance data from the dynamic metrics table for all configured lines
633
+ supabase.from(metricsTable).select("efficiency").in("line_id", configuredLineIds).eq("shift_id", shiftId).eq("date", date)
564
634
  ]);
565
635
  if (lineResult.error) throw lineResult.error;
566
636
  if (!lineResult.data) throw new Error(`Configured default line (${defaultLineId}) not found`);
@@ -707,8 +777,8 @@ var dashboardService = {
707
777
  }
708
778
  const metricsTablePrefixStr = getMetricsTablePrefix();
709
779
  const metricsTable = `${metricsTablePrefixStr}_${companyId.replace(/-/g, "_")}`;
710
- const defaultLineId = entityConfig.defaultLineId;
711
- const secondaryLineId = entityConfig.secondaryLineId;
780
+ const configuredLineIds = getConfiguredLineIds(entityConfig);
781
+ configuredLineIds[0];
712
782
  const factoryViewId = entityConfig.factoryViewId ?? "factory";
713
783
  const defaultTimezone = dateTimeConfig.defaultTimezone;
714
784
  const currentShiftResult = getCurrentShift(defaultTimezone, shiftConfig);
@@ -717,10 +787,10 @@ var dashboardService = {
717
787
  const lineId = lineIdInput;
718
788
  let query = supabase.from(metricsTable).select("company_id,line_id,shift_id,date,workspace_id,workspace_name,total_output,avg_pph,performance_score,avg_cycle_time,trend_score,ideal_output,efficiency,total_day_output").eq("shift_id", queryShiftId).eq("date", queryDate);
719
789
  if (!lineId || lineId === factoryViewId) {
720
- if (!defaultLineId || !secondaryLineId) {
721
- throw new Error("Factory View requires defaultLineId and secondaryLineId to be configured for workspace data.");
790
+ if (!isValidFactoryViewConfiguration(entityConfig)) {
791
+ throw new Error("Factory View requires at least one configured line for workspace data.");
722
792
  }
723
- query = query.in("line_id", [defaultLineId, secondaryLineId]);
793
+ query = query.in("line_id", configuredLineIds);
724
794
  } else {
725
795
  query = query.eq("line_id", lineId);
726
796
  }
@@ -945,8 +1015,8 @@ var dashboardService = {
945
1015
  const companyId = entityConfig.companyId;
946
1016
  const metricsTablePrefixStr = getMetricsTablePrefix();
947
1017
  const metricsTable = `${metricsTablePrefixStr}_${companyId ? companyId.replace(/-/g, "_") : "unknown_company"}`;
948
- const defaultLineId = entityConfig.defaultLineId;
949
- const secondaryLineId = entityConfig.secondaryLineId;
1018
+ const configuredLineIds = getConfiguredLineIds(entityConfig);
1019
+ const defaultLineId = configuredLineIds[0];
950
1020
  const factoryViewId = entityConfig.factoryViewId ?? "factory";
951
1021
  const defaultTimezone = dateTimeConfig.defaultTimezone;
952
1022
  const lineIdToQuery = lineIdInput || factoryViewId;
@@ -955,10 +1025,10 @@ var dashboardService = {
955
1025
  const queryShiftId = shiftProp !== void 0 ? shiftProp : currentShiftResult.shiftId;
956
1026
  try {
957
1027
  if (lineIdToQuery === factoryViewId) {
958
- if (!defaultLineId || !companyId) {
959
- throw new Error("Factory View requires at least defaultLineId and companyId to be configured.");
1028
+ if (!isValidFactoryViewConfiguration(entityConfig) || !companyId) {
1029
+ throw new Error("Factory View requires at least one configured line and companyId to be configured.");
960
1030
  }
961
- const lineIdsToQuery = [defaultLineId, secondaryLineId].filter((id3) => id3 !== void 0 && id3 !== null);
1031
+ const lineIdsToQuery = configuredLineIds;
962
1032
  const [line1Result, metricsResult2, performanceResult2] = await Promise.all([
963
1033
  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(),
964
1034
  supabase.from(lineMetricsTable).select("*").in("line_id", lineIdsToQuery).eq("shift_id", queryShiftId).eq("date", queryDate),
@@ -1129,8 +1199,7 @@ var dashboardService = {
1129
1199
  const dbConfig = config.databaseConfig ?? DEFAULT_DATABASE_CONFIG;
1130
1200
  const entityConfig = config.entityConfig ?? DEFAULT_ENTITY_CONFIG;
1131
1201
  const lineMetricsTable = getTable2(dbConfig, "lineMetrics");
1132
- const defaultLineId = entityConfig.defaultLineId;
1133
- const secondaryLineId = entityConfig.secondaryLineId;
1202
+ const configuredLineIds = getConfiguredLineIds(entityConfig);
1134
1203
  const factoryViewId = entityConfig.factoryViewId ?? "factory";
1135
1204
  const startDate = new Date(year, month, 1);
1136
1205
  const endDate = new Date(year, month + 1, 0);
@@ -1139,10 +1208,10 @@ var dashboardService = {
1139
1208
  const formattedEndDate = formatDate(endDate);
1140
1209
  let query = supabase.from(lineMetricsTable).select("date, shift_id, avg_efficiency, underperforming_workspaces, total_workspaces").gte("date", formattedStartDate).lte("date", formattedEndDate);
1141
1210
  if (lineIdInput === factoryViewId) {
1142
- if (!defaultLineId || !secondaryLineId) {
1143
- throw new Error("Factory View requires defaultLineId and secondaryLineId for monthly data.");
1211
+ if (!isValidFactoryViewConfiguration(entityConfig)) {
1212
+ throw new Error("Factory View requires at least one configured line for monthly data.");
1144
1213
  }
1145
- query = query.in("line_id", [defaultLineId, secondaryLineId]);
1214
+ query = query.in("line_id", configuredLineIds);
1146
1215
  } else {
1147
1216
  query = query.eq("line_id", lineIdInput);
1148
1217
  }
@@ -1173,8 +1242,7 @@ var dashboardService = {
1173
1242
  const companyId = entityConfig.companyId;
1174
1243
  const metricsTablePrefixStr = getMetricsTablePrefix();
1175
1244
  const metricsTable = `${metricsTablePrefixStr}_${companyId ? companyId.replace(/-/g, "_") : "unknown_company"}`;
1176
- const defaultLineId = entityConfig.defaultLineId;
1177
- const secondaryLineId = entityConfig.secondaryLineId;
1245
+ const configuredLineIds = getConfiguredLineIds(entityConfig);
1178
1246
  const factoryViewId = entityConfig.factoryViewId ?? "factory";
1179
1247
  const worstPerformingEndpoint = endpointsConfig?.worstPerformingWorkspaces;
1180
1248
  if (!worstPerformingEndpoint) throw new Error("worstPerformingWorkspaces endpoint must be configured.");
@@ -1186,7 +1254,7 @@ var dashboardService = {
1186
1254
  const currentMonth = monthInput !== void 0 ? monthInput : currentDate.getMonth();
1187
1255
  const currentYear = yearInput !== void 0 ? yearInput : currentDate.getFullYear();
1188
1256
  const bodyPayload = {
1189
- lineId: lineIdInput === factoryViewId ? [defaultLineId, secondaryLineId] : lineIdInput,
1257
+ lineId: lineIdInput === factoryViewId ? configuredLineIds : lineIdInput,
1190
1258
  month: currentMonth,
1191
1259
  year: currentYear,
1192
1260
  companyId,
@@ -3849,11 +3917,11 @@ var useLineDetailedMetrics = (lineIdFromProp) => {
3849
3917
  let targetLineIdsForSubscription = [];
3850
3918
  const factoryViewIdentifier = entityConfig.factoryViewId || "factory";
3851
3919
  if (lineIdToUse === factoryViewIdentifier) {
3852
- if (entityConfig.defaultLineId && entityConfig.secondaryLineId) {
3853
- targetLineIdsForSubscription = [entityConfig.defaultLineId, entityConfig.secondaryLineId];
3920
+ if (isValidFactoryViewConfiguration(entityConfig)) {
3921
+ targetLineIdsForSubscription = getConfiguredLineIds(entityConfig);
3854
3922
  filterString += `,line_id=in.(${targetLineIdsForSubscription.join(",")})`;
3855
3923
  } else {
3856
- console.warn("[useLineDetailedMetrics] Factory view selected but defaultLineId/secondaryLineId not in entityConfig. Realtime updates may be incomplete.");
3924
+ console.warn("[useLineDetailedMetrics] Factory view selected but no lines configured in entityConfig. Realtime updates may be incomplete.");
3857
3925
  return;
3858
3926
  }
3859
3927
  } else {
@@ -4071,9 +4139,9 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId }) => {
4071
4139
  try {
4072
4140
  const currentShiftDetails = getCurrentShift(defaultTimezone, shiftConfig);
4073
4141
  const operationalDate = getOperationalDate(defaultTimezone);
4074
- const targetLineIds = currentLineIdToUse === (entityConfig.factoryViewId || "factory") ? [entityConfig.defaultLineId, entityConfig.secondaryLineId].filter((id3) => !!id3) : [currentLineIdToUse];
4142
+ const targetLineIds = currentLineIdToUse === (entityConfig.factoryViewId || "factory") ? getConfiguredLineIds(entityConfig) : [currentLineIdToUse];
4075
4143
  if (targetLineIds.length === 0 && currentLineIdToUse === (entityConfig.factoryViewId || "factory")) {
4076
- throw new Error("Factory view selected, but defaultLineId and/or secondaryLineId are not configured in entityConfig.");
4144
+ throw new Error("Factory view selected, but no lines are configured in entityConfig.");
4077
4145
  }
4078
4146
  if (targetLineIds.length === 0) {
4079
4147
  throw new Error("No target line IDs available for fetching metrics.");
@@ -4173,7 +4241,7 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId }) => {
4173
4241
  }
4174
4242
  const currentShiftDetails = getCurrentShift(defaultTimezone, shiftConfig);
4175
4243
  const operationalDateForSubscription = getOperationalDate(defaultTimezone);
4176
- const targetLineIds = currentLineIdToUse === (entityConfig.factoryViewId || "factory") ? [entityConfig.defaultLineId, entityConfig.secondaryLineId].filter((id3) => !!id3) : [currentLineIdToUse];
4244
+ const targetLineIds = currentLineIdToUse === (entityConfig.factoryViewId || "factory") ? getConfiguredLineIds(entityConfig) : [currentLineIdToUse];
4177
4245
  if (targetLineIds.length === 0) return;
4178
4246
  const wsMetricsFilter = `date=eq.${operationalDateForSubscription}&shift_id=eq.${currentShiftDetails.shiftId}&line_id=in.(${targetLineIds.join(",")})`;
4179
4247
  const lineMetricsFilter = `date=eq.${operationalDateForSubscription}&shift_id=eq.${currentShiftDetails.shiftId}&line_id=in.(${targetLineIds.join(",")})`;
@@ -4342,11 +4410,8 @@ var useLineKPIs = ({ lineId }) => {
4342
4410
  const currentShiftDetails = getCurrentShift(defaultTimezone, shiftConfig);
4343
4411
  const operationalDate = currentShiftDetails.date;
4344
4412
  const factoryViewIdentifier = entityConfig.factoryViewId || "factory";
4345
- const targetLineIds = currentLineId === factoryViewIdentifier ? [entityConfig.defaultLineId, entityConfig.secondaryLineId].filter((id3) => !!id3) : [currentLineId];
4346
- if (targetLineIds.length === 0 && currentLineId === factoryViewIdentifier) {
4347
- console.warn("[useLineKPIs] Factory view: defaultLineId/secondaryLineId not in entityConfig. Cannot subscribe effectively.");
4348
- return;
4349
- } else if (targetLineIds.length === 0) {
4413
+ const targetLineIds = currentLineId === factoryViewIdentifier ? getConfiguredLineIds(entityConfig) : [currentLineId];
4414
+ if (targetLineIds.length === 0) {
4350
4415
  console.warn("[useLineKPIs] No target line IDs for subscription. LineId:", currentLineId);
4351
4416
  return;
4352
4417
  }
@@ -4446,10 +4511,8 @@ var useRealtimeLineMetrics = ({
4446
4511
  currentTime: (/* @__PURE__ */ new Date()).toLocaleString("en-US", { timeZone: dateTimeConfig.defaultTimezone || "Asia/Kolkata" })
4447
4512
  });
4448
4513
  const factoryViewId = entityConfig.factoryViewId || "factory";
4449
- const defaultLineId = entityConfig.defaultLineId;
4450
- const secondaryLineId = entityConfig.secondaryLineId;
4451
4514
  if (lineIdRef.current === factoryViewId) {
4452
- const targetLineIds = [defaultLineId, secondaryLineId].filter(Boolean);
4515
+ const targetLineIds = getConfiguredLineIds(entityConfig);
4453
4516
  if (targetLineIds.length === 0) {
4454
4517
  throw new Error("No configured line IDs for factory view");
4455
4518
  }
@@ -4663,9 +4726,7 @@ var useRealtimeLineMetrics = ({
4663
4726
  console.log("Setting up line metrics subscriptions for:", lineIdRef.current);
4664
4727
  }
4665
4728
  const factoryViewId = entityConfig.factoryViewId || "factory";
4666
- const defaultLineId = entityConfig.defaultLineId;
4667
- const secondaryLineId = entityConfig.secondaryLineId;
4668
- const targetLineIds = lineIdRef.current === factoryViewId ? [defaultLineId, secondaryLineId].filter(Boolean) : [lineIdRef.current];
4729
+ const targetLineIds = lineIdRef.current === factoryViewId ? getConfiguredLineIds(entityConfig) : [lineIdRef.current];
4669
4730
  if (targetLineIds.length === 0) {
4670
4731
  return;
4671
4732
  }
@@ -27428,20 +27489,33 @@ var DEFAULT_SHIFT_CONFIG2 = {
27428
27489
  var FactoryView = ({
27429
27490
  line1Id,
27430
27491
  line2Id,
27492
+ lineIds,
27493
+ lineNames = {},
27431
27494
  factoryName = "Plant 1",
27432
27495
  timezone = DEFAULT_TIMEZONE,
27433
27496
  shiftConfig = DEFAULT_SHIFT_CONFIG2,
27434
27497
  productIds = {}
27435
27498
  }) => {
27499
+ const effectiveLineIds = React19.useMemo(() => {
27500
+ if (lineIds && lineIds.length > 0) {
27501
+ return lineIds;
27502
+ }
27503
+ const ids = [];
27504
+ if (line1Id) ids.push(line1Id);
27505
+ if (line2Id && line2Id !== line1Id) ids.push(line2Id);
27506
+ return ids;
27507
+ }, [lineIds, line1Id, line2Id]);
27436
27508
  const router$1 = router.useRouter();
27437
27509
  const supabase = useSupabase();
27438
- const line1DataHook = useLineDetailedMetrics(line1Id);
27439
- const line2DataHook = useLineDetailedMetrics(line2Id);
27510
+ const lineDataHooks = effectiveLineIds.map((lineId) => ({
27511
+ lineId,
27512
+ hook: useLineDetailedMetrics(lineId)
27513
+ }));
27440
27514
  const [lines, setLines] = React19.useState([]);
27441
27515
  const [loading, setLoading] = React19.useState(true);
27442
27516
  const [error, setError] = React19.useState(null);
27443
27517
  React19.useMemo(() => {
27444
- const processLineData = (hookData, defaultName) => {
27518
+ const processLineData = (hookData, lineId) => {
27445
27519
  const currentLineInfo = hookData.lineData;
27446
27520
  let last5HoursData = [];
27447
27521
  if (currentLineInfo && currentLineInfo.metrics && currentLineInfo.metrics.output_array && currentLineInfo.metrics.output_array.length > 0) {
@@ -27462,6 +27536,7 @@ var FactoryView = ({
27462
27536
  }
27463
27537
  }
27464
27538
  }
27539
+ const defaultName = lineNames[lineId] || `Line ${lineId.substring(0, 8)}`;
27465
27540
  return {
27466
27541
  name: currentLineInfo?.line_name || defaultName,
27467
27542
  metrics: currentLineInfo,
@@ -27470,11 +27545,8 @@ var FactoryView = ({
27470
27545
  last5Hours: last5HoursData.slice(-5)
27471
27546
  };
27472
27547
  };
27473
- return [
27474
- processLineData(line1DataHook, "Line 1"),
27475
- processLineData(line2DataHook, "Line 2")
27476
- ];
27477
- }, [line1DataHook, line2DataHook]);
27548
+ return lineDataHooks.map(({ lineId, hook }) => processLineData(hook, lineId));
27549
+ }, [lineDataHooks, lineNames]);
27478
27550
  React19.useEffect(() => {
27479
27551
  const fetchHourlyData = async () => {
27480
27552
  try {
@@ -27485,45 +27557,37 @@ var FactoryView = ({
27485
27557
  }
27486
27558
  const { shiftId } = getCurrentShift(timezone, shiftConfig);
27487
27559
  const date = getOperationalDate();
27488
- const { data: hourlyDataLine1, error: errorL1 } = await supabase.from("line_hourly_metrics").select("hour, efficiency").eq("line_id", line1Id).eq("shift_id", shiftId).eq("date", date).order("hour", { ascending: false }).limit(5);
27489
- if (errorL1) throw errorL1;
27490
- const { data: hourlyDataLine2, error: errorL2 } = await supabase.from("line_hourly_metrics").select("hour, efficiency").eq("line_id", line2Id).eq("shift_id", shiftId).eq("date", date).order("hour", { ascending: false }).limit(5);
27491
- if (errorL2) throw errorL2;
27492
- const linesData = [];
27493
- if (line1DataHook.lineData && line1DataHook.lineData.metrics && line1DataHook.lineData.metrics.output_array) {
27494
- linesData.push({
27495
- details: {
27496
- id: line1Id,
27497
- line_name: line1DataHook.lineData.line_name || "Line 1",
27498
- factory_id: line1DataHook.lineData.factory_id || "",
27499
- factory_name: line1DataHook.lineData.factory_name || "Factory 1"
27500
- },
27501
- current_output: line1DataHook.lineData.metrics.current_output || 0,
27502
- ideal_output: line1DataHook.lineData.metrics.ideal_output || 0,
27503
- avg_efficiency: line1DataHook.lineData.metrics.avg_efficiency || 0,
27504
- total_workspaces: line1DataHook.lineData.metrics.total_workspaces || 0,
27505
- underperforming_workspaces: line1DataHook.lineData.metrics.underperforming_workspaces || 0,
27506
- last5Hours: (hourlyDataLine1 || []).map((h) => ({ hour: h.hour, efficiency: h.efficiency })).reverse(),
27507
- productId: productIds[line1Id] || "Product A"
27508
- });
27509
- }
27510
- if (line2DataHook.lineData && line2DataHook.lineData.metrics && line2DataHook.lineData.metrics.output_array) {
27511
- linesData.push({
27512
- details: {
27513
- id: line2Id,
27514
- line_name: line2DataHook.lineData.line_name || "Line 2",
27515
- factory_id: line2DataHook.lineData.factory_id || "",
27516
- factory_name: line2DataHook.lineData.factory_name || "Factory 2"
27517
- },
27518
- current_output: line2DataHook.lineData.metrics.current_output || 0,
27519
- ideal_output: line2DataHook.lineData.metrics.ideal_output || 0,
27520
- avg_efficiency: line2DataHook.lineData.metrics.avg_efficiency || 0,
27521
- total_workspaces: line2DataHook.lineData.metrics.total_workspaces || 0,
27522
- underperforming_workspaces: line2DataHook.lineData.metrics.underperforming_workspaces || 0,
27523
- last5Hours: (hourlyDataLine2 || []).map((h) => ({ hour: h.hour, efficiency: h.efficiency })).reverse(),
27524
- productId: productIds[line2Id] || "Product B"
27525
- });
27560
+ const hourlyDataPromises = effectiveLineIds.map(
27561
+ (lineId) => supabase.from("line_hourly_metrics").select("hour, efficiency").eq("line_id", lineId).eq("shift_id", shiftId).eq("date", date).order("hour", { ascending: false }).limit(5)
27562
+ );
27563
+ const hourlyDataResults = await Promise.all(hourlyDataPromises);
27564
+ for (let i = 0; i < hourlyDataResults.length; i++) {
27565
+ if (hourlyDataResults[i].error) {
27566
+ throw hourlyDataResults[i].error;
27567
+ }
27526
27568
  }
27569
+ const linesData = [];
27570
+ lineDataHooks.forEach(({ lineId, hook }, index) => {
27571
+ const lineData = hook.lineData;
27572
+ const hourlyData = hourlyDataResults[index].data;
27573
+ if (lineData && lineData.metrics && lineData.metrics.output_array) {
27574
+ linesData.push({
27575
+ details: {
27576
+ id: lineId,
27577
+ line_name: lineData.line_name || lineNames[lineId] || `Line ${index + 1}`,
27578
+ factory_id: lineData.factory_id || "",
27579
+ factory_name: lineData.factory_name || factoryName
27580
+ },
27581
+ current_output: lineData.metrics.current_output || 0,
27582
+ ideal_output: lineData.metrics.ideal_output || 0,
27583
+ avg_efficiency: lineData.metrics.avg_efficiency || 0,
27584
+ total_workspaces: lineData.metrics.total_workspaces || 0,
27585
+ underperforming_workspaces: lineData.metrics.underperforming_workspaces || 0,
27586
+ last5Hours: (hourlyData || []).map((h) => ({ hour: h.hour, efficiency: h.efficiency })).reverse(),
27587
+ productId: productIds[lineId] || `Product ${String.fromCharCode(65 + index)}`
27588
+ });
27589
+ }
27590
+ });
27527
27591
  setLines(linesData);
27528
27592
  setLoading(false);
27529
27593
  } catch (err) {
@@ -27532,10 +27596,11 @@ var FactoryView = ({
27532
27596
  setLoading(false);
27533
27597
  }
27534
27598
  };
27535
- if (!line1DataHook.loading && !line2DataHook.loading) {
27599
+ const allHooksLoaded = lineDataHooks.every(({ hook }) => !hook.loading);
27600
+ if (allHooksLoaded) {
27536
27601
  fetchHourlyData();
27537
27602
  }
27538
- }, [supabase, line1DataHook, line2DataHook, line1Id, line2Id, timezone, shiftConfig, productIds]);
27603
+ }, [supabase, lineDataHooks, effectiveLineIds, lineNames, factoryName, timezone, shiftConfig, productIds]);
27539
27604
  const getShiftName = () => {
27540
27605
  const now2 = /* @__PURE__ */ new Date();
27541
27606
  const currentHour = now2.getHours();
@@ -27549,7 +27614,7 @@ var FactoryView = ({
27549
27614
  return /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z" }) });
27550
27615
  }
27551
27616
  };
27552
- if (loading || line1DataHook.loading || line2DataHook.loading) {
27617
+ if (loading || lineDataHooks.some((hookData) => hookData.hook.loading)) {
27553
27618
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "animate-pulse space-y-4", children: [
27554
27619
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-12 bg-gray-200 rounded" }),
27555
27620
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-12 bg-gray-200 rounded" })
@@ -28299,6 +28364,7 @@ var HelpView = ({
28299
28364
  var AuthenticatedHelpView = withAuth(HelpView);
28300
28365
  var HelpView_default = HelpView;
28301
28366
  var KPISection2 = KPISection;
28367
+ var LoadingPageCmp = LoadingPage_default;
28302
28368
  function HomeView({
28303
28369
  defaultLineId,
28304
28370
  factoryViewId,
@@ -28438,53 +28504,7 @@ function HomeView({
28438
28504
  const isInitialLoading = !isHydrated || !displayNamesInitialized && displayNamesLoading;
28439
28505
  const isDataLoading = metricsLoading || kpisLoading;
28440
28506
  if (isInitialLoading) {
28441
- return /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsx(
28442
- motion.div,
28443
- {
28444
- className: "text-center",
28445
- initial: { opacity: 0, scale: 0.9 },
28446
- animate: { opacity: 1, scale: 1 },
28447
- transition: { duration: 0.5 },
28448
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-white rounded-2xl shadow-2xl p-12 max-w-md mx-auto", children: [
28449
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative mb-8", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-24 h-24 mx-auto", children: [
28450
- /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "animate-spin", viewBox: "0 0 100 100", xmlns: "http://www.w3.org/2000/svg", children: [
28451
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "50", cy: "50", r: "45", fill: "none", stroke: "#e5e7eb", strokeWidth: "8" }),
28452
- /* @__PURE__ */ jsxRuntime.jsx(
28453
- "circle",
28454
- {
28455
- cx: "50",
28456
- cy: "50",
28457
- r: "45",
28458
- fill: "none",
28459
- stroke: "#3b82f6",
28460
- strokeWidth: "8",
28461
- strokeDasharray: "150 283",
28462
- strokeLinecap: "round",
28463
- className: "transform -rotate-90 origin-center"
28464
- }
28465
- )
28466
- ] }),
28467
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-16 h-16 bg-gradient-to-br from-blue-500 to-blue-600 rounded-full animate-pulse" }) })
28468
- ] }) }),
28469
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl font-bold text-gray-800 mb-2", children: "Loading Dashboard" }),
28470
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-gray-600 mb-6", children: "Initializing your workspace..." }),
28471
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
28472
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center space-x-2 text-sm text-gray-500", children: [
28473
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-2 h-2 bg-blue-500 rounded-full animate-pulse" }),
28474
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Connecting to services" })
28475
- ] }),
28476
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center space-x-2 text-sm text-gray-500", children: [
28477
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-2 h-2 bg-blue-500 rounded-full animate-pulse", style: { animationDelay: "0.2s" } }),
28478
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Loading workspace configurations" })
28479
- ] }),
28480
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center space-x-2 text-sm text-gray-500", children: [
28481
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-2 h-2 bg-blue-500 rounded-full animate-pulse", style: { animationDelay: "0.4s" } }),
28482
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Preparing dashboard view" })
28483
- ] })
28484
- ] })
28485
- ] })
28486
- }
28487
- ) });
28507
+ return /* @__PURE__ */ jsxRuntime.jsx(LoadingPageCmp, { message: "Loading Dashboard..." });
28488
28508
  }
28489
28509
  if (errorMessage || displayNamesError) {
28490
28510
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-screen items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg bg-white p-6 shadow-lg", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-3 text-red-500", children: [
@@ -34117,6 +34137,7 @@ exports.formatISTDate = formatISTDate;
34117
34137
  exports.formatIdleTime = formatIdleTime;
34118
34138
  exports.formatTimeInZone = formatTimeInZone;
34119
34139
  exports.fromUrlFriendlyName = fromUrlFriendlyName;
34140
+ exports.getAllLineDisplayNames = getAllLineDisplayNames;
34120
34141
  exports.getAllThreadMessages = getAllThreadMessages;
34121
34142
  exports.getAllWorkspaceDisplayNamesAsync = getAllWorkspaceDisplayNamesAsync;
34122
34143
  exports.getAnonClient = getAnonClient;
@@ -34124,12 +34145,15 @@ exports.getCameraNumber = getCameraNumber;
34124
34145
  exports.getCompanyMetricsTableName = getCompanyMetricsTableName;
34125
34146
  exports.getConfigurableShortWorkspaceDisplayName = getConfigurableShortWorkspaceDisplayName;
34126
34147
  exports.getConfigurableWorkspaceDisplayName = getConfigurableWorkspaceDisplayName;
34148
+ exports.getConfiguredLineIds = getConfiguredLineIds;
34127
34149
  exports.getCurrentShift = getCurrentShift;
34128
34150
  exports.getCurrentTimeInZone = getCurrentTimeInZone;
34129
34151
  exports.getDashboardHeaderTimeInZone = getDashboardHeaderTimeInZone;
34130
34152
  exports.getDaysDifferenceInZone = getDaysDifferenceInZone;
34131
34153
  exports.getDefaultCameraStreamUrl = getDefaultCameraStreamUrl;
34154
+ exports.getDefaultLineId = getDefaultLineId;
34132
34155
  exports.getDefaultTabForWorkspace = getDefaultTabForWorkspace;
34156
+ exports.getLineDisplayName = getLineDisplayName;
34133
34157
  exports.getManufacturingInsights = getManufacturingInsights;
34134
34158
  exports.getMetricsTablePrefix = getMetricsTablePrefix;
34135
34159
  exports.getOperationalDate = getOperationalDate;
@@ -34149,13 +34173,16 @@ exports.getWorkspaceFromUrl = getWorkspaceFromUrl;
34149
34173
  exports.getWorkspaceNavigationParams = getWorkspaceNavigationParams;
34150
34174
  exports.identifyCoreUser = identifyCoreUser;
34151
34175
  exports.initializeCoreMixpanel = initializeCoreMixpanel;
34176
+ exports.isLegacyConfiguration = isLegacyConfiguration;
34152
34177
  exports.isTransitionPeriod = isTransitionPeriod;
34178
+ exports.isValidFactoryViewConfiguration = isValidFactoryViewConfiguration;
34153
34179
  exports.isValidLineInfoPayload = isValidLineInfoPayload;
34154
34180
  exports.isValidWorkspaceDetailedMetricsPayload = isValidWorkspaceDetailedMetricsPayload;
34155
34181
  exports.isValidWorkspaceMetricsPayload = isValidWorkspaceMetricsPayload;
34156
34182
  exports.isWorkspaceDisplayNamesLoaded = isWorkspaceDisplayNamesLoaded;
34157
34183
  exports.isWorkspaceDisplayNamesLoading = isWorkspaceDisplayNamesLoading;
34158
34184
  exports.mergeWithDefaultConfig = mergeWithDefaultConfig;
34185
+ exports.migrateLegacyConfiguration = migrateLegacyConfiguration;
34159
34186
  exports.optifyeAgentClient = optifyeAgentClient;
34160
34187
  exports.preInitializeWorkspaceDisplayNames = preInitializeWorkspaceDisplayNames;
34161
34188
  exports.preloadS3Video = preloadS3Video;