@optifye/dashboard-core 6.5.0 → 6.5.1

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 CHANGED
@@ -1950,10 +1950,6 @@ body {
1950
1950
  --tw-bg-opacity: 1;
1951
1951
  background-color: rgb(245 158 11 / var(--tw-bg-opacity, 1));
1952
1952
  }
1953
- .bg-amber-600 {
1954
- --tw-bg-opacity: 1;
1955
- background-color: rgb(217 119 6 / var(--tw-bg-opacity, 1));
1956
- }
1957
1953
  .bg-black {
1958
1954
  --tw-bg-opacity: 1;
1959
1955
  background-color: rgb(0 0 0 / var(--tw-bg-opacity, 1));
@@ -2094,6 +2090,10 @@ body {
2094
2090
  --tw-bg-opacity: 1;
2095
2091
  background-color: rgb(220 252 231 / var(--tw-bg-opacity, 1));
2096
2092
  }
2093
+ .bg-green-400 {
2094
+ --tw-bg-opacity: 1;
2095
+ background-color: rgb(74 222 128 / var(--tw-bg-opacity, 1));
2096
+ }
2097
2097
  .bg-green-50 {
2098
2098
  --tw-bg-opacity: 1;
2099
2099
  background-color: rgb(240 253 244 / var(--tw-bg-opacity, 1));
@@ -2141,6 +2141,10 @@ body {
2141
2141
  --tw-bg-opacity: 1;
2142
2142
  background-color: rgb(254 226 226 / var(--tw-bg-opacity, 1));
2143
2143
  }
2144
+ .bg-red-400 {
2145
+ --tw-bg-opacity: 1;
2146
+ background-color: rgb(248 113 113 / var(--tw-bg-opacity, 1));
2147
+ }
2144
2148
  .bg-red-400\/50 {
2145
2149
  background-color: rgb(248 113 113 / 0.5);
2146
2150
  }
@@ -2164,10 +2168,6 @@ body {
2164
2168
  .bg-red-500\/40 {
2165
2169
  background-color: rgb(239 68 68 / 0.4);
2166
2170
  }
2167
- .bg-red-600 {
2168
- --tw-bg-opacity: 1;
2169
- background-color: rgb(220 38 38 / var(--tw-bg-opacity, 1));
2170
- }
2171
2171
  .bg-red-700 {
2172
2172
  --tw-bg-opacity: 1;
2173
2173
  background-color: rgb(185 28 28 / var(--tw-bg-opacity, 1));
@@ -3718,6 +3718,10 @@ input[type=range]:active::-moz-range-thumb {
3718
3718
  --tw-bg-opacity: 1;
3719
3719
  background-color: rgb(243 244 246 / var(--tw-bg-opacity, 1));
3720
3720
  }
3721
+ .focus\:bg-gray-50:focus {
3722
+ --tw-bg-opacity: 1;
3723
+ background-color: rgb(249 250 251 / var(--tw-bg-opacity, 1));
3724
+ }
3721
3725
  .focus\:bg-white:focus {
3722
3726
  --tw-bg-opacity: 1;
3723
3727
  background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
@@ -4406,9 +4410,6 @@ input[type=range]:active::-moz-range-thumb {
4406
4410
  .dark\:bg-blue-900\/20 {
4407
4411
  background-color: rgb(30 58 138 / 0.2);
4408
4412
  }
4409
- .dark\:bg-blue-900\/30 {
4410
- background-color: rgb(30 58 138 / 0.3);
4411
- }
4412
4413
  .dark\:bg-emerald-900\/50 {
4413
4414
  background-color: rgb(6 78 59 / 0.5);
4414
4415
  }
@@ -4511,10 +4512,6 @@ input[type=range]:active::-moz-range-thumb {
4511
4512
  --tw-text-opacity: 1;
4512
4513
  color: rgb(245 158 11 / var(--tw-text-opacity, 1));
4513
4514
  }
4514
- .dark\:text-blue-400 {
4515
- --tw-text-opacity: 1;
4516
- color: rgb(96 165 250 / var(--tw-text-opacity, 1));
4517
- }
4518
4515
  .dark\:text-emerald-300 {
4519
4516
  --tw-text-opacity: 1;
4520
4517
  color: rgb(110 231 183 / var(--tw-text-opacity, 1));
package/dist/index.d.mts CHANGED
@@ -5184,7 +5184,6 @@ declare const CompactWorkspaceHealthCard: React__default.FC<CompactWorkspaceHeal
5184
5184
  interface HealthStatusGridProps {
5185
5185
  workspaces: WorkspaceHealthWithStatus[];
5186
5186
  onWorkspaceClick?: (workspace: WorkspaceHealthWithStatus) => void;
5187
- viewMode?: 'grid' | 'list';
5188
5187
  showFilters?: boolean;
5189
5188
  groupBy?: 'none' | 'line' | 'status';
5190
5189
  className?: string;
package/dist/index.d.ts CHANGED
@@ -5184,7 +5184,6 @@ declare const CompactWorkspaceHealthCard: React__default.FC<CompactWorkspaceHeal
5184
5184
  interface HealthStatusGridProps {
5185
5185
  workspaces: WorkspaceHealthWithStatus[];
5186
5186
  onWorkspaceClick?: (workspace: WorkspaceHealthWithStatus) => void;
5187
- viewMode?: 'grid' | 'list';
5188
5187
  showFilters?: boolean;
5189
5188
  groupBy?: 'none' | 'line' | 'status';
5190
5189
  className?: string;
package/dist/index.js CHANGED
@@ -3286,35 +3286,6 @@ var useAudioService = () => {
3286
3286
  };
3287
3287
 
3288
3288
  // src/lib/utils/dateShiftUtils.ts
3289
- function getOperationalDate2(timezone = "Asia/Kolkata") {
3290
- const now2 = /* @__PURE__ */ new Date();
3291
- const localTime = new Date(now2.toLocaleString("en-US", { timeZone: timezone }));
3292
- const hour = localTime.getHours();
3293
- if (hour < 6) {
3294
- localTime.setDate(localTime.getDate() - 1);
3295
- }
3296
- return localTime.toISOString().split("T")[0];
3297
- }
3298
- function getCurrentShift2(timezone = "Asia/Kolkata") {
3299
- const now2 = /* @__PURE__ */ new Date();
3300
- const localTime = new Date(now2.toLocaleString("en-US", { timeZone: timezone }));
3301
- const hour = localTime.getHours();
3302
- if (hour >= 6 && hour < 18) {
3303
- return {
3304
- shiftId: 0,
3305
- shiftName: "Day Shift",
3306
- startTime: "06:00",
3307
- endTime: "18:00"
3308
- };
3309
- } else {
3310
- return {
3311
- shiftId: 1,
3312
- shiftName: "Night Shift",
3313
- startTime: "18:00",
3314
- endTime: "06:00"
3315
- };
3316
- }
3317
- }
3318
3289
  function isValidDateFormat(date) {
3319
3290
  return /^\d{4}-\d{2}-\d{2}$/.test(date);
3320
3291
  }
@@ -4428,7 +4399,11 @@ var S3ClipsService = class {
4428
4399
  if (!workspaceId) {
4429
4400
  throw new Error("Valid Workspace ID is required");
4430
4401
  }
4431
- const date = inputDate || getOperationalDate2(this.config.dateTimeConfig?.defaultTimezone);
4402
+ const date = inputDate || getOperationalDate(
4403
+ this.config.dateTimeConfig?.defaultTimezone || "Asia/Kolkata",
4404
+ /* @__PURE__ */ new Date(),
4405
+ this.config.shiftConfig?.dayShift?.startTime || "06:00"
4406
+ );
4432
4407
  if (!isValidDateFormat(date)) {
4433
4408
  throw new Error("Invalid date format. Use YYYY-MM-DD.");
4434
4409
  }
@@ -4439,7 +4414,10 @@ var S3ClipsService = class {
4439
4414
  }
4440
4415
  shiftId = parseInt(shift, 10);
4441
4416
  } else {
4442
- const { shiftId: currentShiftId } = getCurrentShift2(this.config.dateTimeConfig?.defaultTimezone);
4417
+ const { shiftId: currentShiftId } = getCurrentShift(
4418
+ this.config.dateTimeConfig?.defaultTimezone || "Asia/Kolkata",
4419
+ this.config.shiftConfig
4420
+ );
4443
4421
  shiftId = currentShiftId;
4444
4422
  }
4445
4423
  console.log(`[S3ClipsService] Fetching clips for workspace ${workspaceId}`);
@@ -8079,7 +8057,7 @@ var useActiveBreaks = (lineIds) => {
8079
8057
  }
8080
8058
  return { elapsedMinutes, remainingMinutes };
8081
8059
  };
8082
- const getCurrentShift3 = (currentMinutes, dayStart, nightStart) => {
8060
+ const getCurrentShift2 = (currentMinutes, dayStart, nightStart) => {
8083
8061
  const dayStartMinutes = parseTimeToMinutes2(dayStart);
8084
8062
  const nightStartMinutes = parseTimeToMinutes2(nightStart);
8085
8063
  if (nightStartMinutes < dayStartMinutes) {
@@ -8111,7 +8089,7 @@ var useActiveBreaks = (lineIds) => {
8111
8089
  const dayShift = dayShifts?.find((s) => s.line_id === lineId);
8112
8090
  const nightShift = nightShifts?.find((s) => s.line_id === lineId);
8113
8091
  if (!dayShift || !nightShift) continue;
8114
- const currentShift = getCurrentShift3(
8092
+ const currentShift = getCurrentShift2(
8115
8093
  currentMinutes,
8116
8094
  dayShift.start_time || "06:00",
8117
8095
  nightShift.start_time || "18:00"
@@ -11608,9 +11586,12 @@ var usePrefetchClipCounts = ({
11608
11586
  shiftStr = "0";
11609
11587
  console.log(`[usePrefetchClipCounts] No shift provided for historical date ${date}, defaulting to day shift (0)`);
11610
11588
  } else {
11611
- const currentShift = getCurrentShift2();
11589
+ const currentShift = getCurrentShift(
11590
+ dashboardConfig.dateTimeConfig?.defaultTimezone || "Asia/Kolkata",
11591
+ dashboardConfig.shiftConfig
11592
+ );
11612
11593
  shiftStr = currentShift.shiftId.toString();
11613
- console.log(`[usePrefetchClipCounts] Using current operational shift: ${shiftStr} (${currentShift.shiftName})`);
11594
+ console.log(`[usePrefetchClipCounts] Using current operational shift: ${shiftStr}`);
11614
11595
  }
11615
11596
  return {
11616
11597
  workspaceId: workspaceId || "",
@@ -26947,11 +26928,14 @@ var BottlenecksContent = ({
26947
26928
  console.log(`[BottlenecksContent] No shift provided for historical date ${date}, defaulting to day shift (0)`);
26948
26929
  return "0";
26949
26930
  } else {
26950
- const currentShift = getCurrentShift2();
26951
- console.log(`[BottlenecksContent] Using current operational shift: ${currentShift.shiftId} (${currentShift.shiftName})`);
26931
+ const currentShift = getCurrentShift(
26932
+ dashboardConfig.dateTimeConfig?.defaultTimezone || "Asia/Kolkata",
26933
+ dashboardConfig.shiftConfig
26934
+ );
26935
+ console.log(`[BottlenecksContent] Using current operational shift: ${currentShift.shiftId}`);
26952
26936
  return currentShift.shiftId.toString();
26953
26937
  }
26954
- }, [shift, date]);
26938
+ }, [shift, date, dashboardConfig]);
26955
26939
  const {
26956
26940
  data: prefetchData,
26957
26941
  isFullyIndexed,
@@ -28663,7 +28647,6 @@ var WorkspaceHealthCard = ({
28663
28647
  };
28664
28648
  const config = getStatusConfig();
28665
28649
  const StatusIcon = config.icon;
28666
- workspace.isStale ? lucideReact.WifiOff : lucideReact.Wifi;
28667
28650
  const handleClick = () => {
28668
28651
  if (onClick) {
28669
28652
  onClick(workspace);
@@ -28711,34 +28694,13 @@ var WorkspaceHealthCard = ({
28711
28694
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: config.statusText })
28712
28695
  ] })
28713
28696
  ] }),
28714
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
28715
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
28716
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
28717
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Clock, { className: "h-3.5 w-3.5 text-gray-400" }),
28718
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm text-gray-600 dark:text-gray-400 whitespace-nowrap", children: [
28719
- "Last seen: ",
28720
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: formatTimeAgo(workspace.timeSinceLastUpdate) })
28721
- ] })
28722
- ] }),
28723
- workspace.isStale && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
28724
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.WifiOff, { className: "h-3.5 w-3.5 text-amber-500" }),
28725
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-amber-600 dark:text-amber-400 text-xs", children: "No recent updates" })
28726
- ] })
28727
- ] }),
28728
- config.pulse && !workspace.isStale && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
28729
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex h-2 w-2", children: [
28730
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: clsx(
28731
- "animate-ping absolute inline-flex h-full w-full rounded-full opacity-75",
28732
- workspace.status === "healthy" ? "bg-emerald-400" : "bg-amber-400"
28733
- ) }),
28734
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: clsx(
28735
- "relative inline-flex rounded-full h-2 w-2",
28736
- workspace.status === "healthy" ? "bg-emerald-500" : "bg-amber-500"
28737
- ) })
28738
- ] }),
28739
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-gray-500 dark:text-gray-400", children: "Live" })
28697
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-1", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
28698
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Clock, { className: "h-3.5 w-3.5 text-gray-400" }),
28699
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm text-gray-600 dark:text-gray-400 whitespace-nowrap", children: [
28700
+ "Last seen: ",
28701
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: formatTimeAgo(workspace.timeSinceLastUpdate) })
28740
28702
  ] })
28741
- ] })
28703
+ ] }) }) })
28742
28704
  ] })
28743
28705
  }
28744
28706
  );
@@ -28819,16 +28781,16 @@ var CompactWorkspaceHealthCard = ({
28819
28781
  var HealthStatusGrid = ({
28820
28782
  workspaces,
28821
28783
  onWorkspaceClick,
28822
- viewMode: initialViewMode = "grid",
28823
28784
  showFilters = true,
28824
28785
  groupBy: initialGroupBy = "none",
28825
28786
  className = ""
28826
28787
  }) => {
28827
- const [viewMode, setViewMode] = React19.useState(initialViewMode);
28828
28788
  const [searchTerm, setSearchTerm] = React19.useState("");
28829
28789
  const [statusFilter, setStatusFilter] = React19.useState("all");
28830
28790
  const [groupBy, setGroupBy] = React19.useState(initialGroupBy);
28831
28791
  const [expandedGroups, setExpandedGroups] = React19.useState(/* @__PURE__ */ new Set());
28792
+ const lastGroupByRef = React19.useRef(initialGroupBy);
28793
+ const hasInitializedGroupsRef = React19.useRef(false);
28832
28794
  const filteredWorkspaces = React19.useMemo(() => {
28833
28795
  let filtered = [...workspaces];
28834
28796
  if (searchTerm) {
@@ -28869,7 +28831,17 @@ var HealthStatusGrid = ({
28869
28831
  return sortedGroups;
28870
28832
  }, [filteredWorkspaces, groupBy]);
28871
28833
  React19.useEffect(() => {
28872
- if (groupBy !== "none") {
28834
+ if (groupBy !== lastGroupByRef.current) {
28835
+ lastGroupByRef.current = groupBy;
28836
+ hasInitializedGroupsRef.current = false;
28837
+ if (groupBy === "none") {
28838
+ setExpandedGroups(/* @__PURE__ */ new Set());
28839
+ }
28840
+ }
28841
+ }, [groupBy]);
28842
+ React19.useEffect(() => {
28843
+ if (groupBy !== "none" && !hasInitializedGroupsRef.current && Object.keys(groupedWorkspaces).length > 0) {
28844
+ hasInitializedGroupsRef.current = true;
28873
28845
  setExpandedGroups(new Set(Object.keys(groupedWorkspaces)));
28874
28846
  }
28875
28847
  }, [groupBy, groupedWorkspaces]);
@@ -28913,13 +28885,13 @@ var HealthStatusGrid = ({
28913
28885
  ] }) }),
28914
28886
  /* @__PURE__ */ jsxRuntime.jsxs(Select, { value: statusFilter, onValueChange: (value) => setStatusFilter(value), children: [
28915
28887
  /* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { className: "w-full sm:w-[180px] bg-white border-gray-200", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, { placeholder: "All statuses" }) }),
28916
- /* @__PURE__ */ jsxRuntime.jsxs(SelectContent, { children: [
28917
- /* @__PURE__ */ jsxRuntime.jsxs(SelectItem, { value: "all", children: [
28888
+ /* @__PURE__ */ jsxRuntime.jsxs(SelectContent, { className: "bg-white border border-gray-200 shadow-lg", children: [
28889
+ /* @__PURE__ */ jsxRuntime.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: [
28918
28890
  "All (",
28919
28891
  workspaces.length,
28920
28892
  ")"
28921
28893
  ] }),
28922
- /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: "healthy", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
28894
+ /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
28923
28895
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-2 w-2 rounded-full bg-green-500" }),
28924
28896
  /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
28925
28897
  "Healthy (",
@@ -28927,7 +28899,7 @@ var HealthStatusGrid = ({
28927
28899
  ")"
28928
28900
  ] })
28929
28901
  ] }) }),
28930
- /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: "unhealthy", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
28902
+ /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
28931
28903
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-2 w-2 rounded-full bg-red-500" }),
28932
28904
  /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
28933
28905
  "Unhealthy (",
@@ -28935,57 +28907,23 @@ var HealthStatusGrid = ({
28935
28907
  ")"
28936
28908
  ] })
28937
28909
  ] }) }),
28938
- /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: "warning", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
28910
+ /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
28939
28911
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-2 w-2 rounded-full bg-yellow-500" }),
28940
28912
  /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
28941
28913
  "Warning (",
28942
28914
  statusCounts.warning,
28943
28915
  ")"
28944
28916
  ] })
28945
- ] }) }),
28946
- /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: "unknown", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
28947
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-2 w-2 rounded-full bg-gray-400" }),
28948
- /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
28949
- "Unknown (",
28950
- statusCounts.unknown,
28951
- ")"
28952
- ] })
28953
28917
  ] }) })
28954
28918
  ] })
28955
28919
  ] }),
28956
28920
  /* @__PURE__ */ jsxRuntime.jsxs(Select, { value: groupBy, onValueChange: (value) => setGroupBy(value), children: [
28957
28921
  /* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { className: "w-full sm:w-[160px] bg-white border-gray-200", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, { placeholder: "Group by" }) }),
28958
- /* @__PURE__ */ jsxRuntime.jsxs(SelectContent, { children: [
28959
- /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: "none", children: "No grouping" }),
28960
- /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: "line", children: "Group by Line" }),
28961
- /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: "status", children: "Group by Status" })
28922
+ /* @__PURE__ */ jsxRuntime.jsxs(SelectContent, { className: "bg-white border border-gray-200 shadow-lg", children: [
28923
+ /* @__PURE__ */ jsxRuntime.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" }),
28924
+ /* @__PURE__ */ jsxRuntime.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" }),
28925
+ /* @__PURE__ */ jsxRuntime.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" })
28962
28926
  ] })
28963
- ] }),
28964
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
28965
- /* @__PURE__ */ jsxRuntime.jsx(
28966
- "button",
28967
- {
28968
- onClick: () => setViewMode("grid"),
28969
- className: clsx(
28970
- "p-2 rounded-lg transition-colors",
28971
- 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"
28972
- ),
28973
- "aria-label": "Grid view",
28974
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Grid3x3, { className: "h-5 w-5" })
28975
- }
28976
- ),
28977
- /* @__PURE__ */ jsxRuntime.jsx(
28978
- "button",
28979
- {
28980
- onClick: () => setViewMode("list"),
28981
- className: clsx(
28982
- "p-2 rounded-lg transition-colors",
28983
- 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"
28984
- ),
28985
- "aria-label": "List view",
28986
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.List, { className: "h-5 w-5" })
28987
- }
28988
- )
28989
28927
  ] })
28990
28928
  ] }),
28991
28929
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 text-sm text-gray-500 dark:text-gray-400", children: [
@@ -29025,32 +28963,15 @@ var HealthStatusGrid = ({
29025
28963
  ]
29026
28964
  }
29027
28965
  ),
29028
- isExpanded && /* @__PURE__ */ jsxRuntime.jsx(
29029
- "div",
28966
+ isExpanded && /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsx(
28967
+ WorkspaceHealthCard,
29030
28968
  {
29031
- className: clsx(
29032
- viewMode === "grid" ? "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4" : "space-y-2"
29033
- ),
29034
- children: groupWorkspaces.map(
29035
- (workspace) => viewMode === "grid" ? /* @__PURE__ */ jsxRuntime.jsx(
29036
- WorkspaceHealthCard,
29037
- {
29038
- workspace,
29039
- onClick: onWorkspaceClick,
29040
- showDetails: true
29041
- },
29042
- workspace.workspace_id
29043
- ) : /* @__PURE__ */ jsxRuntime.jsx(
29044
- CompactWorkspaceHealthCard,
29045
- {
29046
- workspace,
29047
- onClick: onWorkspaceClick
29048
- },
29049
- workspace.workspace_id
29050
- )
29051
- )
29052
- }
29053
- )
28969
+ workspace,
28970
+ onClick: onWorkspaceClick,
28971
+ showDetails: true
28972
+ },
28973
+ workspace.workspace_id
28974
+ )) })
29054
28975
  ] }, groupName);
29055
28976
  }) }),
29056
28977
  filteredWorkspaces.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-center py-12", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-gray-500 dark:text-gray-400", children: searchTerm || statusFilter !== "all" ? "No workspaces found matching your filters." : "No workspaces available." }) })
@@ -37772,7 +37693,23 @@ var WorkspaceDetailView = ({
37772
37693
  "aria-label": "Navigate back to previous page"
37773
37694
  }
37774
37695
  ) }),
37775
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-1/2 transform -translate-x-1/2", children: /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-3xl font-semibold text-gray-900", children: formattedWorkspaceName }) }),
37696
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-1/2 transform -translate-x-1/2", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
37697
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-3xl font-semibold text-gray-900", children: formattedWorkspaceName }),
37698
+ workspaceHealth && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex h-2.5 w-2.5", children: [
37699
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: clsx(
37700
+ "animate-ping absolute inline-flex h-full w-full rounded-full opacity-75",
37701
+ workspaceHealth.status === "healthy" ? "bg-green-400" : "bg-red-400"
37702
+ ) }),
37703
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: clsx(
37704
+ "relative inline-flex rounded-full h-2.5 w-2.5",
37705
+ workspaceHealth.status === "healthy" ? "bg-green-500" : "bg-red-500"
37706
+ ) })
37707
+ ] })
37708
+ ] }) }),
37709
+ workspaceHealth && activeTab !== "monthly_history" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute right-0 top-0 flex items-center h-8", children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-gray-500", children: [
37710
+ "Last update: ",
37711
+ workspaceHealth.timeSinceLastUpdate
37712
+ ] }) }),
37776
37713
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-8" })
37777
37714
  ] }),
37778
37715
  activeTab !== "monthly_history" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 bg-blue-50 px-3 py-2 rounded-lg", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-4", children: [
@@ -37800,19 +37737,6 @@ var WorkspaceDetailView = ({
37800
37737
  workspace.shift_type,
37801
37738
  " Shift"
37802
37739
  ] })
37803
- ] }),
37804
- workspaceHealth && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
37805
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-px h-4 bg-blue-300" }),
37806
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
37807
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: clsx(
37808
- "h-1.5 w-1.5 rounded-full",
37809
- workspaceHealth.status === "healthy" ? "bg-green-600" : workspaceHealth.status === "unhealthy" ? "bg-red-600" : workspaceHealth.status === "warning" ? "bg-amber-600" : "bg-gray-500"
37810
- ) }),
37811
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-blue-700", children: [
37812
- "Last update: ",
37813
- workspaceHealth.timeSinceLastUpdate
37814
- ] })
37815
- ] })
37816
37740
  ] })
37817
37741
  ] }) }),
37818
37742
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-1 sm:mt-1.5 lg:mt-2 flex items-center justify-between", children: [
@@ -38356,7 +38280,6 @@ var WorkspaceHealthView = ({
38356
38280
  className = ""
38357
38281
  }) => {
38358
38282
  const router$1 = router.useRouter();
38359
- const [viewMode, setViewMode] = React19.useState("grid");
38360
38283
  const [groupBy, setGroupBy] = React19.useState("line");
38361
38284
  const operationalDate = getOperationalDate();
38362
38285
  const currentHour = (/* @__PURE__ */ new Date()).getHours();
@@ -38521,7 +38444,7 @@ var WorkspaceHealthView = ({
38521
38444
  transition: { duration: 0.3, delay: 0.1 },
38522
38445
  className: "grid grid-cols-2 sm:grid-cols-2 md:grid-cols-5 gap-2 sm:gap-3 lg:gap-4",
38523
38446
  children: [
38524
- /* @__PURE__ */ jsxRuntime.jsxs(Card2, { className: "col-span-2 sm:col-span-2 md:col-span-2", children: [
38447
+ /* @__PURE__ */ jsxRuntime.jsxs(Card2, { className: "col-span-2 sm:col-span-2 md:col-span-2 bg-white", children: [
38525
38448
  /* @__PURE__ */ jsxRuntime.jsx(CardHeader2, { className: "pb-3", children: /* @__PURE__ */ jsxRuntime.jsx(CardTitle2, { className: "text-sm font-medium text-gray-500 dark:text-gray-400", children: "Overall System Status" }) }),
38526
38449
  /* @__PURE__ */ jsxRuntime.jsxs(CardContent2, { children: [
38527
38450
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline gap-2", children: [
@@ -38539,33 +38462,33 @@ var WorkspaceHealthView = ({
38539
38462
  ] })
38540
38463
  ] })
38541
38464
  ] }),
38542
- /* @__PURE__ */ jsxRuntime.jsxs(Card2, { children: [
38465
+ /* @__PURE__ */ jsxRuntime.jsxs(Card2, { className: "bg-white", children: [
38543
38466
  /* @__PURE__ */ jsxRuntime.jsx(CardHeader2, { className: "pb-3", children: /* @__PURE__ */ jsxRuntime.jsxs(CardTitle2, { className: "text-sm font-medium text-gray-500 dark:text-gray-400 flex items-center gap-2", children: [
38544
38467
  getStatusIcon("healthy"),
38545
38468
  "Healthy"
38546
38469
  ] }) }),
38547
38470
  /* @__PURE__ */ jsxRuntime.jsxs(CardContent2, { children: [
38548
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-2xl font-bold text-green-600 dark:text-green-400", children: summary.healthyWorkspaces }),
38471
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-2xl font-bold text-gray-900 dark:text-gray-50", children: summary.healthyWorkspaces }),
38549
38472
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: "Operating normally" })
38550
38473
  ] })
38551
38474
  ] }),
38552
- /* @__PURE__ */ jsxRuntime.jsxs(Card2, { children: [
38475
+ /* @__PURE__ */ jsxRuntime.jsxs(Card2, { className: "bg-white", children: [
38553
38476
  /* @__PURE__ */ jsxRuntime.jsx(CardHeader2, { className: "pb-3", children: /* @__PURE__ */ jsxRuntime.jsxs(CardTitle2, { className: "text-sm font-medium text-gray-500 dark:text-gray-400 flex items-center gap-2", children: [
38554
38477
  getStatusIcon("warning"),
38555
38478
  "Warning"
38556
38479
  ] }) }),
38557
38480
  /* @__PURE__ */ jsxRuntime.jsxs(CardContent2, { children: [
38558
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-2xl font-bold text-yellow-600 dark:text-yellow-400", children: summary.warningWorkspaces }),
38481
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-2xl font-bold text-gray-900 dark:text-gray-50", children: summary.warningWorkspaces }),
38559
38482
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: "Delayed updates" })
38560
38483
  ] })
38561
38484
  ] }),
38562
- /* @__PURE__ */ jsxRuntime.jsxs(Card2, { children: [
38485
+ /* @__PURE__ */ jsxRuntime.jsxs(Card2, { className: "bg-white", children: [
38563
38486
  /* @__PURE__ */ jsxRuntime.jsx(CardHeader2, { className: "pb-3", children: /* @__PURE__ */ jsxRuntime.jsxs(CardTitle2, { className: "text-sm font-medium text-gray-500 dark:text-gray-400 flex items-center gap-2", children: [
38564
38487
  getStatusIcon("unhealthy"),
38565
38488
  "Unhealthy"
38566
38489
  ] }) }),
38567
38490
  /* @__PURE__ */ jsxRuntime.jsxs(CardContent2, { children: [
38568
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-2xl font-bold text-red-600 dark:text-red-400", children: summary.unhealthyWorkspaces }),
38491
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-2xl font-bold text-gray-900 dark:text-gray-50", children: summary.unhealthyWorkspaces }),
38569
38492
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: "Requires attention" })
38570
38493
  ] })
38571
38494
  ] })
@@ -38583,7 +38506,6 @@ var WorkspaceHealthView = ({
38583
38506
  {
38584
38507
  workspaces,
38585
38508
  onWorkspaceClick: handleWorkspaceClick,
38586
- viewMode,
38587
38509
  showFilters: true,
38588
38510
  groupBy
38589
38511
  }
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, WifiOff, Wifi, Grid3x3, List, Sun, Moon, MessageSquare, Trash2, RefreshCw, Menu, Send, Copy, UserCheck, LogOut, Package, TrendingUp, TrendingDown, Activity, Settings, LifeBuoy, EyeOff, Eye, Zap, UserCircle } from 'lucide-react';
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
  }
@@ -4398,7 +4369,11 @@ var S3ClipsService = class {
4398
4369
  if (!workspaceId) {
4399
4370
  throw new Error("Valid Workspace ID is required");
4400
4371
  }
4401
- const date = inputDate || getOperationalDate2(this.config.dateTimeConfig?.defaultTimezone);
4372
+ const date = inputDate || getOperationalDate(
4373
+ this.config.dateTimeConfig?.defaultTimezone || "Asia/Kolkata",
4374
+ /* @__PURE__ */ new Date(),
4375
+ this.config.shiftConfig?.dayShift?.startTime || "06:00"
4376
+ );
4402
4377
  if (!isValidDateFormat(date)) {
4403
4378
  throw new Error("Invalid date format. Use YYYY-MM-DD.");
4404
4379
  }
@@ -4409,7 +4384,10 @@ var S3ClipsService = class {
4409
4384
  }
4410
4385
  shiftId = parseInt(shift, 10);
4411
4386
  } else {
4412
- const { shiftId: currentShiftId } = getCurrentShift2(this.config.dateTimeConfig?.defaultTimezone);
4387
+ const { shiftId: currentShiftId } = getCurrentShift(
4388
+ this.config.dateTimeConfig?.defaultTimezone || "Asia/Kolkata",
4389
+ this.config.shiftConfig
4390
+ );
4413
4391
  shiftId = currentShiftId;
4414
4392
  }
4415
4393
  console.log(`[S3ClipsService] Fetching clips for workspace ${workspaceId}`);
@@ -8049,7 +8027,7 @@ var useActiveBreaks = (lineIds) => {
8049
8027
  }
8050
8028
  return { elapsedMinutes, remainingMinutes };
8051
8029
  };
8052
- const getCurrentShift3 = (currentMinutes, dayStart, nightStart) => {
8030
+ const getCurrentShift2 = (currentMinutes, dayStart, nightStart) => {
8053
8031
  const dayStartMinutes = parseTimeToMinutes2(dayStart);
8054
8032
  const nightStartMinutes = parseTimeToMinutes2(nightStart);
8055
8033
  if (nightStartMinutes < dayStartMinutes) {
@@ -8081,7 +8059,7 @@ var useActiveBreaks = (lineIds) => {
8081
8059
  const dayShift = dayShifts?.find((s) => s.line_id === lineId);
8082
8060
  const nightShift = nightShifts?.find((s) => s.line_id === lineId);
8083
8061
  if (!dayShift || !nightShift) continue;
8084
- const currentShift = getCurrentShift3(
8062
+ const currentShift = getCurrentShift2(
8085
8063
  currentMinutes,
8086
8064
  dayShift.start_time || "06:00",
8087
8065
  nightShift.start_time || "18:00"
@@ -11578,9 +11556,12 @@ var usePrefetchClipCounts = ({
11578
11556
  shiftStr = "0";
11579
11557
  console.log(`[usePrefetchClipCounts] No shift provided for historical date ${date}, defaulting to day shift (0)`);
11580
11558
  } else {
11581
- const currentShift = getCurrentShift2();
11559
+ const currentShift = getCurrentShift(
11560
+ dashboardConfig.dateTimeConfig?.defaultTimezone || "Asia/Kolkata",
11561
+ dashboardConfig.shiftConfig
11562
+ );
11582
11563
  shiftStr = currentShift.shiftId.toString();
11583
- console.log(`[usePrefetchClipCounts] Using current operational shift: ${shiftStr} (${currentShift.shiftName})`);
11564
+ console.log(`[usePrefetchClipCounts] Using current operational shift: ${shiftStr}`);
11584
11565
  }
11585
11566
  return {
11586
11567
  workspaceId: workspaceId || "",
@@ -26917,11 +26898,14 @@ var BottlenecksContent = ({
26917
26898
  console.log(`[BottlenecksContent] No shift provided for historical date ${date}, defaulting to day shift (0)`);
26918
26899
  return "0";
26919
26900
  } else {
26920
- const currentShift = getCurrentShift2();
26921
- console.log(`[BottlenecksContent] Using current operational shift: ${currentShift.shiftId} (${currentShift.shiftName})`);
26901
+ const currentShift = getCurrentShift(
26902
+ dashboardConfig.dateTimeConfig?.defaultTimezone || "Asia/Kolkata",
26903
+ dashboardConfig.shiftConfig
26904
+ );
26905
+ console.log(`[BottlenecksContent] Using current operational shift: ${currentShift.shiftId}`);
26922
26906
  return currentShift.shiftId.toString();
26923
26907
  }
26924
- }, [shift, date]);
26908
+ }, [shift, date, dashboardConfig]);
26925
26909
  const {
26926
26910
  data: prefetchData,
26927
26911
  isFullyIndexed,
@@ -28633,7 +28617,6 @@ var WorkspaceHealthCard = ({
28633
28617
  };
28634
28618
  const config = getStatusConfig();
28635
28619
  const StatusIcon = config.icon;
28636
- workspace.isStale ? WifiOff : Wifi;
28637
28620
  const handleClick = () => {
28638
28621
  if (onClick) {
28639
28622
  onClick(workspace);
@@ -28681,34 +28664,13 @@ var WorkspaceHealthCard = ({
28681
28664
  /* @__PURE__ */ jsx("span", { children: config.statusText })
28682
28665
  ] })
28683
28666
  ] }),
28684
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
28685
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
28686
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
28687
- /* @__PURE__ */ jsx(Clock, { className: "h-3.5 w-3.5 text-gray-400" }),
28688
- /* @__PURE__ */ jsxs("span", { className: "text-sm text-gray-600 dark:text-gray-400 whitespace-nowrap", children: [
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" })
28667
+ /* @__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: [
28668
+ /* @__PURE__ */ jsx(Clock, { className: "h-3.5 w-3.5 text-gray-400" }),
28669
+ /* @__PURE__ */ jsxs("span", { className: "text-sm text-gray-600 dark:text-gray-400 whitespace-nowrap", children: [
28670
+ "Last seen: ",
28671
+ /* @__PURE__ */ jsx("span", { className: "font-medium", children: formatTimeAgo(workspace.timeSinceLastUpdate) })
28710
28672
  ] })
28711
- ] })
28673
+ ] }) }) })
28712
28674
  ] })
28713
28675
  }
28714
28676
  );
@@ -28789,16 +28751,16 @@ var CompactWorkspaceHealthCard = ({
28789
28751
  var HealthStatusGrid = ({
28790
28752
  workspaces,
28791
28753
  onWorkspaceClick,
28792
- viewMode: initialViewMode = "grid",
28793
28754
  showFilters = true,
28794
28755
  groupBy: initialGroupBy = "none",
28795
28756
  className = ""
28796
28757
  }) => {
28797
- const [viewMode, setViewMode] = useState(initialViewMode);
28798
28758
  const [searchTerm, setSearchTerm] = useState("");
28799
28759
  const [statusFilter, setStatusFilter] = useState("all");
28800
28760
  const [groupBy, setGroupBy] = useState(initialGroupBy);
28801
28761
  const [expandedGroups, setExpandedGroups] = useState(/* @__PURE__ */ new Set());
28762
+ const lastGroupByRef = useRef(initialGroupBy);
28763
+ const hasInitializedGroupsRef = useRef(false);
28802
28764
  const filteredWorkspaces = useMemo(() => {
28803
28765
  let filtered = [...workspaces];
28804
28766
  if (searchTerm) {
@@ -28839,7 +28801,17 @@ var HealthStatusGrid = ({
28839
28801
  return sortedGroups;
28840
28802
  }, [filteredWorkspaces, groupBy]);
28841
28803
  useEffect(() => {
28842
- if (groupBy !== "none") {
28804
+ if (groupBy !== lastGroupByRef.current) {
28805
+ lastGroupByRef.current = groupBy;
28806
+ hasInitializedGroupsRef.current = false;
28807
+ if (groupBy === "none") {
28808
+ setExpandedGroups(/* @__PURE__ */ new Set());
28809
+ }
28810
+ }
28811
+ }, [groupBy]);
28812
+ useEffect(() => {
28813
+ if (groupBy !== "none" && !hasInitializedGroupsRef.current && Object.keys(groupedWorkspaces).length > 0) {
28814
+ hasInitializedGroupsRef.current = true;
28843
28815
  setExpandedGroups(new Set(Object.keys(groupedWorkspaces)));
28844
28816
  }
28845
28817
  }, [groupBy, groupedWorkspaces]);
@@ -28883,13 +28855,13 @@ var HealthStatusGrid = ({
28883
28855
  ] }) }),
28884
28856
  /* @__PURE__ */ jsxs(Select, { value: statusFilter, onValueChange: (value) => setStatusFilter(value), children: [
28885
28857
  /* @__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: [
28858
+ /* @__PURE__ */ jsxs(SelectContent, { className: "bg-white border border-gray-200 shadow-lg", children: [
28859
+ /* @__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
28860
  "All (",
28889
28861
  workspaces.length,
28890
28862
  ")"
28891
28863
  ] }),
28892
- /* @__PURE__ */ jsx(SelectItem, { value: "healthy", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
28864
+ /* @__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
28865
  /* @__PURE__ */ jsx("div", { className: "h-2 w-2 rounded-full bg-green-500" }),
28894
28866
  /* @__PURE__ */ jsxs("span", { children: [
28895
28867
  "Healthy (",
@@ -28897,7 +28869,7 @@ var HealthStatusGrid = ({
28897
28869
  ")"
28898
28870
  ] })
28899
28871
  ] }) }),
28900
- /* @__PURE__ */ jsx(SelectItem, { value: "unhealthy", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
28872
+ /* @__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
28873
  /* @__PURE__ */ jsx("div", { className: "h-2 w-2 rounded-full bg-red-500" }),
28902
28874
  /* @__PURE__ */ jsxs("span", { children: [
28903
28875
  "Unhealthy (",
@@ -28905,57 +28877,23 @@ var HealthStatusGrid = ({
28905
28877
  ")"
28906
28878
  ] })
28907
28879
  ] }) }),
28908
- /* @__PURE__ */ jsx(SelectItem, { value: "warning", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
28880
+ /* @__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
28881
  /* @__PURE__ */ jsx("div", { className: "h-2 w-2 rounded-full bg-yellow-500" }),
28910
28882
  /* @__PURE__ */ jsxs("span", { children: [
28911
28883
  "Warning (",
28912
28884
  statusCounts.warning,
28913
28885
  ")"
28914
28886
  ] })
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
28887
  ] }) })
28924
28888
  ] })
28925
28889
  ] }),
28926
28890
  /* @__PURE__ */ jsxs(Select, { value: groupBy, onValueChange: (value) => setGroupBy(value), children: [
28927
28891
  /* @__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" })
28892
+ /* @__PURE__ */ jsxs(SelectContent, { className: "bg-white border border-gray-200 shadow-lg", children: [
28893
+ /* @__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" }),
28894
+ /* @__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" }),
28895
+ /* @__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
28896
  ] })
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
28897
  ] })
28960
28898
  ] }),
28961
28899
  /* @__PURE__ */ jsxs("div", { className: "mt-3 text-sm text-gray-500 dark:text-gray-400", children: [
@@ -28995,32 +28933,15 @@ var HealthStatusGrid = ({
28995
28933
  ]
28996
28934
  }
28997
28935
  ),
28998
- isExpanded && /* @__PURE__ */ jsx(
28999
- "div",
28936
+ 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(
28937
+ WorkspaceHealthCard,
29000
28938
  {
29001
- className: clsx(
29002
- viewMode === "grid" ? "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4" : "space-y-2"
29003
- ),
29004
- children: groupWorkspaces.map(
29005
- (workspace) => viewMode === "grid" ? /* @__PURE__ */ jsx(
29006
- WorkspaceHealthCard,
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
- )
28939
+ workspace,
28940
+ onClick: onWorkspaceClick,
28941
+ showDetails: true
28942
+ },
28943
+ workspace.workspace_id
28944
+ )) })
29024
28945
  ] }, groupName);
29025
28946
  }) }),
29026
28947
  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 +37663,23 @@ var WorkspaceDetailView = ({
37742
37663
  "aria-label": "Navigate back to previous page"
37743
37664
  }
37744
37665
  ) }),
37745
- /* @__PURE__ */ jsx("div", { className: "absolute left-1/2 transform -translate-x-1/2", children: /* @__PURE__ */ jsx("h1", { className: "text-3xl font-semibold text-gray-900", children: formattedWorkspaceName }) }),
37666
+ /* @__PURE__ */ jsx("div", { className: "absolute left-1/2 transform -translate-x-1/2", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
37667
+ /* @__PURE__ */ jsx("h1", { className: "text-3xl font-semibold text-gray-900", children: formattedWorkspaceName }),
37668
+ workspaceHealth && /* @__PURE__ */ jsxs("div", { className: "relative flex h-2.5 w-2.5", children: [
37669
+ /* @__PURE__ */ jsx("span", { className: clsx(
37670
+ "animate-ping absolute inline-flex h-full w-full rounded-full opacity-75",
37671
+ workspaceHealth.status === "healthy" ? "bg-green-400" : "bg-red-400"
37672
+ ) }),
37673
+ /* @__PURE__ */ jsx("span", { className: clsx(
37674
+ "relative inline-flex rounded-full h-2.5 w-2.5",
37675
+ workspaceHealth.status === "healthy" ? "bg-green-500" : "bg-red-500"
37676
+ ) })
37677
+ ] })
37678
+ ] }) }),
37679
+ 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: [
37680
+ "Last update: ",
37681
+ workspaceHealth.timeSinceLastUpdate
37682
+ ] }) }),
37746
37683
  /* @__PURE__ */ jsx("div", { className: "w-full h-8" })
37747
37684
  ] }),
37748
37685
  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 +37707,6 @@ var WorkspaceDetailView = ({
37770
37707
  workspace.shift_type,
37771
37708
  " Shift"
37772
37709
  ] })
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
37710
  ] })
37787
37711
  ] }) }),
37788
37712
  /* @__PURE__ */ jsxs("div", { className: "mt-1 sm:mt-1.5 lg:mt-2 flex items-center justify-between", children: [
@@ -38326,7 +38250,6 @@ var WorkspaceHealthView = ({
38326
38250
  className = ""
38327
38251
  }) => {
38328
38252
  const router = useRouter();
38329
- const [viewMode, setViewMode] = useState("grid");
38330
38253
  const [groupBy, setGroupBy] = useState("line");
38331
38254
  const operationalDate = getOperationalDate();
38332
38255
  const currentHour = (/* @__PURE__ */ new Date()).getHours();
@@ -38491,7 +38414,7 @@ var WorkspaceHealthView = ({
38491
38414
  transition: { duration: 0.3, delay: 0.1 },
38492
38415
  className: "grid grid-cols-2 sm:grid-cols-2 md:grid-cols-5 gap-2 sm:gap-3 lg:gap-4",
38493
38416
  children: [
38494
- /* @__PURE__ */ jsxs(Card2, { className: "col-span-2 sm:col-span-2 md:col-span-2", children: [
38417
+ /* @__PURE__ */ jsxs(Card2, { className: "col-span-2 sm:col-span-2 md:col-span-2 bg-white", children: [
38495
38418
  /* @__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
38419
  /* @__PURE__ */ jsxs(CardContent2, { children: [
38497
38420
  /* @__PURE__ */ jsxs("div", { className: "flex items-baseline gap-2", children: [
@@ -38509,33 +38432,33 @@ var WorkspaceHealthView = ({
38509
38432
  ] })
38510
38433
  ] })
38511
38434
  ] }),
38512
- /* @__PURE__ */ jsxs(Card2, { children: [
38435
+ /* @__PURE__ */ jsxs(Card2, { className: "bg-white", children: [
38513
38436
  /* @__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
38437
  getStatusIcon("healthy"),
38515
38438
  "Healthy"
38516
38439
  ] }) }),
38517
38440
  /* @__PURE__ */ jsxs(CardContent2, { children: [
38518
- /* @__PURE__ */ jsx("p", { className: "text-2xl font-bold text-green-600 dark:text-green-400", children: summary.healthyWorkspaces }),
38441
+ /* @__PURE__ */ jsx("p", { className: "text-2xl font-bold text-gray-900 dark:text-gray-50", children: summary.healthyWorkspaces }),
38519
38442
  /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: "Operating normally" })
38520
38443
  ] })
38521
38444
  ] }),
38522
- /* @__PURE__ */ jsxs(Card2, { children: [
38445
+ /* @__PURE__ */ jsxs(Card2, { className: "bg-white", children: [
38523
38446
  /* @__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
38447
  getStatusIcon("warning"),
38525
38448
  "Warning"
38526
38449
  ] }) }),
38527
38450
  /* @__PURE__ */ jsxs(CardContent2, { children: [
38528
- /* @__PURE__ */ jsx("p", { className: "text-2xl font-bold text-yellow-600 dark:text-yellow-400", children: summary.warningWorkspaces }),
38451
+ /* @__PURE__ */ jsx("p", { className: "text-2xl font-bold text-gray-900 dark:text-gray-50", children: summary.warningWorkspaces }),
38529
38452
  /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: "Delayed updates" })
38530
38453
  ] })
38531
38454
  ] }),
38532
- /* @__PURE__ */ jsxs(Card2, { children: [
38455
+ /* @__PURE__ */ jsxs(Card2, { className: "bg-white", children: [
38533
38456
  /* @__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
38457
  getStatusIcon("unhealthy"),
38535
38458
  "Unhealthy"
38536
38459
  ] }) }),
38537
38460
  /* @__PURE__ */ jsxs(CardContent2, { children: [
38538
- /* @__PURE__ */ jsx("p", { className: "text-2xl font-bold text-red-600 dark:text-red-400", children: summary.unhealthyWorkspaces }),
38461
+ /* @__PURE__ */ jsx("p", { className: "text-2xl font-bold text-gray-900 dark:text-gray-50", children: summary.unhealthyWorkspaces }),
38539
38462
  /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: "Requires attention" })
38540
38463
  ] })
38541
38464
  ] })
@@ -38553,7 +38476,6 @@ var WorkspaceHealthView = ({
38553
38476
  {
38554
38477
  workspaces,
38555
38478
  onWorkspaceClick: handleWorkspaceClick,
38556
- viewMode,
38557
38479
  showFilters: true,
38558
38480
  groupBy
38559
38481
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optifye/dashboard-core",
3
- "version": "6.5.0",
3
+ "version": "6.5.1",
4
4
  "description": "Reusable UI & logic for Optifye dashboard",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",