@optifye/dashboard-core 6.12.10 → 6.12.12

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
@@ -1262,6 +1262,9 @@ body {
1262
1262
  .min-h-\[80px\] {
1263
1263
  min-height: 80px;
1264
1264
  }
1265
+ .min-h-\[92px\] {
1266
+ min-height: 92px;
1267
+ }
1265
1268
  .min-h-\[calc\(100dvh-12rem\)\] {
1266
1269
  min-height: calc(100dvh - 12rem);
1267
1270
  }
@@ -1892,6 +1895,9 @@ body {
1892
1895
  .flex-nowrap {
1893
1896
  flex-wrap: nowrap;
1894
1897
  }
1898
+ .content-start {
1899
+ align-content: flex-start;
1900
+ }
1895
1901
  .items-start {
1896
1902
  align-items: flex-start;
1897
1903
  }
package/dist/index.js CHANGED
@@ -37759,6 +37759,8 @@ var VideoCard = React144__namespace.default.memo(({
37759
37759
  VideoCard.displayName = "VideoCard";
37760
37760
  var DEFAULT_HLS_URL = "https://192.168.5.9:8443/cam1.m3u8";
37761
37761
  var DEBUG_DASHBOARD_LOGS2 = process.env.NEXT_PUBLIC_DEBUG_DASHBOARD === "true";
37762
+ var MOBILE_SCROLL_THRESHOLD = 15;
37763
+ var MOBILE_BREAKPOINT_PX = 640;
37762
37764
  var logDebug2 = (...args) => {
37763
37765
  if (!DEBUG_DASHBOARD_LOGS2) return;
37764
37766
  console.log(...args);
@@ -37780,6 +37782,7 @@ var VideoGridView = React144__namespace.default.memo(({
37780
37782
  const observerRef = React144.useRef(null);
37781
37783
  const [gridCols, setGridCols] = React144.useState(4);
37782
37784
  const [gridRows, setGridRows] = React144.useState(1);
37785
+ const [isMobileScrollableGrid, setIsMobileScrollableGrid] = React144.useState(false);
37783
37786
  const [visibleWorkspaces, setVisibleWorkspaces] = React144.useState(/* @__PURE__ */ new Set());
37784
37787
  const [failedStreams, setFailedStreams] = React144.useState(/* @__PURE__ */ new Set());
37785
37788
  const [r2FallbackWorkspaces, setR2FallbackWorkspaces] = React144.useState(/* @__PURE__ */ new Set());
@@ -37893,13 +37896,17 @@ var VideoGridView = React144__namespace.default.memo(({
37893
37896
  const calculateOptimalGrid = React144.useCallback(() => {
37894
37897
  if (!containerRef.current) return;
37895
37898
  const containerPadding = 16;
37896
- const containerWidth = containerRef.current.clientWidth - containerPadding;
37899
+ const rawContainerWidth = containerRef.current.clientWidth;
37900
+ const containerWidth = rawContainerWidth - containerPadding;
37897
37901
  const containerHeight = containerRef.current.clientHeight - containerPadding;
37898
37902
  const count = filteredWorkspaces.length;
37899
37903
  if (count === 0) {
37900
37904
  setGridCols(1);
37905
+ setGridRows(1);
37906
+ setIsMobileScrollableGrid(false);
37901
37907
  return;
37902
37908
  }
37909
+ const shouldUseMobileScroll = rawContainerWidth < MOBILE_BREAKPOINT_PX && count >= MOBILE_SCROLL_THRESHOLD;
37903
37910
  const optimalLayouts = {
37904
37911
  1: 1,
37905
37912
  2: 2,
@@ -37937,11 +37944,12 @@ var VideoGridView = React144__namespace.default.memo(({
37937
37944
  const availableWidth = containerWidth - gap * (bestCols - 1);
37938
37945
  const cellWidth = availableWidth / bestCols;
37939
37946
  if (cellWidth < minCellWidth && bestCols > 1) {
37940
- bestCols = Math.floor((containerWidth + gap) / (minCellWidth + gap));
37947
+ bestCols = Math.max(1, Math.floor((containerWidth + gap) / (minCellWidth + gap)));
37941
37948
  }
37942
37949
  const rows = Math.ceil(count / bestCols);
37943
37950
  setGridCols(bestCols);
37944
37951
  setGridRows(rows);
37952
+ setIsMobileScrollableGrid(shouldUseMobileScroll);
37945
37953
  }, [filteredWorkspaces.length, selectedLine]);
37946
37954
  React144.useEffect(() => {
37947
37955
  calculateOptimalGrid();
@@ -38155,21 +38163,27 @@ var VideoGridView = React144__namespace.default.memo(({
38155
38163
  resolveWorkspaceDisplayName,
38156
38164
  selectedLine
38157
38165
  ]);
38158
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `relative overflow-hidden h-full w-full bg-slate-50/30 ${className}`, children: /* @__PURE__ */ jsxRuntime.jsx(
38166
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `relative h-full min-h-0 w-full overflow-hidden bg-slate-50/30 ${className}`, children: /* @__PURE__ */ jsxRuntime.jsx(
38159
38167
  "div",
38160
38168
  {
38161
38169
  ref: containerRef,
38162
- className: "h-full w-full px-1 sm:px-2 py-1 sm:py-2 overflow-y-auto",
38170
+ "data-testid": "video-grid-scroll-container",
38171
+ "data-mobile-scrollable": isMobileScrollableGrid ? "true" : "false",
38172
+ className: `absolute inset-0 w-full px-1 py-1 sm:px-2 sm:py-2 ${isMobileScrollableGrid ? "overflow-y-auto" : "overflow-hidden"}`,
38163
38173
  children: /* @__PURE__ */ jsxRuntime.jsx(
38164
38174
  "div",
38165
38175
  {
38166
- className: "grid h-full w-full gap-1.5 sm:gap-2",
38176
+ "data-testid": "video-grid-layout",
38177
+ className: `grid w-full gap-1.5 sm:gap-2 ${isMobileScrollableGrid ? "content-start" : "h-full"}`,
38167
38178
  style: {
38168
38179
  gridTemplateColumns: `repeat(${gridCols}, 1fr)`,
38169
- gridTemplateRows: `repeat(${gridRows}, 1fr)`,
38180
+ gridTemplateRows: isMobileScrollableGrid ? void 0 : `repeat(${gridRows}, 1fr)`,
38170
38181
  gridAutoFlow: "row"
38171
38182
  },
38172
- children: workspaceCards.map((card) => renderWorkspaceCard(card, "workspace-card relative w-full h-full"))
38183
+ children: workspaceCards.map((card) => renderWorkspaceCard(
38184
+ card,
38185
+ isMobileScrollableGrid ? "workspace-card relative w-full aspect-video min-h-[92px]" : "workspace-card relative w-full h-full"
38186
+ ))
38173
38187
  }
38174
38188
  )
38175
38189
  }
@@ -50348,7 +50362,7 @@ var LineMonthlyHistory = ({
50348
50362
  { name: "Idle", value: idlePercent }
50349
50363
  ];
50350
50364
  }, [analysisMonthlyData, selectedShiftId, isUptimeMode]);
50351
- if (isLoading) {
50365
+ if (isLoading && analysisMonthlyData.length === 0) {
50352
50366
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center h-[calc(100vh-10rem)]", children: /* @__PURE__ */ jsxRuntime.jsx(
50353
50367
  OptifyeLogoLoader_default,
50354
50368
  {
package/dist/index.mjs CHANGED
@@ -37730,6 +37730,8 @@ var VideoCard = React144__default.memo(({
37730
37730
  VideoCard.displayName = "VideoCard";
37731
37731
  var DEFAULT_HLS_URL = "https://192.168.5.9:8443/cam1.m3u8";
37732
37732
  var DEBUG_DASHBOARD_LOGS2 = process.env.NEXT_PUBLIC_DEBUG_DASHBOARD === "true";
37733
+ var MOBILE_SCROLL_THRESHOLD = 15;
37734
+ var MOBILE_BREAKPOINT_PX = 640;
37733
37735
  var logDebug2 = (...args) => {
37734
37736
  if (!DEBUG_DASHBOARD_LOGS2) return;
37735
37737
  console.log(...args);
@@ -37751,6 +37753,7 @@ var VideoGridView = React144__default.memo(({
37751
37753
  const observerRef = useRef(null);
37752
37754
  const [gridCols, setGridCols] = useState(4);
37753
37755
  const [gridRows, setGridRows] = useState(1);
37756
+ const [isMobileScrollableGrid, setIsMobileScrollableGrid] = useState(false);
37754
37757
  const [visibleWorkspaces, setVisibleWorkspaces] = useState(/* @__PURE__ */ new Set());
37755
37758
  const [failedStreams, setFailedStreams] = useState(/* @__PURE__ */ new Set());
37756
37759
  const [r2FallbackWorkspaces, setR2FallbackWorkspaces] = useState(/* @__PURE__ */ new Set());
@@ -37864,13 +37867,17 @@ var VideoGridView = React144__default.memo(({
37864
37867
  const calculateOptimalGrid = useCallback(() => {
37865
37868
  if (!containerRef.current) return;
37866
37869
  const containerPadding = 16;
37867
- const containerWidth = containerRef.current.clientWidth - containerPadding;
37870
+ const rawContainerWidth = containerRef.current.clientWidth;
37871
+ const containerWidth = rawContainerWidth - containerPadding;
37868
37872
  const containerHeight = containerRef.current.clientHeight - containerPadding;
37869
37873
  const count = filteredWorkspaces.length;
37870
37874
  if (count === 0) {
37871
37875
  setGridCols(1);
37876
+ setGridRows(1);
37877
+ setIsMobileScrollableGrid(false);
37872
37878
  return;
37873
37879
  }
37880
+ const shouldUseMobileScroll = rawContainerWidth < MOBILE_BREAKPOINT_PX && count >= MOBILE_SCROLL_THRESHOLD;
37874
37881
  const optimalLayouts = {
37875
37882
  1: 1,
37876
37883
  2: 2,
@@ -37908,11 +37915,12 @@ var VideoGridView = React144__default.memo(({
37908
37915
  const availableWidth = containerWidth - gap * (bestCols - 1);
37909
37916
  const cellWidth = availableWidth / bestCols;
37910
37917
  if (cellWidth < minCellWidth && bestCols > 1) {
37911
- bestCols = Math.floor((containerWidth + gap) / (minCellWidth + gap));
37918
+ bestCols = Math.max(1, Math.floor((containerWidth + gap) / (minCellWidth + gap)));
37912
37919
  }
37913
37920
  const rows = Math.ceil(count / bestCols);
37914
37921
  setGridCols(bestCols);
37915
37922
  setGridRows(rows);
37923
+ setIsMobileScrollableGrid(shouldUseMobileScroll);
37916
37924
  }, [filteredWorkspaces.length, selectedLine]);
37917
37925
  useEffect(() => {
37918
37926
  calculateOptimalGrid();
@@ -38126,21 +38134,27 @@ var VideoGridView = React144__default.memo(({
38126
38134
  resolveWorkspaceDisplayName,
38127
38135
  selectedLine
38128
38136
  ]);
38129
- return /* @__PURE__ */ jsx("div", { className: `relative overflow-hidden h-full w-full bg-slate-50/30 ${className}`, children: /* @__PURE__ */ jsx(
38137
+ return /* @__PURE__ */ jsx("div", { className: `relative h-full min-h-0 w-full overflow-hidden bg-slate-50/30 ${className}`, children: /* @__PURE__ */ jsx(
38130
38138
  "div",
38131
38139
  {
38132
38140
  ref: containerRef,
38133
- className: "h-full w-full px-1 sm:px-2 py-1 sm:py-2 overflow-y-auto",
38141
+ "data-testid": "video-grid-scroll-container",
38142
+ "data-mobile-scrollable": isMobileScrollableGrid ? "true" : "false",
38143
+ className: `absolute inset-0 w-full px-1 py-1 sm:px-2 sm:py-2 ${isMobileScrollableGrid ? "overflow-y-auto" : "overflow-hidden"}`,
38134
38144
  children: /* @__PURE__ */ jsx(
38135
38145
  "div",
38136
38146
  {
38137
- className: "grid h-full w-full gap-1.5 sm:gap-2",
38147
+ "data-testid": "video-grid-layout",
38148
+ className: `grid w-full gap-1.5 sm:gap-2 ${isMobileScrollableGrid ? "content-start" : "h-full"}`,
38138
38149
  style: {
38139
38150
  gridTemplateColumns: `repeat(${gridCols}, 1fr)`,
38140
- gridTemplateRows: `repeat(${gridRows}, 1fr)`,
38151
+ gridTemplateRows: isMobileScrollableGrid ? void 0 : `repeat(${gridRows}, 1fr)`,
38141
38152
  gridAutoFlow: "row"
38142
38153
  },
38143
- children: workspaceCards.map((card) => renderWorkspaceCard(card, "workspace-card relative w-full h-full"))
38154
+ children: workspaceCards.map((card) => renderWorkspaceCard(
38155
+ card,
38156
+ isMobileScrollableGrid ? "workspace-card relative w-full aspect-video min-h-[92px]" : "workspace-card relative w-full h-full"
38157
+ ))
38144
38158
  }
38145
38159
  )
38146
38160
  }
@@ -50319,7 +50333,7 @@ var LineMonthlyHistory = ({
50319
50333
  { name: "Idle", value: idlePercent }
50320
50334
  ];
50321
50335
  }, [analysisMonthlyData, selectedShiftId, isUptimeMode]);
50322
- if (isLoading) {
50336
+ if (isLoading && analysisMonthlyData.length === 0) {
50323
50337
  return /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center h-[calc(100vh-10rem)]", children: /* @__PURE__ */ jsx(
50324
50338
  OptifyeLogoLoader_default,
50325
50339
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optifye/dashboard-core",
3
- "version": "6.12.10",
3
+ "version": "6.12.12",
4
4
  "description": "Reusable UI & logic for Optifye dashboard",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",