@optifye/dashboard-core 6.5.0 → 6.5.2
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 +12 -15
- package/dist/index.d.mts +8 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +174 -189
- package/dist/index.mjs +175 -190
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -13,7 +13,7 @@ import { noop, warning, invariant, progress, secondsToMilliseconds, milliseconds
|
|
|
13
13
|
import { getValueTransition, hover, press, isPrimaryPointer, GroupPlaybackControls, setDragLock, supportsLinearEasing, attachTimeline, isGenerator, calcGeneratorDuration, isWaapiSupportedEasing, mapEasingToNativeEasing, maxGeneratorDuration, generateLinearEasing, isBezierDefinition } from 'motion-dom';
|
|
14
14
|
import { BarChart as BarChart$1, CartesianGrid, XAxis, YAxis, Tooltip, Legend, Bar, LabelList, ResponsiveContainer, LineChart as LineChart$1, Line, PieChart, Pie, Cell, ReferenceLine, ComposedChart, Area, ScatterChart, Scatter } from 'recharts';
|
|
15
15
|
import { Slot } from '@radix-ui/react-slot';
|
|
16
|
-
import { Camera, ChevronDown, ChevronUp, Check, ShieldCheck, Star, Award, X, Coffee, Plus, ArrowLeft, Clock, Calendar, Save, Minus, ArrowDown, ArrowUp, Settings2, CheckCircle2, Search, Loader2, AlertCircle, Edit2, CheckCircle, AlertTriangle, Info, Share2, Trophy, Target, Download, User, XCircle, ChevronLeft, ChevronRight,
|
|
16
|
+
import { Camera, ChevronDown, ChevronUp, Check, ShieldCheck, Star, Award, X, Coffee, Plus, ArrowLeft, Clock, Calendar, Save, Minus, ArrowDown, ArrowUp, Settings2, CheckCircle2, Search, Loader2, AlertCircle, Edit2, CheckCircle, AlertTriangle, Info, Share2, Trophy, Target, Download, User, XCircle, ChevronLeft, ChevronRight, Sun, Moon, MessageSquare, Trash2, RefreshCw, Menu, Send, Copy, UserCheck, LogOut, Package, TrendingUp, TrendingDown, Activity, Settings, LifeBuoy, EyeOff, Eye, Zap, UserCircle } from 'lucide-react';
|
|
17
17
|
import { DayPicker, useNavigation as useNavigation$1 } from 'react-day-picker';
|
|
18
18
|
import { XMarkIcon, ArrowRightIcon, HomeIcon, TrophyIcon, ChartBarIcon, AdjustmentsHorizontalIcon, ClockIcon, CubeIcon, SparklesIcon, QuestionMarkCircleIcon, HeartIcon, UserCircleIcon, ExclamationCircleIcon, EnvelopeIcon, DocumentTextIcon, ChevronUpIcon, ChevronDownIcon, Bars3Icon, CheckCircleIcon, ChatBubbleLeftRightIcon, XCircleIcon, InformationCircleIcon, ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/24/outline';
|
|
19
19
|
import { CheckIcon } from '@heroicons/react/24/solid';
|
|
@@ -3256,35 +3256,6 @@ var useAudioService = () => {
|
|
|
3256
3256
|
};
|
|
3257
3257
|
|
|
3258
3258
|
// src/lib/utils/dateShiftUtils.ts
|
|
3259
|
-
function getOperationalDate2(timezone = "Asia/Kolkata") {
|
|
3260
|
-
const now2 = /* @__PURE__ */ new Date();
|
|
3261
|
-
const localTime = new Date(now2.toLocaleString("en-US", { timeZone: timezone }));
|
|
3262
|
-
const hour = localTime.getHours();
|
|
3263
|
-
if (hour < 6) {
|
|
3264
|
-
localTime.setDate(localTime.getDate() - 1);
|
|
3265
|
-
}
|
|
3266
|
-
return localTime.toISOString().split("T")[0];
|
|
3267
|
-
}
|
|
3268
|
-
function getCurrentShift2(timezone = "Asia/Kolkata") {
|
|
3269
|
-
const now2 = /* @__PURE__ */ new Date();
|
|
3270
|
-
const localTime = new Date(now2.toLocaleString("en-US", { timeZone: timezone }));
|
|
3271
|
-
const hour = localTime.getHours();
|
|
3272
|
-
if (hour >= 6 && hour < 18) {
|
|
3273
|
-
return {
|
|
3274
|
-
shiftId: 0,
|
|
3275
|
-
shiftName: "Day Shift",
|
|
3276
|
-
startTime: "06:00",
|
|
3277
|
-
endTime: "18:00"
|
|
3278
|
-
};
|
|
3279
|
-
} else {
|
|
3280
|
-
return {
|
|
3281
|
-
shiftId: 1,
|
|
3282
|
-
shiftName: "Night Shift",
|
|
3283
|
-
startTime: "18:00",
|
|
3284
|
-
endTime: "06:00"
|
|
3285
|
-
};
|
|
3286
|
-
}
|
|
3287
|
-
}
|
|
3288
3259
|
function isValidDateFormat(date) {
|
|
3289
3260
|
return /^\d{4}-\d{2}-\d{2}$/.test(date);
|
|
3290
3261
|
}
|
|
@@ -4151,6 +4122,23 @@ var S3ClipsAPIClient = class {
|
|
|
4151
4122
|
};
|
|
4152
4123
|
});
|
|
4153
4124
|
}
|
|
4125
|
+
/**
|
|
4126
|
+
* Batch fetch multiple videos in parallel
|
|
4127
|
+
*/
|
|
4128
|
+
async batchFetchVideos(workspaceId, date, shiftId, requests) {
|
|
4129
|
+
const batchKey = `batch:${workspaceId}:${date}:${shiftId}:${requests.length}`;
|
|
4130
|
+
return this.deduplicate(batchKey, async () => {
|
|
4131
|
+
const response = await this.fetchWithAuth("/api/clips/batch", {
|
|
4132
|
+
workspaceId,
|
|
4133
|
+
date,
|
|
4134
|
+
shift: shiftId.toString(),
|
|
4135
|
+
requests,
|
|
4136
|
+
sopCategories: this.sopCategories
|
|
4137
|
+
});
|
|
4138
|
+
console.log(`[S3ClipsAPIClient] Batch fetched ${response.videos.length} videos in ${response.performance.duration}ms`);
|
|
4139
|
+
return response.videos;
|
|
4140
|
+
});
|
|
4141
|
+
}
|
|
4154
4142
|
/**
|
|
4155
4143
|
* Convert S3 URI to CloudFront URL
|
|
4156
4144
|
* In the API client, URLs are already signed from the server
|
|
@@ -4398,7 +4386,11 @@ var S3ClipsService = class {
|
|
|
4398
4386
|
if (!workspaceId) {
|
|
4399
4387
|
throw new Error("Valid Workspace ID is required");
|
|
4400
4388
|
}
|
|
4401
|
-
const date = inputDate ||
|
|
4389
|
+
const date = inputDate || getOperationalDate(
|
|
4390
|
+
this.config.dateTimeConfig?.defaultTimezone || "Asia/Kolkata",
|
|
4391
|
+
/* @__PURE__ */ new Date(),
|
|
4392
|
+
this.config.shiftConfig?.dayShift?.startTime || "06:00"
|
|
4393
|
+
);
|
|
4402
4394
|
if (!isValidDateFormat(date)) {
|
|
4403
4395
|
throw new Error("Invalid date format. Use YYYY-MM-DD.");
|
|
4404
4396
|
}
|
|
@@ -4409,7 +4401,10 @@ var S3ClipsService = class {
|
|
|
4409
4401
|
}
|
|
4410
4402
|
shiftId = parseInt(shift, 10);
|
|
4411
4403
|
} else {
|
|
4412
|
-
const { shiftId: currentShiftId } =
|
|
4404
|
+
const { shiftId: currentShiftId } = getCurrentShift(
|
|
4405
|
+
this.config.dateTimeConfig?.defaultTimezone || "Asia/Kolkata",
|
|
4406
|
+
this.config.shiftConfig
|
|
4407
|
+
);
|
|
4413
4408
|
shiftId = currentShiftId;
|
|
4414
4409
|
}
|
|
4415
4410
|
console.log(`[S3ClipsService] Fetching clips for workspace ${workspaceId}`);
|
|
@@ -4427,6 +4422,23 @@ var S3ClipsService = class {
|
|
|
4427
4422
|
);
|
|
4428
4423
|
return result.videos;
|
|
4429
4424
|
}
|
|
4425
|
+
/**
|
|
4426
|
+
* Batch fetch multiple videos in parallel
|
|
4427
|
+
*/
|
|
4428
|
+
async batchFetchVideos(workspaceId, date, shiftId, requests) {
|
|
4429
|
+
try {
|
|
4430
|
+
const results = await this.apiClient.batchFetchVideos(
|
|
4431
|
+
workspaceId,
|
|
4432
|
+
date,
|
|
4433
|
+
shiftId,
|
|
4434
|
+
requests
|
|
4435
|
+
);
|
|
4436
|
+
return results.map((r2) => r2.video).filter((v) => v !== null);
|
|
4437
|
+
} catch (error) {
|
|
4438
|
+
console.error("[S3ClipsService] Error batch fetching videos:", error);
|
|
4439
|
+
return [];
|
|
4440
|
+
}
|
|
4441
|
+
}
|
|
4430
4442
|
/**
|
|
4431
4443
|
* Get videos page using pagination API
|
|
4432
4444
|
*/
|
|
@@ -8049,7 +8061,7 @@ var useActiveBreaks = (lineIds) => {
|
|
|
8049
8061
|
}
|
|
8050
8062
|
return { elapsedMinutes, remainingMinutes };
|
|
8051
8063
|
};
|
|
8052
|
-
const
|
|
8064
|
+
const getCurrentShift2 = (currentMinutes, dayStart, nightStart) => {
|
|
8053
8065
|
const dayStartMinutes = parseTimeToMinutes2(dayStart);
|
|
8054
8066
|
const nightStartMinutes = parseTimeToMinutes2(nightStart);
|
|
8055
8067
|
if (nightStartMinutes < dayStartMinutes) {
|
|
@@ -8081,7 +8093,7 @@ var useActiveBreaks = (lineIds) => {
|
|
|
8081
8093
|
const dayShift = dayShifts?.find((s) => s.line_id === lineId);
|
|
8082
8094
|
const nightShift = nightShifts?.find((s) => s.line_id === lineId);
|
|
8083
8095
|
if (!dayShift || !nightShift) continue;
|
|
8084
|
-
const currentShift =
|
|
8096
|
+
const currentShift = getCurrentShift2(
|
|
8085
8097
|
currentMinutes,
|
|
8086
8098
|
dayShift.start_time || "06:00",
|
|
8087
8099
|
nightShift.start_time || "18:00"
|
|
@@ -11578,9 +11590,12 @@ var usePrefetchClipCounts = ({
|
|
|
11578
11590
|
shiftStr = "0";
|
|
11579
11591
|
console.log(`[usePrefetchClipCounts] No shift provided for historical date ${date}, defaulting to day shift (0)`);
|
|
11580
11592
|
} else {
|
|
11581
|
-
const currentShift =
|
|
11593
|
+
const currentShift = getCurrentShift(
|
|
11594
|
+
dashboardConfig.dateTimeConfig?.defaultTimezone || "Asia/Kolkata",
|
|
11595
|
+
dashboardConfig.shiftConfig
|
|
11596
|
+
);
|
|
11582
11597
|
shiftStr = currentShift.shiftId.toString();
|
|
11583
|
-
console.log(`[usePrefetchClipCounts] Using current operational shift: ${shiftStr}
|
|
11598
|
+
console.log(`[usePrefetchClipCounts] Using current operational shift: ${shiftStr}`);
|
|
11584
11599
|
}
|
|
11585
11600
|
return {
|
|
11586
11601
|
workspaceId: workspaceId || "",
|
|
@@ -26917,11 +26932,14 @@ var BottlenecksContent = ({
|
|
|
26917
26932
|
console.log(`[BottlenecksContent] No shift provided for historical date ${date}, defaulting to day shift (0)`);
|
|
26918
26933
|
return "0";
|
|
26919
26934
|
} else {
|
|
26920
|
-
const currentShift =
|
|
26921
|
-
|
|
26935
|
+
const currentShift = getCurrentShift(
|
|
26936
|
+
dashboardConfig.dateTimeConfig?.defaultTimezone || "Asia/Kolkata",
|
|
26937
|
+
dashboardConfig.shiftConfig
|
|
26938
|
+
);
|
|
26939
|
+
console.log(`[BottlenecksContent] Using current operational shift: ${currentShift.shiftId}`);
|
|
26922
26940
|
return currentShift.shiftId.toString();
|
|
26923
26941
|
}
|
|
26924
|
-
}, [shift, date]);
|
|
26942
|
+
}, [shift, date, dashboardConfig]);
|
|
26925
26943
|
const {
|
|
26926
26944
|
data: prefetchData,
|
|
26927
26945
|
isFullyIndexed,
|
|
@@ -27010,44 +27028,73 @@ var BottlenecksContent = ({
|
|
|
27010
27028
|
if (indicesToLoad.length === 0) return;
|
|
27011
27029
|
console.log(`[ensureVideosLoaded] Preloading ${indicesToLoad.length} videos around index ${centerIndex}: [${indicesToLoad.join(", ")}]`);
|
|
27012
27030
|
indicesToLoad.forEach((idx) => loadingVideosRef.current.add(idx));
|
|
27013
|
-
const
|
|
27014
|
-
|
|
27015
|
-
|
|
27016
|
-
|
|
27017
|
-
|
|
27018
|
-
|
|
27019
|
-
|
|
27031
|
+
const operationalDate = date || getOperationalDate();
|
|
27032
|
+
const shiftStr = effectiveShift;
|
|
27033
|
+
console.log(`[ensureVideosLoaded] Batch fetching ${indicesToLoad.length} videos in parallel`);
|
|
27034
|
+
try {
|
|
27035
|
+
const batchRequests = indicesToLoad.map((index) => ({
|
|
27036
|
+
category: effectiveFilter,
|
|
27037
|
+
index,
|
|
27038
|
+
includeMetadata: false
|
|
27039
|
+
// No metadata during bulk preloading
|
|
27040
|
+
}));
|
|
27041
|
+
const videos = await s3ClipsService.batchFetchVideos(
|
|
27042
|
+
workspaceId,
|
|
27043
|
+
operationalDate,
|
|
27044
|
+
shiftStr,
|
|
27045
|
+
batchRequests
|
|
27046
|
+
);
|
|
27047
|
+
if (videos.length > 0 && isMountedRef.current) {
|
|
27048
|
+
videos.forEach((video, idx) => {
|
|
27049
|
+
if (video) {
|
|
27050
|
+
setAllVideos((prev) => {
|
|
27051
|
+
const exists = prev.some((v) => v.id === video.id);
|
|
27052
|
+
if (!exists) {
|
|
27053
|
+
return [...prev, video];
|
|
27054
|
+
}
|
|
27055
|
+
return prev;
|
|
27056
|
+
});
|
|
27057
|
+
const originalIndex = indicesToLoad[idx];
|
|
27058
|
+
loadedIndices.add(originalIndex);
|
|
27059
|
+
preloadVideoUrl(video.src);
|
|
27060
|
+
}
|
|
27061
|
+
});
|
|
27062
|
+
console.log(`[ensureVideosLoaded] Successfully loaded ${videos.length} videos in batch`);
|
|
27063
|
+
}
|
|
27064
|
+
} catch (error2) {
|
|
27065
|
+
console.error("[ensureVideosLoaded] Batch fetch failed:", error2);
|
|
27066
|
+
const loadPromises = indicesToLoad.map(async (index) => {
|
|
27067
|
+
try {
|
|
27068
|
+
const video = await s3ClipsService.getClipByIndex(
|
|
27020
27069
|
workspaceId,
|
|
27021
27070
|
operationalDate,
|
|
27022
27071
|
shiftStr,
|
|
27023
27072
|
effectiveFilter,
|
|
27024
27073
|
index,
|
|
27025
27074
|
true,
|
|
27026
|
-
// includeCycleTime
|
|
27075
|
+
// includeCycleTime
|
|
27027
27076
|
false
|
|
27028
|
-
// includeMetadata
|
|
27077
|
+
// includeMetadata
|
|
27029
27078
|
);
|
|
27079
|
+
if (video && isMountedRef.current) {
|
|
27080
|
+
setAllVideos((prev) => {
|
|
27081
|
+
const exists = prev.some((v) => v.id === video.id);
|
|
27082
|
+
if (!exists) {
|
|
27083
|
+
return [...prev, video];
|
|
27084
|
+
}
|
|
27085
|
+
return prev;
|
|
27086
|
+
});
|
|
27087
|
+
loadedIndices.add(index);
|
|
27088
|
+
preloadVideoUrl(video.src);
|
|
27089
|
+
}
|
|
27090
|
+
} catch (err) {
|
|
27091
|
+
console.warn(`[ensureVideosLoaded] Failed to load video at index ${index}:`, err);
|
|
27030
27092
|
}
|
|
27031
|
-
|
|
27032
|
-
|
|
27033
|
-
|
|
27034
|
-
|
|
27035
|
-
|
|
27036
|
-
}
|
|
27037
|
-
return prev;
|
|
27038
|
-
});
|
|
27039
|
-
loadedIndices.add(index);
|
|
27040
|
-
preloadVideoUrl(video.src);
|
|
27041
|
-
}
|
|
27042
|
-
} catch (error2) {
|
|
27043
|
-
console.warn(`[ensureVideosLoaded] Failed to load video at index ${index}:`, error2);
|
|
27044
|
-
} finally {
|
|
27045
|
-
loadingVideosRef.current.delete(index);
|
|
27046
|
-
}
|
|
27047
|
-
});
|
|
27048
|
-
Promise.all(loadPromises).catch((err) => {
|
|
27049
|
-
console.warn("[ensureVideosLoaded] Some videos failed to preload:", err);
|
|
27050
|
-
});
|
|
27093
|
+
});
|
|
27094
|
+
await Promise.all(loadPromises);
|
|
27095
|
+
} finally {
|
|
27096
|
+
indicesToLoad.forEach((idx) => loadingVideosRef.current.delete(idx));
|
|
27097
|
+
}
|
|
27051
27098
|
}, [s3ClipsService, workspaceId, clipCounts, sopCategories, date, effectiveShift]);
|
|
27052
27099
|
const loadFirstVideoForCategory = useCallback(async (category) => {
|
|
27053
27100
|
if (!workspaceId || !s3ClipsService || !isMountedRef.current) return;
|
|
@@ -28633,7 +28680,6 @@ var WorkspaceHealthCard = ({
|
|
|
28633
28680
|
};
|
|
28634
28681
|
const config = getStatusConfig();
|
|
28635
28682
|
const StatusIcon = config.icon;
|
|
28636
|
-
workspace.isStale ? WifiOff : Wifi;
|
|
28637
28683
|
const handleClick = () => {
|
|
28638
28684
|
if (onClick) {
|
|
28639
28685
|
onClick(workspace);
|
|
@@ -28681,34 +28727,13 @@ var WorkspaceHealthCard = ({
|
|
|
28681
28727
|
/* @__PURE__ */ jsx("span", { children: config.statusText })
|
|
28682
28728
|
] })
|
|
28683
28729
|
] }),
|
|
28684
|
-
/* @__PURE__ */
|
|
28685
|
-
/* @__PURE__ */
|
|
28686
|
-
|
|
28687
|
-
|
|
28688
|
-
|
|
28689
|
-
"Last seen: ",
|
|
28690
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium", children: formatTimeAgo(workspace.timeSinceLastUpdate) })
|
|
28691
|
-
] })
|
|
28692
|
-
] }),
|
|
28693
|
-
workspace.isStale && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
28694
|
-
/* @__PURE__ */ jsx(WifiOff, { className: "h-3.5 w-3.5 text-amber-500" }),
|
|
28695
|
-
/* @__PURE__ */ jsx("span", { className: "text-amber-600 dark:text-amber-400 text-xs", children: "No recent updates" })
|
|
28696
|
-
] })
|
|
28697
|
-
] }),
|
|
28698
|
-
config.pulse && !workspace.isStale && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
28699
|
-
/* @__PURE__ */ jsxs("div", { className: "relative flex h-2 w-2", children: [
|
|
28700
|
-
/* @__PURE__ */ jsx("span", { className: clsx(
|
|
28701
|
-
"animate-ping absolute inline-flex h-full w-full rounded-full opacity-75",
|
|
28702
|
-
workspace.status === "healthy" ? "bg-emerald-400" : "bg-amber-400"
|
|
28703
|
-
) }),
|
|
28704
|
-
/* @__PURE__ */ jsx("span", { className: clsx(
|
|
28705
|
-
"relative inline-flex rounded-full h-2 w-2",
|
|
28706
|
-
workspace.status === "healthy" ? "bg-emerald-500" : "bg-amber-500"
|
|
28707
|
-
) })
|
|
28708
|
-
] }),
|
|
28709
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs text-gray-500 dark:text-gray-400", children: "Live" })
|
|
28730
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-1", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
28731
|
+
/* @__PURE__ */ jsx(Clock, { className: "h-3.5 w-3.5 text-gray-400" }),
|
|
28732
|
+
/* @__PURE__ */ jsxs("span", { className: "text-sm text-gray-600 dark:text-gray-400 whitespace-nowrap", children: [
|
|
28733
|
+
"Last seen: ",
|
|
28734
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: formatTimeAgo(workspace.timeSinceLastUpdate) })
|
|
28710
28735
|
] })
|
|
28711
|
-
] })
|
|
28736
|
+
] }) }) })
|
|
28712
28737
|
] })
|
|
28713
28738
|
}
|
|
28714
28739
|
);
|
|
@@ -28789,16 +28814,16 @@ var CompactWorkspaceHealthCard = ({
|
|
|
28789
28814
|
var HealthStatusGrid = ({
|
|
28790
28815
|
workspaces,
|
|
28791
28816
|
onWorkspaceClick,
|
|
28792
|
-
viewMode: initialViewMode = "grid",
|
|
28793
28817
|
showFilters = true,
|
|
28794
28818
|
groupBy: initialGroupBy = "none",
|
|
28795
28819
|
className = ""
|
|
28796
28820
|
}) => {
|
|
28797
|
-
const [viewMode, setViewMode] = useState(initialViewMode);
|
|
28798
28821
|
const [searchTerm, setSearchTerm] = useState("");
|
|
28799
28822
|
const [statusFilter, setStatusFilter] = useState("all");
|
|
28800
28823
|
const [groupBy, setGroupBy] = useState(initialGroupBy);
|
|
28801
28824
|
const [expandedGroups, setExpandedGroups] = useState(/* @__PURE__ */ new Set());
|
|
28825
|
+
const lastGroupByRef = useRef(initialGroupBy);
|
|
28826
|
+
const hasInitializedGroupsRef = useRef(false);
|
|
28802
28827
|
const filteredWorkspaces = useMemo(() => {
|
|
28803
28828
|
let filtered = [...workspaces];
|
|
28804
28829
|
if (searchTerm) {
|
|
@@ -28839,7 +28864,17 @@ var HealthStatusGrid = ({
|
|
|
28839
28864
|
return sortedGroups;
|
|
28840
28865
|
}, [filteredWorkspaces, groupBy]);
|
|
28841
28866
|
useEffect(() => {
|
|
28842
|
-
if (groupBy !==
|
|
28867
|
+
if (groupBy !== lastGroupByRef.current) {
|
|
28868
|
+
lastGroupByRef.current = groupBy;
|
|
28869
|
+
hasInitializedGroupsRef.current = false;
|
|
28870
|
+
if (groupBy === "none") {
|
|
28871
|
+
setExpandedGroups(/* @__PURE__ */ new Set());
|
|
28872
|
+
}
|
|
28873
|
+
}
|
|
28874
|
+
}, [groupBy]);
|
|
28875
|
+
useEffect(() => {
|
|
28876
|
+
if (groupBy !== "none" && !hasInitializedGroupsRef.current && Object.keys(groupedWorkspaces).length > 0) {
|
|
28877
|
+
hasInitializedGroupsRef.current = true;
|
|
28843
28878
|
setExpandedGroups(new Set(Object.keys(groupedWorkspaces)));
|
|
28844
28879
|
}
|
|
28845
28880
|
}, [groupBy, groupedWorkspaces]);
|
|
@@ -28883,13 +28918,13 @@ var HealthStatusGrid = ({
|
|
|
28883
28918
|
] }) }),
|
|
28884
28919
|
/* @__PURE__ */ jsxs(Select, { value: statusFilter, onValueChange: (value) => setStatusFilter(value), children: [
|
|
28885
28920
|
/* @__PURE__ */ jsx(SelectTrigger, { className: "w-full sm:w-[180px] bg-white border-gray-200", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "All statuses" }) }),
|
|
28886
|
-
/* @__PURE__ */ jsxs(SelectContent, { children: [
|
|
28887
|
-
/* @__PURE__ */ jsxs(SelectItem, { value: "all", children: [
|
|
28921
|
+
/* @__PURE__ */ jsxs(SelectContent, { className: "bg-white border border-gray-200 shadow-lg", children: [
|
|
28922
|
+
/* @__PURE__ */ jsxs(SelectItem, { value: "all", className: "text-gray-700 hover:bg-gray-50 focus:bg-gray-50 border-b border-gray-100 last:border-b-0", children: [
|
|
28888
28923
|
"All (",
|
|
28889
28924
|
workspaces.length,
|
|
28890
28925
|
")"
|
|
28891
28926
|
] }),
|
|
28892
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "healthy", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
28927
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "healthy", className: "text-gray-700 hover:bg-gray-50 focus:bg-gray-50 border-b border-gray-100 last:border-b-0", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
28893
28928
|
/* @__PURE__ */ jsx("div", { className: "h-2 w-2 rounded-full bg-green-500" }),
|
|
28894
28929
|
/* @__PURE__ */ jsxs("span", { children: [
|
|
28895
28930
|
"Healthy (",
|
|
@@ -28897,7 +28932,7 @@ var HealthStatusGrid = ({
|
|
|
28897
28932
|
")"
|
|
28898
28933
|
] })
|
|
28899
28934
|
] }) }),
|
|
28900
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "unhealthy", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
28935
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "unhealthy", className: "text-gray-700 hover:bg-gray-50 focus:bg-gray-50 border-b border-gray-100 last:border-b-0", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
28901
28936
|
/* @__PURE__ */ jsx("div", { className: "h-2 w-2 rounded-full bg-red-500" }),
|
|
28902
28937
|
/* @__PURE__ */ jsxs("span", { children: [
|
|
28903
28938
|
"Unhealthy (",
|
|
@@ -28905,57 +28940,23 @@ var HealthStatusGrid = ({
|
|
|
28905
28940
|
")"
|
|
28906
28941
|
] })
|
|
28907
28942
|
] }) }),
|
|
28908
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "warning", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
28943
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "warning", className: "text-gray-700 hover:bg-gray-50 focus:bg-gray-50 border-b border-gray-100 last:border-b-0", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
28909
28944
|
/* @__PURE__ */ jsx("div", { className: "h-2 w-2 rounded-full bg-yellow-500" }),
|
|
28910
28945
|
/* @__PURE__ */ jsxs("span", { children: [
|
|
28911
28946
|
"Warning (",
|
|
28912
28947
|
statusCounts.warning,
|
|
28913
28948
|
")"
|
|
28914
28949
|
] })
|
|
28915
|
-
] }) }),
|
|
28916
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "unknown", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
28917
|
-
/* @__PURE__ */ jsx("div", { className: "h-2 w-2 rounded-full bg-gray-400" }),
|
|
28918
|
-
/* @__PURE__ */ jsxs("span", { children: [
|
|
28919
|
-
"Unknown (",
|
|
28920
|
-
statusCounts.unknown,
|
|
28921
|
-
")"
|
|
28922
|
-
] })
|
|
28923
28950
|
] }) })
|
|
28924
28951
|
] })
|
|
28925
28952
|
] }),
|
|
28926
28953
|
/* @__PURE__ */ jsxs(Select, { value: groupBy, onValueChange: (value) => setGroupBy(value), children: [
|
|
28927
28954
|
/* @__PURE__ */ jsx(SelectTrigger, { className: "w-full sm:w-[160px] bg-white border-gray-200", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Group by" }) }),
|
|
28928
|
-
/* @__PURE__ */ jsxs(SelectContent, { children: [
|
|
28929
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "none", children: "No grouping" }),
|
|
28930
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "line", children: "Group by Line" }),
|
|
28931
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "status", children: "Group by Status" })
|
|
28955
|
+
/* @__PURE__ */ jsxs(SelectContent, { className: "bg-white border border-gray-200 shadow-lg", children: [
|
|
28956
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "none", className: "text-gray-700 hover:bg-gray-50 focus:bg-gray-50 border-b border-gray-100 last:border-b-0", children: "No grouping" }),
|
|
28957
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "line", className: "text-gray-700 hover:bg-gray-50 focus:bg-gray-50 border-b border-gray-100 last:border-b-0", children: "Group by Line" }),
|
|
28958
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "status", className: "text-gray-700 hover:bg-gray-50 focus:bg-gray-50 border-b border-gray-100 last:border-b-0", children: "Group by Status" })
|
|
28932
28959
|
] })
|
|
28933
|
-
] }),
|
|
28934
|
-
/* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
28935
|
-
/* @__PURE__ */ jsx(
|
|
28936
|
-
"button",
|
|
28937
|
-
{
|
|
28938
|
-
onClick: () => setViewMode("grid"),
|
|
28939
|
-
className: clsx(
|
|
28940
|
-
"p-2 rounded-lg transition-colors",
|
|
28941
|
-
viewMode === "grid" ? "bg-blue-100 dark:bg-blue-900/30 text-blue-600 dark:text-blue-400" : "text-gray-600 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700"
|
|
28942
|
-
),
|
|
28943
|
-
"aria-label": "Grid view",
|
|
28944
|
-
children: /* @__PURE__ */ jsx(Grid3x3, { className: "h-5 w-5" })
|
|
28945
|
-
}
|
|
28946
|
-
),
|
|
28947
|
-
/* @__PURE__ */ jsx(
|
|
28948
|
-
"button",
|
|
28949
|
-
{
|
|
28950
|
-
onClick: () => setViewMode("list"),
|
|
28951
|
-
className: clsx(
|
|
28952
|
-
"p-2 rounded-lg transition-colors",
|
|
28953
|
-
viewMode === "list" ? "bg-blue-100 dark:bg-blue-900/30 text-blue-600 dark:text-blue-400" : "text-gray-600 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700"
|
|
28954
|
-
),
|
|
28955
|
-
"aria-label": "List view",
|
|
28956
|
-
children: /* @__PURE__ */ jsx(List, { className: "h-5 w-5" })
|
|
28957
|
-
}
|
|
28958
|
-
)
|
|
28959
28960
|
] })
|
|
28960
28961
|
] }),
|
|
28961
28962
|
/* @__PURE__ */ jsxs("div", { className: "mt-3 text-sm text-gray-500 dark:text-gray-400", children: [
|
|
@@ -28995,32 +28996,15 @@ var HealthStatusGrid = ({
|
|
|
28995
28996
|
]
|
|
28996
28997
|
}
|
|
28997
28998
|
),
|
|
28998
|
-
isExpanded && /* @__PURE__ */ jsx(
|
|
28999
|
-
|
|
28999
|
+
isExpanded && /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4", children: groupWorkspaces.map((workspace) => /* @__PURE__ */ jsx(
|
|
29000
|
+
WorkspaceHealthCard,
|
|
29000
29001
|
{
|
|
29001
|
-
|
|
29002
|
-
|
|
29003
|
-
|
|
29004
|
-
|
|
29005
|
-
|
|
29006
|
-
|
|
29007
|
-
{
|
|
29008
|
-
workspace,
|
|
29009
|
-
onClick: onWorkspaceClick,
|
|
29010
|
-
showDetails: true
|
|
29011
|
-
},
|
|
29012
|
-
workspace.workspace_id
|
|
29013
|
-
) : /* @__PURE__ */ jsx(
|
|
29014
|
-
CompactWorkspaceHealthCard,
|
|
29015
|
-
{
|
|
29016
|
-
workspace,
|
|
29017
|
-
onClick: onWorkspaceClick
|
|
29018
|
-
},
|
|
29019
|
-
workspace.workspace_id
|
|
29020
|
-
)
|
|
29021
|
-
)
|
|
29022
|
-
}
|
|
29023
|
-
)
|
|
29002
|
+
workspace,
|
|
29003
|
+
onClick: onWorkspaceClick,
|
|
29004
|
+
showDetails: true
|
|
29005
|
+
},
|
|
29006
|
+
workspace.workspace_id
|
|
29007
|
+
)) })
|
|
29024
29008
|
] }, groupName);
|
|
29025
29009
|
}) }),
|
|
29026
29010
|
filteredWorkspaces.length === 0 && /* @__PURE__ */ jsx("div", { className: "text-center py-12", children: /* @__PURE__ */ jsx("p", { className: "text-gray-500 dark:text-gray-400", children: searchTerm || statusFilter !== "all" ? "No workspaces found matching your filters." : "No workspaces available." }) })
|
|
@@ -37742,7 +37726,23 @@ var WorkspaceDetailView = ({
|
|
|
37742
37726
|
"aria-label": "Navigate back to previous page"
|
|
37743
37727
|
}
|
|
37744
37728
|
) }),
|
|
37745
|
-
/* @__PURE__ */ jsx("div", { className: "absolute left-1/2 transform -translate-x-1/2", children: /* @__PURE__ */
|
|
37729
|
+
/* @__PURE__ */ jsx("div", { className: "absolute left-1/2 transform -translate-x-1/2", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
37730
|
+
/* @__PURE__ */ jsx("h1", { className: "text-3xl font-semibold text-gray-900", children: formattedWorkspaceName }),
|
|
37731
|
+
workspaceHealth && /* @__PURE__ */ jsxs("div", { className: "relative flex h-2.5 w-2.5", children: [
|
|
37732
|
+
/* @__PURE__ */ jsx("span", { className: clsx(
|
|
37733
|
+
"animate-ping absolute inline-flex h-full w-full rounded-full opacity-75",
|
|
37734
|
+
workspaceHealth.status === "healthy" ? "bg-green-400" : "bg-red-400"
|
|
37735
|
+
) }),
|
|
37736
|
+
/* @__PURE__ */ jsx("span", { className: clsx(
|
|
37737
|
+
"relative inline-flex rounded-full h-2.5 w-2.5",
|
|
37738
|
+
workspaceHealth.status === "healthy" ? "bg-green-500" : "bg-red-500"
|
|
37739
|
+
) })
|
|
37740
|
+
] })
|
|
37741
|
+
] }) }),
|
|
37742
|
+
workspaceHealth && activeTab !== "monthly_history" && /* @__PURE__ */ jsx("div", { className: "absolute right-0 top-0 flex items-center h-8", children: /* @__PURE__ */ jsxs("span", { className: "text-xs text-gray-500", children: [
|
|
37743
|
+
"Last update: ",
|
|
37744
|
+
workspaceHealth.timeSinceLastUpdate
|
|
37745
|
+
] }) }),
|
|
37746
37746
|
/* @__PURE__ */ jsx("div", { className: "w-full h-8" })
|
|
37747
37747
|
] }),
|
|
37748
37748
|
activeTab !== "monthly_history" && /* @__PURE__ */ jsx("div", { className: "mt-3 bg-blue-50 px-3 py-2 rounded-lg", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-4", children: [
|
|
@@ -37770,19 +37770,6 @@ var WorkspaceDetailView = ({
|
|
|
37770
37770
|
workspace.shift_type,
|
|
37771
37771
|
" Shift"
|
|
37772
37772
|
] })
|
|
37773
|
-
] }),
|
|
37774
|
-
workspaceHealth && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
37775
|
-
/* @__PURE__ */ jsx("div", { className: "w-px h-4 bg-blue-300" }),
|
|
37776
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
37777
|
-
/* @__PURE__ */ jsx("div", { className: clsx(
|
|
37778
|
-
"h-1.5 w-1.5 rounded-full",
|
|
37779
|
-
workspaceHealth.status === "healthy" ? "bg-green-600" : workspaceHealth.status === "unhealthy" ? "bg-red-600" : workspaceHealth.status === "warning" ? "bg-amber-600" : "bg-gray-500"
|
|
37780
|
-
) }),
|
|
37781
|
-
/* @__PURE__ */ jsxs("span", { className: "text-xs text-blue-700", children: [
|
|
37782
|
-
"Last update: ",
|
|
37783
|
-
workspaceHealth.timeSinceLastUpdate
|
|
37784
|
-
] })
|
|
37785
|
-
] })
|
|
37786
37773
|
] })
|
|
37787
37774
|
] }) }),
|
|
37788
37775
|
/* @__PURE__ */ jsxs("div", { className: "mt-1 sm:mt-1.5 lg:mt-2 flex items-center justify-between", children: [
|
|
@@ -38326,7 +38313,6 @@ var WorkspaceHealthView = ({
|
|
|
38326
38313
|
className = ""
|
|
38327
38314
|
}) => {
|
|
38328
38315
|
const router = useRouter();
|
|
38329
|
-
const [viewMode, setViewMode] = useState("grid");
|
|
38330
38316
|
const [groupBy, setGroupBy] = useState("line");
|
|
38331
38317
|
const operationalDate = getOperationalDate();
|
|
38332
38318
|
const currentHour = (/* @__PURE__ */ new Date()).getHours();
|
|
@@ -38491,7 +38477,7 @@ var WorkspaceHealthView = ({
|
|
|
38491
38477
|
transition: { duration: 0.3, delay: 0.1 },
|
|
38492
38478
|
className: "grid grid-cols-2 sm:grid-cols-2 md:grid-cols-5 gap-2 sm:gap-3 lg:gap-4",
|
|
38493
38479
|
children: [
|
|
38494
|
-
/* @__PURE__ */ jsxs(Card2, { className: "col-span-2 sm:col-span-2 md:col-span-2", children: [
|
|
38480
|
+
/* @__PURE__ */ jsxs(Card2, { className: "col-span-2 sm:col-span-2 md:col-span-2 bg-white", children: [
|
|
38495
38481
|
/* @__PURE__ */ jsx(CardHeader2, { className: "pb-3", children: /* @__PURE__ */ jsx(CardTitle2, { className: "text-sm font-medium text-gray-500 dark:text-gray-400", children: "Overall System Status" }) }),
|
|
38496
38482
|
/* @__PURE__ */ jsxs(CardContent2, { children: [
|
|
38497
38483
|
/* @__PURE__ */ jsxs("div", { className: "flex items-baseline gap-2", children: [
|
|
@@ -38509,33 +38495,33 @@ var WorkspaceHealthView = ({
|
|
|
38509
38495
|
] })
|
|
38510
38496
|
] })
|
|
38511
38497
|
] }),
|
|
38512
|
-
/* @__PURE__ */ jsxs(Card2, { children: [
|
|
38498
|
+
/* @__PURE__ */ jsxs(Card2, { className: "bg-white", children: [
|
|
38513
38499
|
/* @__PURE__ */ jsx(CardHeader2, { className: "pb-3", children: /* @__PURE__ */ jsxs(CardTitle2, { className: "text-sm font-medium text-gray-500 dark:text-gray-400 flex items-center gap-2", children: [
|
|
38514
38500
|
getStatusIcon("healthy"),
|
|
38515
38501
|
"Healthy"
|
|
38516
38502
|
] }) }),
|
|
38517
38503
|
/* @__PURE__ */ jsxs(CardContent2, { children: [
|
|
38518
|
-
/* @__PURE__ */ jsx("p", { className: "text-2xl font-bold text-
|
|
38504
|
+
/* @__PURE__ */ jsx("p", { className: "text-2xl font-bold text-gray-900 dark:text-gray-50", children: summary.healthyWorkspaces }),
|
|
38519
38505
|
/* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: "Operating normally" })
|
|
38520
38506
|
] })
|
|
38521
38507
|
] }),
|
|
38522
|
-
/* @__PURE__ */ jsxs(Card2, { children: [
|
|
38508
|
+
/* @__PURE__ */ jsxs(Card2, { className: "bg-white", children: [
|
|
38523
38509
|
/* @__PURE__ */ jsx(CardHeader2, { className: "pb-3", children: /* @__PURE__ */ jsxs(CardTitle2, { className: "text-sm font-medium text-gray-500 dark:text-gray-400 flex items-center gap-2", children: [
|
|
38524
38510
|
getStatusIcon("warning"),
|
|
38525
38511
|
"Warning"
|
|
38526
38512
|
] }) }),
|
|
38527
38513
|
/* @__PURE__ */ jsxs(CardContent2, { children: [
|
|
38528
|
-
/* @__PURE__ */ jsx("p", { className: "text-2xl font-bold text-
|
|
38514
|
+
/* @__PURE__ */ jsx("p", { className: "text-2xl font-bold text-gray-900 dark:text-gray-50", children: summary.warningWorkspaces }),
|
|
38529
38515
|
/* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: "Delayed updates" })
|
|
38530
38516
|
] })
|
|
38531
38517
|
] }),
|
|
38532
|
-
/* @__PURE__ */ jsxs(Card2, { children: [
|
|
38518
|
+
/* @__PURE__ */ jsxs(Card2, { className: "bg-white", children: [
|
|
38533
38519
|
/* @__PURE__ */ jsx(CardHeader2, { className: "pb-3", children: /* @__PURE__ */ jsxs(CardTitle2, { className: "text-sm font-medium text-gray-500 dark:text-gray-400 flex items-center gap-2", children: [
|
|
38534
38520
|
getStatusIcon("unhealthy"),
|
|
38535
38521
|
"Unhealthy"
|
|
38536
38522
|
] }) }),
|
|
38537
38523
|
/* @__PURE__ */ jsxs(CardContent2, { children: [
|
|
38538
|
-
/* @__PURE__ */ jsx("p", { className: "text-2xl font-bold text-
|
|
38524
|
+
/* @__PURE__ */ jsx("p", { className: "text-2xl font-bold text-gray-900 dark:text-gray-50", children: summary.unhealthyWorkspaces }),
|
|
38539
38525
|
/* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: "Requires attention" })
|
|
38540
38526
|
] })
|
|
38541
38527
|
] })
|
|
@@ -38553,7 +38539,6 @@ var WorkspaceHealthView = ({
|
|
|
38553
38539
|
{
|
|
38554
38540
|
workspaces,
|
|
38555
38541
|
onWorkspaceClick: handleWorkspaceClick,
|
|
38556
|
-
viewMode,
|
|
38557
38542
|
showFilters: true,
|
|
38558
38543
|
groupBy
|
|
38559
38544
|
}
|