@optifye/dashboard-core 6.0.4 → 6.0.6
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 +0 -22
- package/dist/index.d.mts +125 -11
- package/dist/index.d.ts +125 -11
- package/dist/index.js +332 -147
- package/dist/index.mjs +322 -148
- package/package.json +1 -1
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
|
|
541
|
-
const
|
|
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 (!
|
|
548
|
-
throw new Error("Factory View requires
|
|
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
|
|
561
|
-
supabase.from(lineMetricsTable).select("*").in("line_id",
|
|
562
|
-
// Get performance data from the dynamic metrics table for
|
|
563
|
-
supabase.from(metricsTable).select("efficiency").in("line_id",
|
|
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
|
|
711
|
-
|
|
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 (!
|
|
721
|
-
throw new Error("Factory View requires
|
|
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",
|
|
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
|
|
949
|
-
const
|
|
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 (!
|
|
959
|
-
throw new Error("Factory View requires at least
|
|
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 =
|
|
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
|
|
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 (!
|
|
1143
|
-
throw new Error("Factory View requires
|
|
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",
|
|
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
|
|
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 ?
|
|
1257
|
+
lineId: lineIdInput === factoryViewId ? configuredLineIds : lineIdInput,
|
|
1190
1258
|
month: currentMonth,
|
|
1191
1259
|
year: currentYear,
|
|
1192
1260
|
companyId,
|
|
@@ -2039,7 +2107,7 @@ var authRateLimitService = {
|
|
|
2039
2107
|
};
|
|
2040
2108
|
var isMixpanelInitialized = false;
|
|
2041
2109
|
var currentUserProperties;
|
|
2042
|
-
var initializeCoreMixpanel = (token,
|
|
2110
|
+
var initializeCoreMixpanel = (token, debugOrOptions, trackPageViewArg) => {
|
|
2043
2111
|
if (!token) {
|
|
2044
2112
|
console.warn("Mixpanel token not provided for initialization. Mixpanel will not be enabled.");
|
|
2045
2113
|
return;
|
|
@@ -2048,15 +2116,51 @@ var initializeCoreMixpanel = (token, debug, trackPageView) => {
|
|
|
2048
2116
|
console.warn("Mixpanel already initialized. Ignoring subsequent initialization.");
|
|
2049
2117
|
return;
|
|
2050
2118
|
}
|
|
2051
|
-
|
|
2119
|
+
let debug;
|
|
2120
|
+
let trackPageView;
|
|
2121
|
+
let sessionOpts = {};
|
|
2122
|
+
if (typeof debugOrOptions === "boolean" || debugOrOptions === void 0) {
|
|
2123
|
+
debug = debugOrOptions;
|
|
2124
|
+
trackPageView = trackPageViewArg;
|
|
2125
|
+
} else {
|
|
2126
|
+
const opts = debugOrOptions;
|
|
2127
|
+
({ debug, trackPageView, ...sessionOpts } = opts);
|
|
2128
|
+
}
|
|
2129
|
+
const initOptions = {
|
|
2052
2130
|
debug: debug ?? process.env.NODE_ENV === "development",
|
|
2053
|
-
// Keep env var as fallback if not explicitly passed
|
|
2054
2131
|
track_pageview: trackPageView ?? true,
|
|
2055
|
-
// Default to true if not specified in config
|
|
2056
2132
|
persistence: "localStorage"
|
|
2133
|
+
};
|
|
2134
|
+
if (sessionOpts.recordSessionsPercent !== void 0) {
|
|
2135
|
+
initOptions.record_sessions_percent = sessionOpts.recordSessionsPercent;
|
|
2136
|
+
} else {
|
|
2137
|
+
initOptions.record_sessions_percent = 1;
|
|
2138
|
+
}
|
|
2139
|
+
if (sessionOpts.recordIdleTimeoutMs !== void 0) {
|
|
2140
|
+
initOptions.record_idle_timeout_ms = sessionOpts.recordIdleTimeoutMs;
|
|
2141
|
+
}
|
|
2142
|
+
if (sessionOpts.recordHeatmapData !== void 0) {
|
|
2143
|
+
initOptions.record_heatmap_data = sessionOpts.recordHeatmapData;
|
|
2144
|
+
} else {
|
|
2145
|
+
initOptions.record_heatmap_data = true;
|
|
2146
|
+
}
|
|
2147
|
+
if (sessionOpts.recordCanvas !== void 0) {
|
|
2148
|
+
initOptions.record_canvas = sessionOpts.recordCanvas;
|
|
2149
|
+
}
|
|
2150
|
+
if (sessionOpts.recordBlockSelector !== void 0) {
|
|
2151
|
+
initOptions.record_block_selector = sessionOpts.recordBlockSelector;
|
|
2152
|
+
}
|
|
2153
|
+
if (sessionOpts.recordMaskTextSelector !== void 0) {
|
|
2154
|
+
initOptions.record_mask_text_selector = sessionOpts.recordMaskTextSelector;
|
|
2155
|
+
}
|
|
2156
|
+
Object.keys(sessionOpts).forEach((key) => {
|
|
2157
|
+
if (!(key in initOptions)) {
|
|
2158
|
+
initOptions[key] = sessionOpts[key];
|
|
2159
|
+
}
|
|
2057
2160
|
});
|
|
2161
|
+
mixpanel__default.default.init(token, initOptions);
|
|
2058
2162
|
isMixpanelInitialized = true;
|
|
2059
|
-
console.log("Mixpanel initialized in dashboard-core.");
|
|
2163
|
+
console.log("Mixpanel initialized in dashboard-core with Session Replay support.");
|
|
2060
2164
|
};
|
|
2061
2165
|
var trackCorePageView = (pageName, properties) => {
|
|
2062
2166
|
if (!isMixpanelInitialized) return;
|
|
@@ -2072,6 +2176,46 @@ var trackCoreEvent = (eventName, properties) => {
|
|
|
2072
2176
|
};
|
|
2073
2177
|
mixpanel__default.default.track(eventName, mergedProps);
|
|
2074
2178
|
};
|
|
2179
|
+
var startCoreSessionRecording = () => {
|
|
2180
|
+
try {
|
|
2181
|
+
if (!isMixpanelInitialized) return;
|
|
2182
|
+
if (typeof mixpanel__default.default.start_session_recording === "function") {
|
|
2183
|
+
mixpanel__default.default.start_session_recording();
|
|
2184
|
+
}
|
|
2185
|
+
} catch (err) {
|
|
2186
|
+
console.error("[Mixpanel] Unable to start session recording:", err);
|
|
2187
|
+
}
|
|
2188
|
+
};
|
|
2189
|
+
var stopCoreSessionRecording = () => {
|
|
2190
|
+
try {
|
|
2191
|
+
if (!isMixpanelInitialized) return;
|
|
2192
|
+
if (typeof mixpanel__default.default.stop_session_recording === "function") {
|
|
2193
|
+
mixpanel__default.default.stop_session_recording();
|
|
2194
|
+
}
|
|
2195
|
+
} catch (err) {
|
|
2196
|
+
console.error("[Mixpanel] Unable to stop session recording:", err);
|
|
2197
|
+
}
|
|
2198
|
+
};
|
|
2199
|
+
var getCoreSessionRecordingProperties = () => {
|
|
2200
|
+
try {
|
|
2201
|
+
if (!isMixpanelInitialized) return {};
|
|
2202
|
+
if (typeof mixpanel__default.default.get_session_recording_properties === "function") {
|
|
2203
|
+
return mixpanel__default.default.get_session_recording_properties() || {};
|
|
2204
|
+
}
|
|
2205
|
+
} catch {
|
|
2206
|
+
}
|
|
2207
|
+
return {};
|
|
2208
|
+
};
|
|
2209
|
+
var getCoreSessionReplayUrl = () => {
|
|
2210
|
+
try {
|
|
2211
|
+
if (!isMixpanelInitialized) return null;
|
|
2212
|
+
if (typeof mixpanel__default.default.get_session_replay_url === "function") {
|
|
2213
|
+
return mixpanel__default.default.get_session_replay_url();
|
|
2214
|
+
}
|
|
2215
|
+
} catch {
|
|
2216
|
+
}
|
|
2217
|
+
return null;
|
|
2218
|
+
};
|
|
2075
2219
|
var identifyCoreUser = (userId, userProperties) => {
|
|
2076
2220
|
if (!isMixpanelInitialized) return;
|
|
2077
2221
|
mixpanel__default.default.identify(userId);
|
|
@@ -2123,8 +2267,9 @@ var SSEChatClient = class {
|
|
|
2123
2267
|
thread_id: threadId,
|
|
2124
2268
|
user_id: userId,
|
|
2125
2269
|
company_id: context.companyId,
|
|
2126
|
-
|
|
2127
|
-
|
|
2270
|
+
shift_id: context.shiftId,
|
|
2271
|
+
// Send all_lines if available, otherwise fall back to single line_id
|
|
2272
|
+
...context.allLines && context.allLines.length > 0 ? { all_lines: context.allLines } : { line_id: context.lineId }
|
|
2128
2273
|
}),
|
|
2129
2274
|
signal: controller.signal,
|
|
2130
2275
|
// Don't include credentials since the API returns Access-Control-Allow-Origin: *
|
|
@@ -3849,11 +3994,11 @@ var useLineDetailedMetrics = (lineIdFromProp) => {
|
|
|
3849
3994
|
let targetLineIdsForSubscription = [];
|
|
3850
3995
|
const factoryViewIdentifier = entityConfig.factoryViewId || "factory";
|
|
3851
3996
|
if (lineIdToUse === factoryViewIdentifier) {
|
|
3852
|
-
if (entityConfig
|
|
3853
|
-
targetLineIdsForSubscription =
|
|
3997
|
+
if (isValidFactoryViewConfiguration(entityConfig)) {
|
|
3998
|
+
targetLineIdsForSubscription = getConfiguredLineIds(entityConfig);
|
|
3854
3999
|
filterString += `,line_id=in.(${targetLineIdsForSubscription.join(",")})`;
|
|
3855
4000
|
} else {
|
|
3856
|
-
console.warn("[useLineDetailedMetrics] Factory view selected but
|
|
4001
|
+
console.warn("[useLineDetailedMetrics] Factory view selected but no lines configured in entityConfig. Realtime updates may be incomplete.");
|
|
3857
4002
|
return;
|
|
3858
4003
|
}
|
|
3859
4004
|
} else {
|
|
@@ -4071,9 +4216,9 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId }) => {
|
|
|
4071
4216
|
try {
|
|
4072
4217
|
const currentShiftDetails = getCurrentShift(defaultTimezone, shiftConfig);
|
|
4073
4218
|
const operationalDate = getOperationalDate(defaultTimezone);
|
|
4074
|
-
const targetLineIds = currentLineIdToUse === (entityConfig.factoryViewId || "factory") ?
|
|
4219
|
+
const targetLineIds = currentLineIdToUse === (entityConfig.factoryViewId || "factory") ? getConfiguredLineIds(entityConfig) : [currentLineIdToUse];
|
|
4075
4220
|
if (targetLineIds.length === 0 && currentLineIdToUse === (entityConfig.factoryViewId || "factory")) {
|
|
4076
|
-
throw new Error("Factory view selected, but
|
|
4221
|
+
throw new Error("Factory view selected, but no lines are configured in entityConfig.");
|
|
4077
4222
|
}
|
|
4078
4223
|
if (targetLineIds.length === 0) {
|
|
4079
4224
|
throw new Error("No target line IDs available for fetching metrics.");
|
|
@@ -4173,7 +4318,7 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId }) => {
|
|
|
4173
4318
|
}
|
|
4174
4319
|
const currentShiftDetails = getCurrentShift(defaultTimezone, shiftConfig);
|
|
4175
4320
|
const operationalDateForSubscription = getOperationalDate(defaultTimezone);
|
|
4176
|
-
const targetLineIds = currentLineIdToUse === (entityConfig.factoryViewId || "factory") ?
|
|
4321
|
+
const targetLineIds = currentLineIdToUse === (entityConfig.factoryViewId || "factory") ? getConfiguredLineIds(entityConfig) : [currentLineIdToUse];
|
|
4177
4322
|
if (targetLineIds.length === 0) return;
|
|
4178
4323
|
const wsMetricsFilter = `date=eq.${operationalDateForSubscription}&shift_id=eq.${currentShiftDetails.shiftId}&line_id=in.(${targetLineIds.join(",")})`;
|
|
4179
4324
|
const lineMetricsFilter = `date=eq.${operationalDateForSubscription}&shift_id=eq.${currentShiftDetails.shiftId}&line_id=in.(${targetLineIds.join(",")})`;
|
|
@@ -4342,11 +4487,8 @@ var useLineKPIs = ({ lineId }) => {
|
|
|
4342
4487
|
const currentShiftDetails = getCurrentShift(defaultTimezone, shiftConfig);
|
|
4343
4488
|
const operationalDate = currentShiftDetails.date;
|
|
4344
4489
|
const factoryViewIdentifier = entityConfig.factoryViewId || "factory";
|
|
4345
|
-
const targetLineIds = currentLineId === factoryViewIdentifier ?
|
|
4346
|
-
if (targetLineIds.length === 0
|
|
4347
|
-
console.warn("[useLineKPIs] Factory view: defaultLineId/secondaryLineId not in entityConfig. Cannot subscribe effectively.");
|
|
4348
|
-
return;
|
|
4349
|
-
} else if (targetLineIds.length === 0) {
|
|
4490
|
+
const targetLineIds = currentLineId === factoryViewIdentifier ? getConfiguredLineIds(entityConfig) : [currentLineId];
|
|
4491
|
+
if (targetLineIds.length === 0) {
|
|
4350
4492
|
console.warn("[useLineKPIs] No target line IDs for subscription. LineId:", currentLineId);
|
|
4351
4493
|
return;
|
|
4352
4494
|
}
|
|
@@ -4446,10 +4588,8 @@ var useRealtimeLineMetrics = ({
|
|
|
4446
4588
|
currentTime: (/* @__PURE__ */ new Date()).toLocaleString("en-US", { timeZone: dateTimeConfig.defaultTimezone || "Asia/Kolkata" })
|
|
4447
4589
|
});
|
|
4448
4590
|
const factoryViewId = entityConfig.factoryViewId || "factory";
|
|
4449
|
-
const defaultLineId = entityConfig.defaultLineId;
|
|
4450
|
-
const secondaryLineId = entityConfig.secondaryLineId;
|
|
4451
4591
|
if (lineIdRef.current === factoryViewId) {
|
|
4452
|
-
const targetLineIds =
|
|
4592
|
+
const targetLineIds = getConfiguredLineIds(entityConfig);
|
|
4453
4593
|
if (targetLineIds.length === 0) {
|
|
4454
4594
|
throw new Error("No configured line IDs for factory view");
|
|
4455
4595
|
}
|
|
@@ -4663,9 +4803,7 @@ var useRealtimeLineMetrics = ({
|
|
|
4663
4803
|
console.log("Setting up line metrics subscriptions for:", lineIdRef.current);
|
|
4664
4804
|
}
|
|
4665
4805
|
const factoryViewId = entityConfig.factoryViewId || "factory";
|
|
4666
|
-
const
|
|
4667
|
-
const secondaryLineId = entityConfig.secondaryLineId;
|
|
4668
|
-
const targetLineIds = lineIdRef.current === factoryViewId ? [defaultLineId, secondaryLineId].filter(Boolean) : [lineIdRef.current];
|
|
4806
|
+
const targetLineIds = lineIdRef.current === factoryViewId ? getConfiguredLineIds(entityConfig) : [lineIdRef.current];
|
|
4669
4807
|
if (targetLineIds.length === 0) {
|
|
4670
4808
|
return;
|
|
4671
4809
|
}
|
|
@@ -25709,6 +25847,12 @@ var AIAgentView = () => {
|
|
|
25709
25847
|
const lineId = getLineIdFromPath();
|
|
25710
25848
|
const { shiftId } = getCurrentShift(dateTimeConfig.defaultTimezone || "Asia/Kolkata", shiftConfig);
|
|
25711
25849
|
const companyId = entityConfig.companyId || "default-company-id";
|
|
25850
|
+
const configuredLineIds = getConfiguredLineIds(entityConfig);
|
|
25851
|
+
const lineDisplayNames = getAllLineDisplayNames(entityConfig);
|
|
25852
|
+
const allLines = configuredLineIds.map((id3) => ({
|
|
25853
|
+
id: id3,
|
|
25854
|
+
name: lineDisplayNames[id3] || `Line ${id3.substring(0, 8)}`
|
|
25855
|
+
}));
|
|
25712
25856
|
const ACTIVE_THREAD_STORAGE_KEY = `ai-agent-active-thread-${lineId}`;
|
|
25713
25857
|
React19.useLayoutEffect(() => {
|
|
25714
25858
|
const savedThreadId = localStorage.getItem(ACTIVE_THREAD_STORAGE_KEY);
|
|
@@ -25879,7 +26023,8 @@ var AIAgentView = () => {
|
|
|
25879
26023
|
{
|
|
25880
26024
|
companyId,
|
|
25881
26025
|
lineId,
|
|
25882
|
-
shiftId
|
|
26026
|
+
shiftId,
|
|
26027
|
+
allLines
|
|
25883
26028
|
},
|
|
25884
26029
|
{
|
|
25885
26030
|
onThreadCreated: (threadId) => {
|
|
@@ -26526,6 +26671,13 @@ var AIAgentView = () => {
|
|
|
26526
26671
|
console.error("Bar chart missing required parameters:", { data: !!args.data, x_field: !!args.x_field, y_field: !!args.y_field });
|
|
26527
26672
|
return null;
|
|
26528
26673
|
}
|
|
26674
|
+
if (!Array.isArray(args.data)) {
|
|
26675
|
+
console.error("Bar chart data must be an array, got:", typeof args.data, args.data);
|
|
26676
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-red-500 text-sm", children: [
|
|
26677
|
+
"Error: Chart data must be an array. Received: ",
|
|
26678
|
+
typeof args.data
|
|
26679
|
+
] }) }, `bar-error-${key}`);
|
|
26680
|
+
}
|
|
26529
26681
|
return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-64", children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.BarChart, { data: args.data, margin: CHART_STYLES.margin, children: [
|
|
26530
26682
|
/* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { ...CHART_STYLES.grid }),
|
|
26531
26683
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -26563,6 +26715,13 @@ var AIAgentView = () => {
|
|
|
26563
26715
|
console.error("Line chart missing required parameters:", { data: !!args.data, x_field: !!args.x_field, y_field: !!args.y_field });
|
|
26564
26716
|
return null;
|
|
26565
26717
|
}
|
|
26718
|
+
if (!Array.isArray(args.data)) {
|
|
26719
|
+
console.error("Line chart data must be an array, got:", typeof args.data, args.data);
|
|
26720
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-red-500 text-sm", children: [
|
|
26721
|
+
"Error: Chart data must be an array. Received: ",
|
|
26722
|
+
typeof args.data
|
|
26723
|
+
] }) }, `line-error-${key}`);
|
|
26724
|
+
}
|
|
26566
26725
|
return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-64", children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.LineChart, { data: args.data, margin: CHART_STYLES.margin, children: [
|
|
26567
26726
|
/* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { ...CHART_STYLES.grid }),
|
|
26568
26727
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -26604,6 +26763,13 @@ var AIAgentView = () => {
|
|
|
26604
26763
|
console.error("Available args:", Object.keys(args));
|
|
26605
26764
|
return null;
|
|
26606
26765
|
}
|
|
26766
|
+
if (!Array.isArray(args.data)) {
|
|
26767
|
+
console.error("Pie chart data must be an array, got:", typeof args.data, args.data);
|
|
26768
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-red-500 text-sm", children: [
|
|
26769
|
+
"Error: Chart data must be an array. Received: ",
|
|
26770
|
+
typeof args.data
|
|
26771
|
+
] }) }, `pie-error-${key}`);
|
|
26772
|
+
}
|
|
26607
26773
|
const pieData = args.data.map((item) => ({
|
|
26608
26774
|
name: item[args.label_field],
|
|
26609
26775
|
value: item[args.value_field]
|
|
@@ -26623,6 +26789,13 @@ var AIAgentView = () => {
|
|
|
26623
26789
|
console.error("Comparison table missing required data");
|
|
26624
26790
|
return null;
|
|
26625
26791
|
}
|
|
26792
|
+
if (!Array.isArray(args.data)) {
|
|
26793
|
+
console.error("Comparison table data must be an array, got:", typeof args.data, args.data);
|
|
26794
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-red-500 text-sm", children: [
|
|
26795
|
+
"Error: Table data must be an array. Received: ",
|
|
26796
|
+
typeof args.data
|
|
26797
|
+
] }) }, `table-error-${key}`);
|
|
26798
|
+
}
|
|
26626
26799
|
const columns = args.columns || Object.keys(args.data[0] || {});
|
|
26627
26800
|
let sortedData = [...args.data];
|
|
26628
26801
|
if (args.sort_by && columns.includes(args.sort_by)) {
|
|
@@ -26662,6 +26835,13 @@ var AIAgentView = () => {
|
|
|
26662
26835
|
});
|
|
26663
26836
|
return null;
|
|
26664
26837
|
}
|
|
26838
|
+
if (!Array.isArray(args.data)) {
|
|
26839
|
+
console.error("Multi-line chart data must be an array, got:", typeof args.data, args.data);
|
|
26840
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-red-500 text-sm", children: [
|
|
26841
|
+
"Error: Chart data must be an array. Received: ",
|
|
26842
|
+
typeof args.data
|
|
26843
|
+
] }) }, `multi-line-error-${key}`);
|
|
26844
|
+
}
|
|
26665
26845
|
return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-80", children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.LineChart, { data: args.data, margin: CHART_STYLES.margin, children: [
|
|
26666
26846
|
/* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { ...CHART_STYLES.grid }),
|
|
26667
26847
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -26715,6 +26895,13 @@ var AIAgentView = () => {
|
|
|
26715
26895
|
});
|
|
26716
26896
|
return null;
|
|
26717
26897
|
}
|
|
26898
|
+
if (!Array.isArray(args.data)) {
|
|
26899
|
+
console.error("Stacked bar chart data must be an array, got:", typeof args.data, args.data);
|
|
26900
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-red-500 text-sm", children: [
|
|
26901
|
+
"Error: Chart data must be an array. Received: ",
|
|
26902
|
+
typeof args.data
|
|
26903
|
+
] }) }, `stacked-bar-error-${key}`);
|
|
26904
|
+
}
|
|
26718
26905
|
return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-80", children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.BarChart, { data: args.data, margin: CHART_STYLES.margin, children: [
|
|
26719
26906
|
/* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { ...CHART_STYLES.grid }),
|
|
26720
26907
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -26767,6 +26954,13 @@ var AIAgentView = () => {
|
|
|
26767
26954
|
});
|
|
26768
26955
|
return null;
|
|
26769
26956
|
}
|
|
26957
|
+
if (!Array.isArray(args.data)) {
|
|
26958
|
+
console.error("Dual-axis chart data must be an array, got:", typeof args.data, args.data);
|
|
26959
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-red-500 text-sm", children: [
|
|
26960
|
+
"Error: Chart data must be an array. Received: ",
|
|
26961
|
+
typeof args.data
|
|
26962
|
+
] }) }, `dual-axis-error-${key}`);
|
|
26963
|
+
}
|
|
26770
26964
|
return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-80", children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.ComposedChart, { data: args.data, margin: { ...CHART_STYLES.margin, bottom: 80 }, children: [
|
|
26771
26965
|
/* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { ...CHART_STYLES.grid }),
|
|
26772
26966
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -26854,6 +27048,13 @@ var AIAgentView = () => {
|
|
|
26854
27048
|
});
|
|
26855
27049
|
return null;
|
|
26856
27050
|
}
|
|
27051
|
+
if (!Array.isArray(args.data)) {
|
|
27052
|
+
console.error("Scatter plot data must be an array, got:", typeof args.data, args.data);
|
|
27053
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-red-500 text-sm", children: [
|
|
27054
|
+
"Error: Chart data must be an array. Received: ",
|
|
27055
|
+
typeof args.data
|
|
27056
|
+
] }) }, `scatter-error-${key}`);
|
|
27057
|
+
}
|
|
26857
27058
|
const groupedData = args.data.reduce((acc, item) => {
|
|
26858
27059
|
const group = item[args.group_field];
|
|
26859
27060
|
if (!acc[group]) {
|
|
@@ -26917,6 +27118,13 @@ var AIAgentView = () => {
|
|
|
26917
27118
|
});
|
|
26918
27119
|
return null;
|
|
26919
27120
|
}
|
|
27121
|
+
if (!Array.isArray(args.data)) {
|
|
27122
|
+
console.error("Combo chart data must be an array, got:", typeof args.data, args.data);
|
|
27123
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-red-500 text-sm", children: [
|
|
27124
|
+
"Error: Chart data must be an array. Received: ",
|
|
27125
|
+
typeof args.data
|
|
27126
|
+
] }) }, `combo-error-${key}`);
|
|
27127
|
+
}
|
|
26920
27128
|
return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-80", children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.ComposedChart, { data: args.data, margin: { ...CHART_STYLES.margin, bottom: 80 }, children: [
|
|
26921
27129
|
/* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { ...CHART_STYLES.grid }),
|
|
26922
27130
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -26991,6 +27199,13 @@ var AIAgentView = () => {
|
|
|
26991
27199
|
});
|
|
26992
27200
|
return null;
|
|
26993
27201
|
}
|
|
27202
|
+
if (!Array.isArray(args.data)) {
|
|
27203
|
+
console.error("Area chart data must be an array, got:", typeof args.data, args.data);
|
|
27204
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-red-500 text-sm", children: [
|
|
27205
|
+
"Error: Chart data must be an array. Received: ",
|
|
27206
|
+
typeof args.data
|
|
27207
|
+
] }) }, `area-error-${key}`);
|
|
27208
|
+
}
|
|
26994
27209
|
return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-80", children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.ComposedChart, { data: args.data, margin: { ...CHART_STYLES.margin, bottom: 80 }, children: [
|
|
26995
27210
|
/* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs("linearGradient", { id: "colorGradient", x1: "0", y1: "0", x2: "0", y2: "1", children: [
|
|
26996
27211
|
/* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "5%", stopColor: CHART_COLORS.primary, stopOpacity: 0.8 }),
|
|
@@ -27428,20 +27643,33 @@ var DEFAULT_SHIFT_CONFIG2 = {
|
|
|
27428
27643
|
var FactoryView = ({
|
|
27429
27644
|
line1Id,
|
|
27430
27645
|
line2Id,
|
|
27646
|
+
lineIds,
|
|
27647
|
+
lineNames = {},
|
|
27431
27648
|
factoryName = "Plant 1",
|
|
27432
27649
|
timezone = DEFAULT_TIMEZONE,
|
|
27433
27650
|
shiftConfig = DEFAULT_SHIFT_CONFIG2,
|
|
27434
27651
|
productIds = {}
|
|
27435
27652
|
}) => {
|
|
27653
|
+
const effectiveLineIds = React19.useMemo(() => {
|
|
27654
|
+
if (lineIds && lineIds.length > 0) {
|
|
27655
|
+
return lineIds;
|
|
27656
|
+
}
|
|
27657
|
+
const ids = [];
|
|
27658
|
+
if (line1Id) ids.push(line1Id);
|
|
27659
|
+
if (line2Id && line2Id !== line1Id) ids.push(line2Id);
|
|
27660
|
+
return ids;
|
|
27661
|
+
}, [lineIds, line1Id, line2Id]);
|
|
27436
27662
|
const router$1 = router.useRouter();
|
|
27437
27663
|
const supabase = useSupabase();
|
|
27438
|
-
const
|
|
27439
|
-
|
|
27664
|
+
const lineDataHooks = effectiveLineIds.map((lineId) => ({
|
|
27665
|
+
lineId,
|
|
27666
|
+
hook: useLineDetailedMetrics(lineId)
|
|
27667
|
+
}));
|
|
27440
27668
|
const [lines, setLines] = React19.useState([]);
|
|
27441
27669
|
const [loading, setLoading] = React19.useState(true);
|
|
27442
27670
|
const [error, setError] = React19.useState(null);
|
|
27443
27671
|
React19.useMemo(() => {
|
|
27444
|
-
const processLineData = (hookData,
|
|
27672
|
+
const processLineData = (hookData, lineId) => {
|
|
27445
27673
|
const currentLineInfo = hookData.lineData;
|
|
27446
27674
|
let last5HoursData = [];
|
|
27447
27675
|
if (currentLineInfo && currentLineInfo.metrics && currentLineInfo.metrics.output_array && currentLineInfo.metrics.output_array.length > 0) {
|
|
@@ -27462,6 +27690,7 @@ var FactoryView = ({
|
|
|
27462
27690
|
}
|
|
27463
27691
|
}
|
|
27464
27692
|
}
|
|
27693
|
+
const defaultName = lineNames[lineId] || `Line ${lineId.substring(0, 8)}`;
|
|
27465
27694
|
return {
|
|
27466
27695
|
name: currentLineInfo?.line_name || defaultName,
|
|
27467
27696
|
metrics: currentLineInfo,
|
|
@@ -27470,11 +27699,8 @@ var FactoryView = ({
|
|
|
27470
27699
|
last5Hours: last5HoursData.slice(-5)
|
|
27471
27700
|
};
|
|
27472
27701
|
};
|
|
27473
|
-
return
|
|
27474
|
-
|
|
27475
|
-
processLineData(line2DataHook, "Line 2")
|
|
27476
|
-
];
|
|
27477
|
-
}, [line1DataHook, line2DataHook]);
|
|
27702
|
+
return lineDataHooks.map(({ lineId, hook }) => processLineData(hook, lineId));
|
|
27703
|
+
}, [lineDataHooks, lineNames]);
|
|
27478
27704
|
React19.useEffect(() => {
|
|
27479
27705
|
const fetchHourlyData = async () => {
|
|
27480
27706
|
try {
|
|
@@ -27485,45 +27711,37 @@ var FactoryView = ({
|
|
|
27485
27711
|
}
|
|
27486
27712
|
const { shiftId } = getCurrentShift(timezone, shiftConfig);
|
|
27487
27713
|
const date = getOperationalDate();
|
|
27488
|
-
const
|
|
27489
|
-
|
|
27490
|
-
|
|
27491
|
-
|
|
27492
|
-
|
|
27493
|
-
|
|
27494
|
-
|
|
27495
|
-
|
|
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
|
-
});
|
|
27714
|
+
const hourlyDataPromises = effectiveLineIds.map(
|
|
27715
|
+
(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)
|
|
27716
|
+
);
|
|
27717
|
+
const hourlyDataResults = await Promise.all(hourlyDataPromises);
|
|
27718
|
+
for (let i = 0; i < hourlyDataResults.length; i++) {
|
|
27719
|
+
if (hourlyDataResults[i].error) {
|
|
27720
|
+
throw hourlyDataResults[i].error;
|
|
27721
|
+
}
|
|
27526
27722
|
}
|
|
27723
|
+
const linesData = [];
|
|
27724
|
+
lineDataHooks.forEach(({ lineId, hook }, index) => {
|
|
27725
|
+
const lineData = hook.lineData;
|
|
27726
|
+
const hourlyData = hourlyDataResults[index].data;
|
|
27727
|
+
if (lineData && lineData.metrics && lineData.metrics.output_array) {
|
|
27728
|
+
linesData.push({
|
|
27729
|
+
details: {
|
|
27730
|
+
id: lineId,
|
|
27731
|
+
line_name: lineData.line_name || lineNames[lineId] || `Line ${index + 1}`,
|
|
27732
|
+
factory_id: lineData.factory_id || "",
|
|
27733
|
+
factory_name: lineData.factory_name || factoryName
|
|
27734
|
+
},
|
|
27735
|
+
current_output: lineData.metrics.current_output || 0,
|
|
27736
|
+
ideal_output: lineData.metrics.ideal_output || 0,
|
|
27737
|
+
avg_efficiency: lineData.metrics.avg_efficiency || 0,
|
|
27738
|
+
total_workspaces: lineData.metrics.total_workspaces || 0,
|
|
27739
|
+
underperforming_workspaces: lineData.metrics.underperforming_workspaces || 0,
|
|
27740
|
+
last5Hours: (hourlyData || []).map((h) => ({ hour: h.hour, efficiency: h.efficiency })).reverse(),
|
|
27741
|
+
productId: productIds[lineId] || `Product ${String.fromCharCode(65 + index)}`
|
|
27742
|
+
});
|
|
27743
|
+
}
|
|
27744
|
+
});
|
|
27527
27745
|
setLines(linesData);
|
|
27528
27746
|
setLoading(false);
|
|
27529
27747
|
} catch (err) {
|
|
@@ -27532,10 +27750,11 @@ var FactoryView = ({
|
|
|
27532
27750
|
setLoading(false);
|
|
27533
27751
|
}
|
|
27534
27752
|
};
|
|
27535
|
-
|
|
27753
|
+
const allHooksLoaded = lineDataHooks.every(({ hook }) => !hook.loading);
|
|
27754
|
+
if (allHooksLoaded) {
|
|
27536
27755
|
fetchHourlyData();
|
|
27537
27756
|
}
|
|
27538
|
-
}, [supabase,
|
|
27757
|
+
}, [supabase, lineDataHooks, effectiveLineIds, lineNames, factoryName, timezone, shiftConfig, productIds]);
|
|
27539
27758
|
const getShiftName = () => {
|
|
27540
27759
|
const now2 = /* @__PURE__ */ new Date();
|
|
27541
27760
|
const currentHour = now2.getHours();
|
|
@@ -27549,7 +27768,7 @@ var FactoryView = ({
|
|
|
27549
27768
|
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
27769
|
}
|
|
27551
27770
|
};
|
|
27552
|
-
if (loading ||
|
|
27771
|
+
if (loading || lineDataHooks.some((hookData) => hookData.hook.loading)) {
|
|
27553
27772
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "animate-pulse space-y-4", children: [
|
|
27554
27773
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-12 bg-gray-200 rounded" }),
|
|
27555
27774
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-12 bg-gray-200 rounded" })
|
|
@@ -28299,6 +28518,7 @@ var HelpView = ({
|
|
|
28299
28518
|
var AuthenticatedHelpView = withAuth(HelpView);
|
|
28300
28519
|
var HelpView_default = HelpView;
|
|
28301
28520
|
var KPISection2 = KPISection;
|
|
28521
|
+
var LoadingPageCmp = LoadingPage_default;
|
|
28302
28522
|
function HomeView({
|
|
28303
28523
|
defaultLineId,
|
|
28304
28524
|
factoryViewId,
|
|
@@ -28438,53 +28658,7 @@ function HomeView({
|
|
|
28438
28658
|
const isInitialLoading = !isHydrated || !displayNamesInitialized && displayNamesLoading;
|
|
28439
28659
|
const isDataLoading = metricsLoading || kpisLoading;
|
|
28440
28660
|
if (isInitialLoading) {
|
|
28441
|
-
return /* @__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
|
-
) });
|
|
28661
|
+
return /* @__PURE__ */ jsxRuntime.jsx(LoadingPageCmp, { message: "Loading Dashboard..." });
|
|
28488
28662
|
}
|
|
28489
28663
|
if (errorMessage || displayNamesError) {
|
|
28490
28664
|
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 +34291,7 @@ exports.formatISTDate = formatISTDate;
|
|
|
34117
34291
|
exports.formatIdleTime = formatIdleTime;
|
|
34118
34292
|
exports.formatTimeInZone = formatTimeInZone;
|
|
34119
34293
|
exports.fromUrlFriendlyName = fromUrlFriendlyName;
|
|
34294
|
+
exports.getAllLineDisplayNames = getAllLineDisplayNames;
|
|
34120
34295
|
exports.getAllThreadMessages = getAllThreadMessages;
|
|
34121
34296
|
exports.getAllWorkspaceDisplayNamesAsync = getAllWorkspaceDisplayNamesAsync;
|
|
34122
34297
|
exports.getAnonClient = getAnonClient;
|
|
@@ -34124,12 +34299,17 @@ exports.getCameraNumber = getCameraNumber;
|
|
|
34124
34299
|
exports.getCompanyMetricsTableName = getCompanyMetricsTableName;
|
|
34125
34300
|
exports.getConfigurableShortWorkspaceDisplayName = getConfigurableShortWorkspaceDisplayName;
|
|
34126
34301
|
exports.getConfigurableWorkspaceDisplayName = getConfigurableWorkspaceDisplayName;
|
|
34302
|
+
exports.getConfiguredLineIds = getConfiguredLineIds;
|
|
34303
|
+
exports.getCoreSessionRecordingProperties = getCoreSessionRecordingProperties;
|
|
34304
|
+
exports.getCoreSessionReplayUrl = getCoreSessionReplayUrl;
|
|
34127
34305
|
exports.getCurrentShift = getCurrentShift;
|
|
34128
34306
|
exports.getCurrentTimeInZone = getCurrentTimeInZone;
|
|
34129
34307
|
exports.getDashboardHeaderTimeInZone = getDashboardHeaderTimeInZone;
|
|
34130
34308
|
exports.getDaysDifferenceInZone = getDaysDifferenceInZone;
|
|
34131
34309
|
exports.getDefaultCameraStreamUrl = getDefaultCameraStreamUrl;
|
|
34310
|
+
exports.getDefaultLineId = getDefaultLineId;
|
|
34132
34311
|
exports.getDefaultTabForWorkspace = getDefaultTabForWorkspace;
|
|
34312
|
+
exports.getLineDisplayName = getLineDisplayName;
|
|
34133
34313
|
exports.getManufacturingInsights = getManufacturingInsights;
|
|
34134
34314
|
exports.getMetricsTablePrefix = getMetricsTablePrefix;
|
|
34135
34315
|
exports.getOperationalDate = getOperationalDate;
|
|
@@ -34149,13 +34329,16 @@ exports.getWorkspaceFromUrl = getWorkspaceFromUrl;
|
|
|
34149
34329
|
exports.getWorkspaceNavigationParams = getWorkspaceNavigationParams;
|
|
34150
34330
|
exports.identifyCoreUser = identifyCoreUser;
|
|
34151
34331
|
exports.initializeCoreMixpanel = initializeCoreMixpanel;
|
|
34332
|
+
exports.isLegacyConfiguration = isLegacyConfiguration;
|
|
34152
34333
|
exports.isTransitionPeriod = isTransitionPeriod;
|
|
34334
|
+
exports.isValidFactoryViewConfiguration = isValidFactoryViewConfiguration;
|
|
34153
34335
|
exports.isValidLineInfoPayload = isValidLineInfoPayload;
|
|
34154
34336
|
exports.isValidWorkspaceDetailedMetricsPayload = isValidWorkspaceDetailedMetricsPayload;
|
|
34155
34337
|
exports.isValidWorkspaceMetricsPayload = isValidWorkspaceMetricsPayload;
|
|
34156
34338
|
exports.isWorkspaceDisplayNamesLoaded = isWorkspaceDisplayNamesLoaded;
|
|
34157
34339
|
exports.isWorkspaceDisplayNamesLoading = isWorkspaceDisplayNamesLoading;
|
|
34158
34340
|
exports.mergeWithDefaultConfig = mergeWithDefaultConfig;
|
|
34341
|
+
exports.migrateLegacyConfiguration = migrateLegacyConfiguration;
|
|
34159
34342
|
exports.optifyeAgentClient = optifyeAgentClient;
|
|
34160
34343
|
exports.preInitializeWorkspaceDisplayNames = preInitializeWorkspaceDisplayNames;
|
|
34161
34344
|
exports.preloadS3Video = preloadS3Video;
|
|
@@ -34170,6 +34353,8 @@ exports.resetCoreMixpanel = resetCoreMixpanel;
|
|
|
34170
34353
|
exports.resetSubscriptionManager = resetSubscriptionManager;
|
|
34171
34354
|
exports.s3VideoPreloader = s3VideoPreloader;
|
|
34172
34355
|
exports.skuService = skuService;
|
|
34356
|
+
exports.startCoreSessionRecording = startCoreSessionRecording;
|
|
34357
|
+
exports.stopCoreSessionRecording = stopCoreSessionRecording;
|
|
34173
34358
|
exports.storeWorkspaceMapping = storeWorkspaceMapping;
|
|
34174
34359
|
exports.streamProxyConfig = streamProxyConfig;
|
|
34175
34360
|
exports.throttledReloadDashboard = throttledReloadDashboard;
|