@optifye/dashboard-core 6.10.50 → 6.10.51
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.d.mts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +404 -211
- package/dist/index.mjs +404 -211
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -1029,6 +1029,44 @@ var fetchBackendJson = async (supabase, endpoint, options = {}) => {
|
|
|
1029
1029
|
}
|
|
1030
1030
|
};
|
|
1031
1031
|
|
|
1032
|
+
// src/lib/services/lineMetricsSelection.ts
|
|
1033
|
+
var toTimestamp = (value) => {
|
|
1034
|
+
if (typeof value !== "string") return 0;
|
|
1035
|
+
const parsed = Date.parse(value);
|
|
1036
|
+
return Number.isNaN(parsed) ? 0 : parsed;
|
|
1037
|
+
};
|
|
1038
|
+
var compareByLatestThenSku = (a, b) => {
|
|
1039
|
+
const timeDiff = toTimestamp(b.last_updated) - toTimestamp(a.last_updated);
|
|
1040
|
+
if (timeDiff !== 0) return timeDiff;
|
|
1041
|
+
const aSku = typeof a.sku_id === "string" ? a.sku_id : "";
|
|
1042
|
+
const bSku = typeof b.sku_id === "string" ? b.sku_id : "";
|
|
1043
|
+
return aSku.localeCompare(bSku);
|
|
1044
|
+
};
|
|
1045
|
+
var pickPreferredLineMetricsRow = async (supabase, lineId, rows, skuTable = "skus") => {
|
|
1046
|
+
if (!rows || rows.length === 0) {
|
|
1047
|
+
return null;
|
|
1048
|
+
}
|
|
1049
|
+
if (rows.length === 1) {
|
|
1050
|
+
return rows[0];
|
|
1051
|
+
}
|
|
1052
|
+
let dummySkuId = null;
|
|
1053
|
+
try {
|
|
1054
|
+
const { data } = await supabase.from(skuTable).select("id").eq("line_id", lineId).eq("sku_definition", "dummy_definition").eq("is_active", true).limit(1);
|
|
1055
|
+
if (Array.isArray(data) && data.length > 0) {
|
|
1056
|
+
dummySkuId = typeof data[0]?.id === "string" ? data[0].id : null;
|
|
1057
|
+
}
|
|
1058
|
+
} catch (error) {
|
|
1059
|
+
console.warn("[lineMetricsSelection] Failed dummy SKU lookup:", error);
|
|
1060
|
+
}
|
|
1061
|
+
if (dummySkuId) {
|
|
1062
|
+
const dummyRow = rows.find((row) => row.sku_id === dummySkuId);
|
|
1063
|
+
if (dummyRow) {
|
|
1064
|
+
return dummyRow;
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
return rows.slice().sort(compareByLatestThenSku)[0] ?? null;
|
|
1068
|
+
};
|
|
1069
|
+
|
|
1032
1070
|
// src/lib/services/dashboardService.ts
|
|
1033
1071
|
var getTable = (dbConfig, tableName) => {
|
|
1034
1072
|
const defaults2 = DEFAULT_DATABASE_CONFIG.tables;
|
|
@@ -1047,6 +1085,7 @@ var dashboardService = {
|
|
|
1047
1085
|
const workspaceConfig = config.workspaceConfig ?? DEFAULT_WORKSPACE_CONFIG;
|
|
1048
1086
|
const linesTable = getTable(dbConfig, "lines");
|
|
1049
1087
|
const lineMetricsTable = getTable(dbConfig, "lineMetrics");
|
|
1088
|
+
const skuTable = dbConfig?.tables?.skus ?? "skus";
|
|
1050
1089
|
const companyId = entityConfig.companyId;
|
|
1051
1090
|
const metricsTablePrefixStr = getMetricsTablePrefix();
|
|
1052
1091
|
`${metricsTablePrefixStr}_${companyId ? companyId.replace(/-/g, "_") : "unknown_company"}`;
|
|
@@ -1140,9 +1179,14 @@ var dashboardService = {
|
|
|
1140
1179
|
if (!lineData) throw new Error(`Line with ID ${lineId} not found`);
|
|
1141
1180
|
let metricsFromDb = null;
|
|
1142
1181
|
try {
|
|
1143
|
-
const { data:
|
|
1182
|
+
const { data: fetchedMetricsRows, error } = await supabase.from(lineMetricsTable).select("*").eq("line_id", lineId).eq("shift_id", shiftId).eq("date", date);
|
|
1144
1183
|
if (error) throw error;
|
|
1145
|
-
metricsFromDb =
|
|
1184
|
+
metricsFromDb = await pickPreferredLineMetricsRow(
|
|
1185
|
+
supabase,
|
|
1186
|
+
lineId,
|
|
1187
|
+
fetchedMetricsRows,
|
|
1188
|
+
skuTable
|
|
1189
|
+
);
|
|
1146
1190
|
} catch (err) {
|
|
1147
1191
|
console.error(`Error fetching line metrics for ${lineId}:`, err);
|
|
1148
1192
|
}
|
|
@@ -1553,6 +1597,7 @@ var dashboardService = {
|
|
|
1553
1597
|
const workspaceConfig = config.workspaceConfig ?? DEFAULT_WORKSPACE_CONFIG;
|
|
1554
1598
|
const linesTable = getTable(dbConfig, "lines");
|
|
1555
1599
|
const lineMetricsTable = getTable(dbConfig, "lineMetrics");
|
|
1600
|
+
const skuTable = dbConfig?.tables?.skus ?? "skus";
|
|
1556
1601
|
const companyId = entityConfig.companyId;
|
|
1557
1602
|
const metricsTablePrefixStr = getMetricsTablePrefix();
|
|
1558
1603
|
`${metricsTablePrefixStr}_${companyId ? companyId.replace(/-/g, "_") : "unknown_company"}`;
|
|
@@ -1651,7 +1696,7 @@ var dashboardService = {
|
|
|
1651
1696
|
}
|
|
1652
1697
|
const [lineResult, metricsResult] = await Promise.all([
|
|
1653
1698
|
supabase.from(linesTable).select("id, line_name, factory_id, monitoring_mode, factories!lines_factory_id_fkey(factory_name), company_id, companies!lines_company_id_fkey(company_name:name)").eq("id", lineIdToQuery).single(),
|
|
1654
|
-
supabase.from(lineMetricsTable).select("*").eq("line_id", lineIdToQuery).eq("shift_id", queryShiftId).eq("date", queryDate)
|
|
1699
|
+
supabase.from(lineMetricsTable).select("*").eq("line_id", lineIdToQuery).eq("shift_id", queryShiftId).eq("date", queryDate)
|
|
1655
1700
|
]);
|
|
1656
1701
|
if (lineResult.error) throw lineResult.error;
|
|
1657
1702
|
if (!lineResult.data) {
|
|
@@ -1659,7 +1704,12 @@ var dashboardService = {
|
|
|
1659
1704
|
}
|
|
1660
1705
|
if (metricsResult.error) throw metricsResult.error;
|
|
1661
1706
|
const lineData = lineResult.data;
|
|
1662
|
-
const metrics2 =
|
|
1707
|
+
const metrics2 = await pickPreferredLineMetricsRow(
|
|
1708
|
+
supabase,
|
|
1709
|
+
lineIdToQuery,
|
|
1710
|
+
metricsResult.data,
|
|
1711
|
+
skuTable
|
|
1712
|
+
);
|
|
1663
1713
|
return {
|
|
1664
1714
|
line_id: lineData.id,
|
|
1665
1715
|
line_name: lineData.line_name,
|
|
@@ -17330,6 +17380,7 @@ function useCompanyClipsCost() {
|
|
|
17330
17380
|
const [data, setData] = useState(null);
|
|
17331
17381
|
const [isLoading, setIsLoading] = useState(true);
|
|
17332
17382
|
const [error, setError] = useState(null);
|
|
17383
|
+
const hasFetchedOnceRef = useRef(false);
|
|
17333
17384
|
const canViewClipsCost = user?.role_level === "owner" || user?.role_level === "optifye";
|
|
17334
17385
|
const companyId = user?.properties?.company_id || user?.company_id || entityConfig.companyId;
|
|
17335
17386
|
const apiBaseUrl = config?.apiBaseUrl || process.env.NEXT_PUBLIC_API_BASE_URL || "";
|
|
@@ -17337,9 +17388,12 @@ function useCompanyClipsCost() {
|
|
|
17337
17388
|
if (!canViewClipsCost || !companyId || !supabase || !apiBaseUrl || !session?.access_token) {
|
|
17338
17389
|
setIsLoading(false);
|
|
17339
17390
|
setData(null);
|
|
17391
|
+
hasFetchedOnceRef.current = false;
|
|
17340
17392
|
return;
|
|
17341
17393
|
}
|
|
17342
|
-
|
|
17394
|
+
if (!hasFetchedOnceRef.current) {
|
|
17395
|
+
setIsLoading(true);
|
|
17396
|
+
}
|
|
17343
17397
|
setError(null);
|
|
17344
17398
|
try {
|
|
17345
17399
|
const [statsResponse, linesResult] = await Promise.all([
|
|
@@ -17356,9 +17410,18 @@ function useCompanyClipsCost() {
|
|
|
17356
17410
|
}
|
|
17357
17411
|
const statsResult = await statsResponse.json();
|
|
17358
17412
|
const totalClassifications = statsResult.total_classifications || 0;
|
|
17413
|
+
const monthlyClassifications = statsResult.monthly_classifications ?? totalClassifications;
|
|
17414
|
+
const monthStart = statsResult.month_start || null;
|
|
17415
|
+
const historicalMonthlyClassifications = Array.isArray(statsResult.historical_monthly_classifications) ? statsResult.historical_monthly_classifications.map((item) => ({
|
|
17416
|
+
monthStart: item?.month_start || "",
|
|
17417
|
+
classifications: Number(item?.classifications || 0)
|
|
17418
|
+
})).filter((item) => item.monthStart && item.classifications > 0) : [];
|
|
17359
17419
|
const hasVlmEnabledLine = (linesResult.data?.length || 0) > 0;
|
|
17360
17420
|
setData({
|
|
17361
17421
|
totalClassifications,
|
|
17422
|
+
monthlyClassifications,
|
|
17423
|
+
monthStart,
|
|
17424
|
+
historicalMonthlyClassifications,
|
|
17362
17425
|
hasVlmEnabledLine
|
|
17363
17426
|
});
|
|
17364
17427
|
} catch (err) {
|
|
@@ -17366,6 +17429,7 @@ function useCompanyClipsCost() {
|
|
|
17366
17429
|
setError(err instanceof Error ? err.message : "Failed to load clips data");
|
|
17367
17430
|
setData(null);
|
|
17368
17431
|
} finally {
|
|
17432
|
+
hasFetchedOnceRef.current = true;
|
|
17369
17433
|
setIsLoading(false);
|
|
17370
17434
|
}
|
|
17371
17435
|
}, [canViewClipsCost, companyId, supabase, apiBaseUrl, session?.access_token]);
|
|
@@ -36736,6 +36800,7 @@ var FileManagerFilters = ({
|
|
|
36736
36800
|
const endInputRef = useRef(null);
|
|
36737
36801
|
const [idleLabelFilter, setIdleLabelFilter] = useState(null);
|
|
36738
36802
|
const [showIdleLabelFilterModal, setShowIdleLabelFilterModal] = useState(false);
|
|
36803
|
+
const [isLoadingIdleReasonOptions, setIsLoadingIdleReasonOptions] = useState(false);
|
|
36739
36804
|
const timezone = useAppTimezone();
|
|
36740
36805
|
const supabase = useSupabase();
|
|
36741
36806
|
const [clipMetadata, setClipMetadata] = useState({});
|
|
@@ -36778,18 +36843,27 @@ var FileManagerFilters = ({
|
|
|
36778
36843
|
iconColor: colorConfig.text
|
|
36779
36844
|
};
|
|
36780
36845
|
};
|
|
36781
|
-
const
|
|
36782
|
-
"
|
|
36783
|
-
|
|
36784
|
-
"Machine Downtime",
|
|
36785
|
-
"No Material"
|
|
36786
|
-
];
|
|
36846
|
+
const normalizeIdleReasonLabel = useCallback((label) => {
|
|
36847
|
+
return label.replace(/_/g, " ").trim();
|
|
36848
|
+
}, []);
|
|
36787
36849
|
const getIdleTimeRootCause = useCallback((clipId) => {
|
|
36788
36850
|
const classification = mergedClipClassifications[clipId];
|
|
36789
36851
|
if (!classification) return "processing";
|
|
36790
36852
|
if (classification.status === "processing") return "processing";
|
|
36791
36853
|
return classification.label || "processing";
|
|
36792
36854
|
}, [mergedClipClassifications]);
|
|
36855
|
+
const idleReasonOptions = useMemo(() => {
|
|
36856
|
+
const idleClips = clipMetadata["idle_time"] || [];
|
|
36857
|
+
const uniqueReasons = /* @__PURE__ */ new Set();
|
|
36858
|
+
idleClips.forEach((clip) => {
|
|
36859
|
+
const clipId = clip.clipId || clip.id;
|
|
36860
|
+
if (!clipId) return;
|
|
36861
|
+
const reason = getIdleTimeRootCause(clipId);
|
|
36862
|
+
if (!reason || reason === "processing") return;
|
|
36863
|
+
uniqueReasons.add(normalizeIdleReasonLabel(reason));
|
|
36864
|
+
});
|
|
36865
|
+
return Array.from(uniqueReasons).sort((a, b) => a.localeCompare(b));
|
|
36866
|
+
}, [clipMetadata, getIdleTimeRootCause, normalizeIdleReasonLabel]);
|
|
36793
36867
|
const getClipBadge = useCallback((node) => {
|
|
36794
36868
|
if (node.categoryId === "idle_time" || node.categoryId === "low_value") {
|
|
36795
36869
|
return { text: "Idle", className: "bg-red-100 text-red-700" };
|
|
@@ -36817,6 +36891,79 @@ var FileManagerFilters = ({
|
|
|
36817
36891
|
return null;
|
|
36818
36892
|
}
|
|
36819
36893
|
}, [supabase]);
|
|
36894
|
+
const fetchClipMetadataPage = useCallback(async (categoryId, page = 1) => {
|
|
36895
|
+
if (!workspaceId || !date || shift === void 0) {
|
|
36896
|
+
throw new Error("Missing required params for clip metadata fetch");
|
|
36897
|
+
}
|
|
36898
|
+
const response = await fetchWithSupabaseAuth(supabase, "/api/clips/supabase", {
|
|
36899
|
+
method: "POST",
|
|
36900
|
+
headers: {
|
|
36901
|
+
"Content-Type": "application/json"
|
|
36902
|
+
},
|
|
36903
|
+
body: JSON.stringify({
|
|
36904
|
+
action: "clip-metadata",
|
|
36905
|
+
workspaceId,
|
|
36906
|
+
date,
|
|
36907
|
+
shift: shift.toString(),
|
|
36908
|
+
category: categoryId,
|
|
36909
|
+
page,
|
|
36910
|
+
limit: 50,
|
|
36911
|
+
snapshotDateTime,
|
|
36912
|
+
snapshotClipId
|
|
36913
|
+
}),
|
|
36914
|
+
redirectReason: "session_expired"
|
|
36915
|
+
});
|
|
36916
|
+
if (!response.ok) {
|
|
36917
|
+
throw new Error(`API error: ${response.status}`);
|
|
36918
|
+
}
|
|
36919
|
+
return response.json();
|
|
36920
|
+
}, [workspaceId, date, shift, snapshotDateTime, snapshotClipId, supabase]);
|
|
36921
|
+
const seedIdleClassifications = useCallback(async (clips) => {
|
|
36922
|
+
if (!idleTimeVlmEnabled || clips.length === 0) {
|
|
36923
|
+
return;
|
|
36924
|
+
}
|
|
36925
|
+
const authToken = await getAuthToken3();
|
|
36926
|
+
if (!authToken) {
|
|
36927
|
+
return;
|
|
36928
|
+
}
|
|
36929
|
+
const seededClassifications = {};
|
|
36930
|
+
clips.forEach((clip) => {
|
|
36931
|
+
if (!clip.clipId) {
|
|
36932
|
+
return;
|
|
36933
|
+
}
|
|
36934
|
+
if (clip.classification_status) {
|
|
36935
|
+
seededClassifications[clip.clipId] = {
|
|
36936
|
+
status: clip.classification_status,
|
|
36937
|
+
label: clip.classification_label || void 0,
|
|
36938
|
+
confidence: clip.classification_confidence ?? void 0
|
|
36939
|
+
};
|
|
36940
|
+
}
|
|
36941
|
+
});
|
|
36942
|
+
if (Object.keys(seededClassifications).length > 0) {
|
|
36943
|
+
setLocalClipClassifications((prev) => ({
|
|
36944
|
+
...prev,
|
|
36945
|
+
...seededClassifications
|
|
36946
|
+
}));
|
|
36947
|
+
}
|
|
36948
|
+
const clipIdsToFetch = clips.map((clip) => clip.clipId || clip.id).filter(Boolean).filter((id3) => {
|
|
36949
|
+
if (!id3) return false;
|
|
36950
|
+
if (mergedClipClassifications[id3]?.status === "classified") return false;
|
|
36951
|
+
if (seededClassifications[id3]?.status === "classified") return false;
|
|
36952
|
+
return true;
|
|
36953
|
+
});
|
|
36954
|
+
if (clipIdsToFetch.length === 0) {
|
|
36955
|
+
return;
|
|
36956
|
+
}
|
|
36957
|
+
try {
|
|
36958
|
+
const classifications = await fetchClassifications(clipIdsToFetch, authToken);
|
|
36959
|
+
setLocalClipClassifications((prev) => ({
|
|
36960
|
+
...prev,
|
|
36961
|
+
...classifications
|
|
36962
|
+
}));
|
|
36963
|
+
} catch (error) {
|
|
36964
|
+
console.error("[FileManager] Error fetching idle classifications:", error);
|
|
36965
|
+
}
|
|
36966
|
+
}, [idleTimeVlmEnabled, getAuthToken3, mergedClipClassifications]);
|
|
36820
36967
|
const fetchClipMetadata = useCallback(async (categoryId, page = 1) => {
|
|
36821
36968
|
if (!workspaceId || !date || shift === void 0) {
|
|
36822
36969
|
console.warn("[FileManager] Missing required params for clip metadata fetch");
|
|
@@ -36825,69 +36972,13 @@ var FileManagerFilters = ({
|
|
|
36825
36972
|
const loadingKey = `${categoryId}-${page}`;
|
|
36826
36973
|
setLoadingCategories((prev) => /* @__PURE__ */ new Set([...prev, loadingKey]));
|
|
36827
36974
|
try {
|
|
36828
|
-
const
|
|
36829
|
-
method: "POST",
|
|
36830
|
-
headers: {
|
|
36831
|
-
"Content-Type": "application/json"
|
|
36832
|
-
},
|
|
36833
|
-
body: JSON.stringify({
|
|
36834
|
-
action: "clip-metadata",
|
|
36835
|
-
workspaceId,
|
|
36836
|
-
date,
|
|
36837
|
-
shift: shift.toString(),
|
|
36838
|
-
category: categoryId,
|
|
36839
|
-
page,
|
|
36840
|
-
limit: 50,
|
|
36841
|
-
snapshotDateTime,
|
|
36842
|
-
snapshotClipId
|
|
36843
|
-
}),
|
|
36844
|
-
redirectReason: "session_expired"
|
|
36845
|
-
});
|
|
36846
|
-
if (!response.ok) {
|
|
36847
|
-
throw new Error(`API error: ${response.status}`);
|
|
36848
|
-
}
|
|
36849
|
-
const data = await response.json();
|
|
36975
|
+
const data = await fetchClipMetadataPage(categoryId, page);
|
|
36850
36976
|
setClipMetadata((prev) => ({
|
|
36851
36977
|
...prev,
|
|
36852
36978
|
[categoryId]: page === 1 ? data.clips : [...prev[categoryId] || [], ...data.clips]
|
|
36853
36979
|
}));
|
|
36854
|
-
|
|
36855
|
-
|
|
36856
|
-
const seededClassifications = {};
|
|
36857
|
-
(data.clips || []).forEach((clip) => {
|
|
36858
|
-
if (!clip.clipId) {
|
|
36859
|
-
return;
|
|
36860
|
-
}
|
|
36861
|
-
if (clip.classification_status) {
|
|
36862
|
-
seededClassifications[clip.clipId] = {
|
|
36863
|
-
status: clip.classification_status,
|
|
36864
|
-
label: clip.classification_label || void 0,
|
|
36865
|
-
confidence: clip.classification_confidence ?? void 0
|
|
36866
|
-
};
|
|
36867
|
-
}
|
|
36868
|
-
});
|
|
36869
|
-
if (Object.keys(seededClassifications).length > 0) {
|
|
36870
|
-
setLocalClipClassifications((prev) => ({
|
|
36871
|
-
...prev,
|
|
36872
|
-
...seededClassifications
|
|
36873
|
-
}));
|
|
36874
|
-
}
|
|
36875
|
-
const clipIds = (data.clips || []).map((clip) => clip.clipId || clip.id).filter(Boolean);
|
|
36876
|
-
const newClipIds = clipIds.filter((id3) => {
|
|
36877
|
-
if (mergedClipClassifications[id3]?.status === "classified") return false;
|
|
36878
|
-
if (seededClassifications[id3]?.status === "classified") return false;
|
|
36879
|
-
return true;
|
|
36880
|
-
});
|
|
36881
|
-
if (newClipIds.length > 0) {
|
|
36882
|
-
fetchClassifications(newClipIds, authToken).then((classifications) => {
|
|
36883
|
-
setLocalClipClassifications((prev) => ({
|
|
36884
|
-
...prev,
|
|
36885
|
-
...classifications
|
|
36886
|
-
}));
|
|
36887
|
-
}).catch((error) => {
|
|
36888
|
-
console.error("[FileManager] Error fetching idle classifications:", error);
|
|
36889
|
-
});
|
|
36890
|
-
}
|
|
36980
|
+
if (categoryId === "idle_time" && idleTimeVlmEnabled) {
|
|
36981
|
+
await seedIdleClassifications(data.clips || []);
|
|
36891
36982
|
}
|
|
36892
36983
|
setCategoryPages((prev) => ({ ...prev, [categoryId]: page }));
|
|
36893
36984
|
setCategoryHasMore((prev) => ({ ...prev, [categoryId]: data.hasMore }));
|
|
@@ -36901,7 +36992,64 @@ var FileManagerFilters = ({
|
|
|
36901
36992
|
return newSet;
|
|
36902
36993
|
});
|
|
36903
36994
|
}
|
|
36904
|
-
}, [workspaceId, date, shift,
|
|
36995
|
+
}, [workspaceId, date, shift, fetchClipMetadataPage, idleTimeVlmEnabled, seedIdleClassifications]);
|
|
36996
|
+
const ensureAllIdleTimeClipMetadataLoaded = useCallback(async () => {
|
|
36997
|
+
if (!workspaceId || !date || shift === void 0) {
|
|
36998
|
+
return;
|
|
36999
|
+
}
|
|
37000
|
+
let accumulatedClips = [...clipMetadata["idle_time"] || []];
|
|
37001
|
+
let currentPage = categoryPages["idle_time"] || 0;
|
|
37002
|
+
let hasMore = categoryHasMore["idle_time"];
|
|
37003
|
+
if (currentPage === 0) {
|
|
37004
|
+
const firstPageData = await fetchClipMetadataPage("idle_time", 1);
|
|
37005
|
+
accumulatedClips = firstPageData.clips || [];
|
|
37006
|
+
currentPage = 1;
|
|
37007
|
+
hasMore = firstPageData.hasMore;
|
|
37008
|
+
} else if (hasMore === void 0) {
|
|
37009
|
+
hasMore = false;
|
|
37010
|
+
}
|
|
37011
|
+
while (hasMore) {
|
|
37012
|
+
const nextPage = currentPage + 1;
|
|
37013
|
+
const nextPageData = await fetchClipMetadataPage("idle_time", nextPage);
|
|
37014
|
+
accumulatedClips = [...accumulatedClips, ...nextPageData.clips || []];
|
|
37015
|
+
currentPage = nextPage;
|
|
37016
|
+
hasMore = nextPageData.hasMore;
|
|
37017
|
+
}
|
|
37018
|
+
const dedupedClips = accumulatedClips.filter((clip, index, arr) => {
|
|
37019
|
+
const clipKey = clip.clipId || clip.id;
|
|
37020
|
+
return arr.findIndex((item) => (item.clipId || item.id) === clipKey) === index;
|
|
37021
|
+
});
|
|
37022
|
+
setClipMetadata((prev) => ({
|
|
37023
|
+
...prev,
|
|
37024
|
+
idle_time: dedupedClips
|
|
37025
|
+
}));
|
|
37026
|
+
setCategoryPages((prev) => ({ ...prev, idle_time: currentPage }));
|
|
37027
|
+
setCategoryHasMore((prev) => ({ ...prev, idle_time: false }));
|
|
37028
|
+
if (idleTimeVlmEnabled) {
|
|
37029
|
+
await seedIdleClassifications(dedupedClips);
|
|
37030
|
+
}
|
|
37031
|
+
}, [
|
|
37032
|
+
workspaceId,
|
|
37033
|
+
date,
|
|
37034
|
+
shift,
|
|
37035
|
+
clipMetadata,
|
|
37036
|
+
categoryPages,
|
|
37037
|
+
categoryHasMore,
|
|
37038
|
+
fetchClipMetadataPage,
|
|
37039
|
+
idleTimeVlmEnabled,
|
|
37040
|
+
seedIdleClassifications
|
|
37041
|
+
]);
|
|
37042
|
+
const handleOpenIdleLabelFilterModal = useCallback(async () => {
|
|
37043
|
+
setShowIdleLabelFilterModal(true);
|
|
37044
|
+
setIsLoadingIdleReasonOptions(true);
|
|
37045
|
+
try {
|
|
37046
|
+
await ensureAllIdleTimeClipMetadataLoaded();
|
|
37047
|
+
} catch (error) {
|
|
37048
|
+
console.error("[FileManager] Error loading idle reason options:", error);
|
|
37049
|
+
} finally {
|
|
37050
|
+
setIsLoadingIdleReasonOptions(false);
|
|
37051
|
+
}
|
|
37052
|
+
}, [ensureAllIdleTimeClipMetadataLoaded]);
|
|
36905
37053
|
const fetchPercentileClips = useCallback(async (type) => {
|
|
36906
37054
|
if (!workspaceId || !date || shift === void 0) {
|
|
36907
37055
|
console.warn("[FileManager] Missing required params for percentile clips fetch");
|
|
@@ -37572,7 +37720,7 @@ var FileManagerFilters = ({
|
|
|
37572
37720
|
activeFilter === "idle_time" && idleTimeVlmEnabled && /* @__PURE__ */ jsx(
|
|
37573
37721
|
"button",
|
|
37574
37722
|
{
|
|
37575
|
-
onClick:
|
|
37723
|
+
onClick: handleOpenIdleLabelFilterModal,
|
|
37576
37724
|
className: `p-2 rounded-xl transition-all duration-200 ${idleLabelFilter ? "bg-purple-100 text-purple-600 hover:bg-purple-200 shadow-sm" : "bg-slate-100 text-slate-600 hover:bg-slate-200"}`,
|
|
37577
37725
|
title: "Filter by idle reason",
|
|
37578
37726
|
children: /* @__PURE__ */ jsx(Tag, { className: "h-5 w-5" })
|
|
@@ -37660,7 +37808,10 @@ var FileManagerFilters = ({
|
|
|
37660
37808
|
}
|
|
37661
37809
|
)
|
|
37662
37810
|
] }),
|
|
37663
|
-
/* @__PURE__ */ jsx("div", { className: "p-2 max-h-60 overflow-y-auto", children:
|
|
37811
|
+
/* @__PURE__ */ jsx("div", { className: "p-2 max-h-60 overflow-y-auto", children: isLoadingIdleReasonOptions ? /* @__PURE__ */ jsxs("div", { className: "px-3 py-4 text-sm text-slate-500 flex items-center gap-2", children: [
|
|
37812
|
+
/* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }),
|
|
37813
|
+
"Loading idle reasons..."
|
|
37814
|
+
] }) : idleReasonOptions.length === 0 ? /* @__PURE__ */ jsx("div", { className: "px-3 py-4 text-sm text-slate-500", children: "No classified idle reasons found yet." }) : idleReasonOptions.map((reason) => {
|
|
37664
37815
|
const config = getRootCauseConfig(reason);
|
|
37665
37816
|
return /* @__PURE__ */ jsxs(
|
|
37666
37817
|
"button",
|
|
@@ -49225,7 +49376,7 @@ var SideNavBar = memo$1(({
|
|
|
49225
49376
|
if (hasClipsCostData) {
|
|
49226
49377
|
items.push({
|
|
49227
49378
|
key: "clips-analysis",
|
|
49228
|
-
label: "
|
|
49379
|
+
label: "Billing",
|
|
49229
49380
|
icon: CurrencyDollarIcon,
|
|
49230
49381
|
onClick: () => {
|
|
49231
49382
|
handleClipsCostClick();
|
|
@@ -61508,25 +61659,39 @@ var ProfileView = () => {
|
|
|
61508
61659
|
var ProfileView_default = ProfileView;
|
|
61509
61660
|
var REFRESH_INTERVAL_MS = 30 * 1e3;
|
|
61510
61661
|
var ClipsCostView = () => {
|
|
61511
|
-
const { data, isLoading,
|
|
61662
|
+
const { data, isLoading, error, refetch } = useCompanyClipsCost();
|
|
61512
61663
|
const navigation = useNavigation();
|
|
61664
|
+
const refetchRef = useRef(refetch);
|
|
61665
|
+
useEffect(() => {
|
|
61666
|
+
refetchRef.current = refetch;
|
|
61667
|
+
}, [refetch]);
|
|
61513
61668
|
useEffect(() => {
|
|
61514
61669
|
const intervalId = setInterval(() => {
|
|
61515
|
-
|
|
61670
|
+
void refetchRef.current();
|
|
61516
61671
|
}, REFRESH_INTERVAL_MS);
|
|
61517
61672
|
return () => clearInterval(intervalId);
|
|
61518
|
-
}, [
|
|
61673
|
+
}, []);
|
|
61519
61674
|
const mobileMenuContext = useMobileMenu();
|
|
61520
61675
|
useHideMobileHeader(!!mobileMenuContext);
|
|
61521
61676
|
const formatNumber = (num) => {
|
|
61522
61677
|
return new Intl.NumberFormat("en-US").format(num);
|
|
61523
61678
|
};
|
|
61679
|
+
const formatMonthLabel = (monthStart) => {
|
|
61680
|
+
if (!monthStart) {
|
|
61681
|
+
return "Current Month";
|
|
61682
|
+
}
|
|
61683
|
+
const parsed = /* @__PURE__ */ new Date(`${monthStart}T00:00:00`);
|
|
61684
|
+
if (Number.isNaN(parsed.getTime())) {
|
|
61685
|
+
return "Current Month";
|
|
61686
|
+
}
|
|
61687
|
+
return new Intl.DateTimeFormat("en-US", { month: "long", year: "numeric" }).format(parsed);
|
|
61688
|
+
};
|
|
61524
61689
|
if (isLoading) {
|
|
61525
|
-
return /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "lg" }) });
|
|
61690
|
+
return /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center min-h-screen bg-gray-50", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "lg", message: "Loading usage data..." }) });
|
|
61526
61691
|
}
|
|
61527
61692
|
return /* @__PURE__ */ jsxs("div", { className: "min-h-screen bg-gray-50 flex flex-col", children: [
|
|
61528
|
-
/* @__PURE__ */ jsx("header", { className: "sticky top-0 z-10 bg-white border-b flex-shrink-0", children: /* @__PURE__ */ jsxs("div", { className: "px-3 sm:px-
|
|
61529
|
-
/* @__PURE__ */
|
|
61693
|
+
/* @__PURE__ */ jsx("header", { className: "sticky top-0 z-10 bg-white border-b border-gray-200 shadow-sm flex-shrink-0", children: /* @__PURE__ */ jsxs("div", { className: "px-3 sm:px-6 lg:px-8 py-3 sm:py-4 w-full", children: [
|
|
61694
|
+
/* @__PURE__ */ jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
61530
61695
|
/* @__PURE__ */ jsx("div", { className: "flex items-center", children: mobileMenuContext && /* @__PURE__ */ jsx(
|
|
61531
61696
|
HamburgerButton,
|
|
61532
61697
|
{
|
|
@@ -61534,46 +61699,57 @@ var ClipsCostView = () => {
|
|
|
61534
61699
|
className: "flex-shrink-0 -ml-1"
|
|
61535
61700
|
}
|
|
61536
61701
|
) }),
|
|
61537
|
-
/* @__PURE__ */
|
|
61538
|
-
|
|
61539
|
-
|
|
61540
|
-
|
|
61541
|
-
|
|
61542
|
-
|
|
61702
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col items-center justify-center", children: [
|
|
61703
|
+
/* @__PURE__ */ jsx("h1", { className: "text-lg font-semibold text-gray-900", children: "Billing" }),
|
|
61704
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500", children: "Track your usage based features spend" })
|
|
61705
|
+
] }),
|
|
61706
|
+
/* @__PURE__ */ jsx("div", { className: "w-9" })
|
|
61707
|
+
] }) }),
|
|
61708
|
+
/* @__PURE__ */ jsx("div", { className: "hidden sm:block", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
61709
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-4 min-w-[120px]", children: /* @__PURE__ */ jsx(
|
|
61543
61710
|
BackButtonMinimal,
|
|
61544
61711
|
{
|
|
61545
61712
|
onClick: () => navigation.goToDashboard(),
|
|
61546
61713
|
text: "Back",
|
|
61547
61714
|
size: "default",
|
|
61548
|
-
|
|
61715
|
+
"aria-label": "Navigate back to dashboard"
|
|
61549
61716
|
}
|
|
61550
61717
|
) }),
|
|
61551
|
-
/* @__PURE__ */
|
|
61552
|
-
|
|
61553
|
-
|
|
61718
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col items-center", children: [
|
|
61719
|
+
/* @__PURE__ */ jsx("h1", { className: "text-2xl lg:text-3xl font-semibold text-gray-900 text-center", children: "Billing" }),
|
|
61720
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500 mt-1 text-center", children: "Track your usage based features spend" })
|
|
61721
|
+
] }),
|
|
61722
|
+
/* @__PURE__ */ jsx("div", { className: "min-w-[120px]" })
|
|
61554
61723
|
] }) })
|
|
61555
61724
|
] }) }),
|
|
61556
|
-
/* @__PURE__ */
|
|
61557
|
-
|
|
61558
|
-
|
|
61559
|
-
/* @__PURE__ */ jsx(
|
|
61560
|
-
/* @__PURE__ */ jsx("
|
|
61561
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500", children: "Clip analysis data will appear here once clips have been analyzed." })
|
|
61562
|
-
] }) : /* @__PURE__ */ jsxs("div", { className: "bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden", children: [
|
|
61563
|
-
/* @__PURE__ */ jsx("div", { className: "p-6 border-b border-gray-100", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
61564
|
-
/* @__PURE__ */ jsx("div", { className: "p-2 bg-blue-50 rounded-lg", children: /* @__PURE__ */ jsx(Film, { className: "h-5 w-5 text-blue-600" }) }),
|
|
61565
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
61566
|
-
/* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold text-gray-900", children: "Clips Analysis" }),
|
|
61567
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500", children: "AI-powered clip classification usage" })
|
|
61568
|
-
] })
|
|
61569
|
-
] }) }),
|
|
61570
|
-
/* @__PURE__ */ jsx("div", { className: "p-6", children: /* @__PURE__ */ jsxs("div", { className: "text-center py-4", children: [
|
|
61571
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-gray-500 mb-2", children: "Total Clips Analyzed" }),
|
|
61572
|
-
/* @__PURE__ */ jsx("p", { className: "text-4xl font-bold text-gray-900", children: formatNumber(data?.totalClassifications || 0) }),
|
|
61573
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500 mt-2", children: "clips processed through AI classification" })
|
|
61574
|
-
] }) })
|
|
61725
|
+
/* @__PURE__ */ jsx("main", { className: "flex-1 p-4 sm:p-6 lg:p-8 max-w-7xl mx-auto w-full", children: error ? /* @__PURE__ */ jsxs("div", { className: "p-4 bg-red-50 border border-red-200 rounded-lg flex items-start gap-3 text-red-700 animate-in fade-in slide-in-from-top-2 max-w-2xl mx-auto", children: [
|
|
61726
|
+
/* @__PURE__ */ jsx(AlertCircle, { className: "h-5 w-5 flex-shrink-0 mt-0.5" }),
|
|
61727
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
61728
|
+
/* @__PURE__ */ jsx("h3", { className: "font-medium", children: "Error loading usage data" }),
|
|
61729
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm mt-1 text-red-600", children: error })
|
|
61575
61730
|
] })
|
|
61576
|
-
] })
|
|
61731
|
+
] }) : /* @__PURE__ */ jsxs("div", { className: "max-w-xl mt-8 animate-in fade-in slide-in-from-bottom-4 duration-500", children: [
|
|
61732
|
+
/* @__PURE__ */ jsx(Card2, { className: "overflow-hidden shadow-sm border-gray-200 bg-white", children: /* @__PURE__ */ jsx(CardContent2, { className: "p-8", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center text-center", children: [
|
|
61733
|
+
/* @__PURE__ */ jsx("div", { className: "p-3 bg-blue-50 rounded-full mb-4", children: /* @__PURE__ */ jsx(Film, { className: "h-8 w-8 text-blue-600" }) }),
|
|
61734
|
+
/* @__PURE__ */ jsx("h2", { className: "text-sm font-medium text-gray-500 uppercase tracking-wider mb-2", children: "Clips Analyzed" }),
|
|
61735
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500 mb-3", children: formatMonthLabel(data?.monthStart) }),
|
|
61736
|
+
/* @__PURE__ */ jsx("div", { className: "text-5xl font-bold text-gray-900 mb-2 tabular-nums tracking-tight", children: formatNumber(data?.monthlyClassifications || 0) })
|
|
61737
|
+
] }) }) }),
|
|
61738
|
+
/* @__PURE__ */ jsx(Card2, { className: "mt-4 overflow-hidden shadow-sm border-gray-200 bg-white", children: /* @__PURE__ */ jsxs(CardContent2, { className: "p-6", children: [
|
|
61739
|
+
/* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-gray-900 mb-3 uppercase tracking-wider", children: "Previous Months" }),
|
|
61740
|
+
(data?.historicalMonthlyClassifications?.length || 0) === 0 ? /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500", children: "No historical month usage yet." }) : /* @__PURE__ */ jsx("div", { className: "space-y-2", children: data?.historicalMonthlyClassifications.map((item) => /* @__PURE__ */ jsxs(
|
|
61741
|
+
"div",
|
|
61742
|
+
{
|
|
61743
|
+
className: "flex items-center justify-between rounded-md border border-gray-100 bg-gray-50 px-3 py-2",
|
|
61744
|
+
children: [
|
|
61745
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm text-gray-700", children: formatMonthLabel(item.monthStart) }),
|
|
61746
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-gray-900 tabular-nums", children: formatNumber(item.classifications) })
|
|
61747
|
+
]
|
|
61748
|
+
},
|
|
61749
|
+
item.monthStart
|
|
61750
|
+
)) })
|
|
61751
|
+
] }) })
|
|
61752
|
+
] }) })
|
|
61577
61753
|
] });
|
|
61578
61754
|
};
|
|
61579
61755
|
var ClipsCostView_default = ClipsCostView;
|
|
@@ -64855,6 +65031,7 @@ var WorkspaceDetailView = ({
|
|
|
64855
65031
|
}, [monthlyData, range]);
|
|
64856
65032
|
const formattedWorkspaceName = displayName || formatWorkspaceName3(workspace?.workspace_name || "", effectiveLineId);
|
|
64857
65033
|
const shouldShowCycleTimeChart = !isUptimeMode && (showCycleTimeChart ?? formattedWorkspaceName.startsWith("FINAL ASSY"));
|
|
65034
|
+
const showIdleBreakdownChart = !shouldShowCycleTimeChart && idleTimeVlmEnabled;
|
|
64858
65035
|
const idleClipDate = date || workspace?.date || calculatedOperationalDate || getOperationalDate(timezone);
|
|
64859
65036
|
const idleClipShiftId = parsedShiftId ?? workspace?.shift_id;
|
|
64860
65037
|
const shiftDurationMinutes = useMemo(
|
|
@@ -65458,107 +65635,123 @@ var WorkspaceDetailView = ({
|
|
|
65458
65635
|
] }) : /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(WorkspaceMetricCards, { workspace, legend: efficiencyLegend, className: "flex-1" }) })
|
|
65459
65636
|
] }),
|
|
65460
65637
|
/* @__PURE__ */ jsxs("div", { className: "hidden lg:flex lg:flex-col lg:h-full lg:min-h-0 gap-3", children: [
|
|
65461
|
-
/* @__PURE__ */ jsxs(
|
|
65462
|
-
|
|
65463
|
-
|
|
65464
|
-
|
|
65465
|
-
|
|
65466
|
-
|
|
65467
|
-
|
|
65468
|
-
|
|
65469
|
-
|
|
65470
|
-
|
|
65471
|
-
|
|
65472
|
-
|
|
65473
|
-
|
|
65474
|
-
|
|
65475
|
-
|
|
65476
|
-
|
|
65477
|
-
|
|
65478
|
-
|
|
65479
|
-
|
|
65480
|
-
|
|
65481
|
-
|
|
65482
|
-
|
|
65483
|
-
|
|
65484
|
-
|
|
65485
|
-
|
|
65486
|
-
|
|
65487
|
-
|
|
65488
|
-
|
|
65489
|
-
|
|
65490
|
-
|
|
65491
|
-
|
|
65492
|
-
|
|
65493
|
-
|
|
65494
|
-
|
|
65495
|
-
|
|
65496
|
-
|
|
65497
|
-
|
|
65498
|
-
|
|
65499
|
-
|
|
65500
|
-
|
|
65501
|
-
|
|
65502
|
-
|
|
65503
|
-
|
|
65504
|
-
|
|
65505
|
-
|
|
65506
|
-
|
|
65507
|
-
|
|
65508
|
-
|
|
65509
|
-
|
|
65510
|
-
|
|
65511
|
-
|
|
65512
|
-
|
|
65513
|
-
|
|
65514
|
-
|
|
65515
|
-
|
|
65516
|
-
|
|
65517
|
-
|
|
65518
|
-
|
|
65519
|
-
|
|
65520
|
-
|
|
65521
|
-
|
|
65522
|
-
|
|
65523
|
-
|
|
65524
|
-
|
|
65525
|
-
|
|
65526
|
-
|
|
65527
|
-
|
|
65528
|
-
|
|
65529
|
-
|
|
65530
|
-
|
|
65531
|
-
|
|
65532
|
-
|
|
65533
|
-
|
|
65534
|
-
|
|
65535
|
-
|
|
65536
|
-
|
|
65537
|
-
|
|
65538
|
-
|
|
65539
|
-
|
|
65540
|
-
|
|
65541
|
-
|
|
65542
|
-
|
|
65543
|
-
|
|
65544
|
-
|
|
65545
|
-
|
|
65546
|
-
|
|
65547
|
-
|
|
65548
|
-
|
|
65549
|
-
|
|
65550
|
-
|
|
65551
|
-
|
|
65552
|
-
|
|
65553
|
-
|
|
65554
|
-
|
|
65555
|
-
|
|
65556
|
-
|
|
65557
|
-
|
|
65558
|
-
|
|
65559
|
-
|
|
65560
|
-
|
|
65561
|
-
|
|
65638
|
+
/* @__PURE__ */ jsxs(
|
|
65639
|
+
"div",
|
|
65640
|
+
{
|
|
65641
|
+
className: clsx(
|
|
65642
|
+
"grid grid-cols-1 gap-3 min-h-0",
|
|
65643
|
+
isUptimeMode && showIdleBreakdownChart ? "lg:grid-cols-3" : "lg:grid-cols-10",
|
|
65644
|
+
desktopTopSectionClass
|
|
65645
|
+
),
|
|
65646
|
+
children: [
|
|
65647
|
+
!shouldShowCycleTimeChart && !isUptimeMode && /* @__PURE__ */ jsxs(
|
|
65648
|
+
motion.div,
|
|
65649
|
+
{
|
|
65650
|
+
className: "bg-white rounded-lg shadow-sm p-4 lg:col-span-2 flex flex-col min-h-0",
|
|
65651
|
+
variants: chartCardVariants,
|
|
65652
|
+
initial: "initial",
|
|
65653
|
+
animate: "animate",
|
|
65654
|
+
children: [
|
|
65655
|
+
/* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-gray-700 mb-4 text-center", children: "Today's Output" }),
|
|
65656
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 min-h-[220px] min-w-0", children: /* @__PURE__ */ jsx(
|
|
65657
|
+
OutputProgressChart,
|
|
65658
|
+
{
|
|
65659
|
+
currentOutput: workspace.total_actions || 0,
|
|
65660
|
+
targetOutput: workspace.target_output || 0
|
|
65661
|
+
}
|
|
65662
|
+
) })
|
|
65663
|
+
]
|
|
65664
|
+
}
|
|
65665
|
+
),
|
|
65666
|
+
/* @__PURE__ */ jsxs(
|
|
65667
|
+
motion.div,
|
|
65668
|
+
{
|
|
65669
|
+
className: clsx(
|
|
65670
|
+
"bg-white rounded-lg shadow-sm p-4 flex flex-col min-h-0",
|
|
65671
|
+
isUptimeMode && showIdleBreakdownChart ? "lg:col-span-2" : shouldShowCycleTimeChart || isUptimeMode ? "lg:col-span-10" : idleTimeVlmEnabled ? "lg:col-span-6" : "lg:col-span-8"
|
|
65672
|
+
),
|
|
65673
|
+
variants: chartCardVariants,
|
|
65674
|
+
initial: "initial",
|
|
65675
|
+
animate: "animate",
|
|
65676
|
+
children: [
|
|
65677
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3 mb-4 flex-none", children: [
|
|
65678
|
+
/* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-gray-700", children: isUptimeMode ? "Machine Utilization" : shouldShowCycleTimeChart ? "Cycle Time (last 60 minutes)" : "Hourly Output" }),
|
|
65679
|
+
!isUptimeMode && /* @__PURE__ */ jsx(
|
|
65680
|
+
"button",
|
|
65681
|
+
{
|
|
65682
|
+
onClick: () => setShowChartIdleTime(!showChartIdleTime),
|
|
65683
|
+
className: `inline-flex items-center px-3 py-1.5 text-sm font-medium rounded-md transition-colors ${showChartIdleTime ? "bg-blue-50 text-blue-700 border border-blue-200" : "bg-white text-gray-700 border border-gray-300 hover:bg-gray-50"}`,
|
|
65684
|
+
children: showChartIdleTime ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
65685
|
+
/* @__PURE__ */ jsx(EyeOff, { className: "w-4 h-4 mr-1.5" }),
|
|
65686
|
+
"Hide Idle Time"
|
|
65687
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
65688
|
+
/* @__PURE__ */ jsx(Eye, { className: "w-4 h-4 mr-1.5" }),
|
|
65689
|
+
"Show Idle Time"
|
|
65690
|
+
] })
|
|
65691
|
+
}
|
|
65692
|
+
)
|
|
65693
|
+
] }),
|
|
65694
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 min-h-[220px] min-w-0", children: isUptimeMode ? /* @__PURE__ */ jsx(
|
|
65695
|
+
HourlyUptimeChart,
|
|
65696
|
+
{
|
|
65697
|
+
idleTimeHourly: workspace.idle_time_hourly,
|
|
65698
|
+
shiftStart: workspace.shift_start,
|
|
65699
|
+
shiftEnd: workspace.shift_end,
|
|
65700
|
+
shiftDate: idleClipDate,
|
|
65701
|
+
timezone,
|
|
65702
|
+
elapsedMinutes: elapsedShiftMinutes
|
|
65703
|
+
}
|
|
65704
|
+
) : shouldShowCycleTimeChart ? /* @__PURE__ */ jsx(
|
|
65705
|
+
CycleTimeOverTimeChart,
|
|
65706
|
+
{
|
|
65707
|
+
data: workspace.hourly_action_counts || [],
|
|
65708
|
+
idealCycleTime: workspace.ideal_cycle_time || 0,
|
|
65709
|
+
shiftStart: workspace.shift_start || ""
|
|
65710
|
+
}
|
|
65711
|
+
) : /* @__PURE__ */ jsx(
|
|
65712
|
+
HourlyOutputChart2,
|
|
65713
|
+
{
|
|
65714
|
+
data: workspace.hourly_action_counts || [],
|
|
65715
|
+
pphThreshold: workspace.pph_threshold || 0,
|
|
65716
|
+
shiftStart: workspace.shift_start || "06:00",
|
|
65717
|
+
shiftEnd: workspace.shift_end,
|
|
65718
|
+
showIdleTime: showChartIdleTime,
|
|
65719
|
+
idleTimeHourly: workspace.idle_time_hourly,
|
|
65720
|
+
idleTimeClips,
|
|
65721
|
+
idleTimeClipClassifications,
|
|
65722
|
+
shiftDate: idleClipDate,
|
|
65723
|
+
timezone
|
|
65724
|
+
}
|
|
65725
|
+
) })
|
|
65726
|
+
]
|
|
65727
|
+
}
|
|
65728
|
+
),
|
|
65729
|
+
!shouldShowCycleTimeChart && idleTimeVlmEnabled && /* @__PURE__ */ jsxs(
|
|
65730
|
+
motion.div,
|
|
65731
|
+
{
|
|
65732
|
+
className: clsx(
|
|
65733
|
+
"bg-white rounded-lg shadow-sm p-4 flex flex-col min-h-0",
|
|
65734
|
+
isUptimeMode ? "lg:col-span-1" : "lg:col-span-2"
|
|
65735
|
+
),
|
|
65736
|
+
variants: chartCardVariants,
|
|
65737
|
+
initial: "initial",
|
|
65738
|
+
animate: "animate",
|
|
65739
|
+
children: [
|
|
65740
|
+
/* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-gray-700 mb-4 text-center", children: "Idle Time Breakdown" }),
|
|
65741
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 min-h-[220px] min-w-0", children: /* @__PURE__ */ jsx(
|
|
65742
|
+
IdleTimeReasonChart,
|
|
65743
|
+
{
|
|
65744
|
+
data: idleTimeData.chartData,
|
|
65745
|
+
isLoading: idleTimeData.isLoading,
|
|
65746
|
+
error: idleTimeData.error
|
|
65747
|
+
}
|
|
65748
|
+
) })
|
|
65749
|
+
]
|
|
65750
|
+
}
|
|
65751
|
+
)
|
|
65752
|
+
]
|
|
65753
|
+
}
|
|
65754
|
+
),
|
|
65562
65755
|
isUptimeMode ? /* @__PURE__ */ jsx("div", { className: clsx("flex min-h-0", desktopBottomSectionClass), children: /* @__PURE__ */ jsx(UptimeMetricCards, { workspace, uptimePieData, className: "flex-1" }) }) : shouldShowCycleTimeChart ? /* @__PURE__ */ jsxs("div", { className: clsx("grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3 min-h-0", desktopBottomSectionClass), children: [
|
|
65563
65756
|
/* @__PURE__ */ jsxs(Card2, { children: [
|
|
65564
65757
|
/* @__PURE__ */ jsx(CardHeader2, { className: "pb-2 flex-none", children: /* @__PURE__ */ jsx(CardTitle2, { className: "text-lg text-center", children: "Efficiency" }) }),
|