@gen3/workspaces 0.12.50 → 0.12.52

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.
Files changed (39) hide show
  1. package/TODO.md +2 -2
  2. package/dist/dts/components/HorizontalAccordian.js +2 -2
  3. package/dist/dts/components/HorizontalAccordian.js.map +1 -1
  4. package/dist/dts/components/KernelLifecyclePanel/ActiveKernelsPanel.d.ts.map +1 -1
  5. package/dist/dts/components/KernelLifecyclePanel/ActiveKernelsPanel.js +2 -0
  6. package/dist/dts/components/KernelLifecyclePanel/ActiveKernelsPanel.js.map +1 -1
  7. package/dist/dts/components/MicroContainerReduxPanel.d.ts.map +1 -1
  8. package/dist/dts/components/MicroContainerReduxPanel.js +13 -13
  9. package/dist/dts/components/MicroContainerReduxPanel.js.map +1 -1
  10. package/dist/dts/core/hatcheryApi.d.ts.map +1 -1
  11. package/dist/dts/core/hatcheryApi.js +21 -6
  12. package/dist/dts/core/hatcheryApi.js.map +1 -1
  13. package/dist/dts/core/jegGatewayApi.d.ts +67 -0
  14. package/dist/dts/core/jegGatewayApi.d.ts.map +1 -1
  15. package/dist/dts/core/jegGatewayApi.js +2 -0
  16. package/dist/dts/core/jegGatewayApi.js.map +1 -1
  17. package/dist/dts/providers/useGatewayConnectionStatus.d.ts.map +1 -1
  18. package/dist/dts/providers/useGatewayConnectionStatus.js +5 -1
  19. package/dist/dts/providers/useGatewayConnectionStatus.js.map +1 -1
  20. package/dist/dts/providers/useJEGWorkspaceResourceMonitor.d.ts.map +1 -1
  21. package/dist/dts/providers/useJEGWorkspaceResourceMonitor.js +69 -41
  22. package/dist/dts/providers/useJEGWorkspaceResourceMonitor.js.map +1 -1
  23. package/dist/dts/providers/useMicroContainerRedux.d.ts.map +1 -1
  24. package/dist/dts/providers/useMicroContainerRedux.js +7 -14
  25. package/dist/dts/providers/useMicroContainerRedux.js.map +1 -1
  26. package/dist/dts/server/workspaceAssetsHandler.js +2 -2
  27. package/dist/dts/server/workspaceAssetsHandler.js.map +1 -1
  28. package/dist/dts/workspace/WorkspaceLayout/SettingsPanel.d.ts.map +1 -1
  29. package/dist/dts/workspace/WorkspaceLayout/SettingsPanel.js +1 -2
  30. package/dist/dts/workspace/WorkspaceLayout/SettingsPanel.js.map +1 -1
  31. package/dist/index/cjs/index.js +128 -83
  32. package/dist/index/cjs/index.js.map +1 -1
  33. package/dist/index/esm/index.js +128 -83
  34. package/dist/index/esm/index.js.map +1 -1
  35. package/dist/server/cjs/server.js +2 -2
  36. package/dist/server/cjs/server.js.map +1 -1
  37. package/dist/server/esm/server.js +2 -2
  38. package/dist/server/esm/server.js.map +1 -1
  39. package/package.json +4 -4
@@ -3,10 +3,10 @@ import React, { useCallback, useMemo, useState, useRef, useEffect, createContext
3
3
  import { mergeDefaultTailwindClassnames, ACTIVITY_CHANNEL, convertSecondsToMilliseconds, InfoRolloverButton, OverflowTooltippedLabel, PanelErrorBoundary, ProtectedContent, FixedNavPageLayout, ContentSource, getNavPageLayoutPropsFromConfig } from '@gen3/frontend';
4
4
  import { Card, Stack, Badge, Text, List, Group, Tooltip, Button, LoadingOverlay, Alert, Loader, Divider, Select, ActionIcon, TextInput, Textarea, Table, Scroller, Tabs, Center } from '@mantine/core';
5
5
  import { Icon } from '@iconify-icon/react';
6
+ import { useInterval, useElementSize, useDisclosure, useResizeObserver } from '@mantine/hooks';
6
7
  import { GEN3_API, GEN3_WORKSPACE_API, gen3Api, useCoreSelector, selectJEGActiveWorkspaceStatus, useCoreDispatch, setJEGActiveWorkspaceStatus, WorkspaceStatus, setJEGRequestedWorkspaceStatus, RequestedWorkspaceStatus, setJEGActiveWorkspaceId, isFetchBaseQueryError, selectJEGRequestedWorkspaceStatus, selectJEGRequestedWorkspaceStatusTimestamp, isTimeGreaterThan, formatUptimeInMinutes, selectJEGKernelIds, removeManyJEGActiveKernels, upsertManyJEGActiveKernels, normalizeRtkError, selectAllJEGKernels, addJEGActiveKernel, selectWorkspaceTier, setWorkspaceTier, selectWorkspaceFullscreen, setWorkspaceFullscreen, useGetDictionaryFromUrlQuery, useUserAuth, GEN3_COMMONS_NAME } from '@gen3/core';
7
8
  import { useDeepCompareEffect } from 'use-deep-compare';
8
9
  import { notifications } from '@mantine/notifications';
9
- import { useElementSize, useDisclosure, useResizeObserver } from '@mantine/hooks';
10
10
  import { IoSettingsSharp } from 'react-icons/io5';
11
11
  import { BsFillInfoCircleFill } from 'react-icons/bs';
12
12
  import { MdKeyboardArrowDown, MdKeyboardArrowRight } from 'react-icons/md';
@@ -337,22 +337,34 @@ const HatcheryWithTags = gen3Api.enhanceEndpoints({
337
337
  'Hatchery'
338
338
  ]
339
339
  });
340
- const StatusStringToHatcheryServiceStatus = {
341
- running: [
340
+ /*
341
+ * Hatchery states:
342
+ *
343
+ * `Terminating` - The workspace is shutting down
344
+ * `Launching` - The workspace is starting up
345
+ * `Stopped` - The workspace is in a failed state and must be terminated
346
+ * `Running` - The workspace is running and ready to be used
347
+ * `Not Found` - The workspace could not be found
348
+ */ const StatusStringToHatcheryServiceStatus = {
349
+ launching: [
342
350
  'launching',
343
351
  'pending',
344
- 'starting',
352
+ 'starting'
353
+ ],
354
+ running: [
345
355
  'running',
346
356
  'ready'
347
357
  ],
348
358
  stopped: [
349
- 'not-running',
350
- 'stopped',
351
- 'terminated'
359
+ 'stopped'
352
360
  ],
353
- terminated: [
361
+ terminating: [
354
362
  'terminating',
355
363
  'stopping'
364
+ ],
365
+ unknown: [
366
+ 'not found',
367
+ 'unknown'
356
368
  ]
357
369
  };
358
370
  const hatcheryApi = HatcheryWithTags.injectEndpoints({
@@ -395,17 +407,22 @@ const hatcheryApi = HatcheryWithTags.injectEndpoints({
395
407
  transformResponse: (response)=>{
396
408
  const results = (response.status || 'unknown').toLowerCase();
397
409
  let hatcheryStatus = HatcheryServiceState.unknown;
398
- if (results === 'not found' || results === 'unknown') hatcheryStatus = HatcheryServiceState.unknown;
410
+ if (StatusStringToHatcheryServiceStatus.unknown.includes(results)) {
411
+ hatcheryStatus = HatcheryServiceState.unknown;
412
+ }
413
+ if (StatusStringToHatcheryServiceStatus.launching.includes(results)) {
414
+ hatcheryStatus = HatcheryServiceState.launching;
415
+ }
399
416
  if (StatusStringToHatcheryServiceStatus.running.includes(results)) {
400
417
  hatcheryStatus = HatcheryServiceState.running;
401
418
  }
402
419
  if (StatusStringToHatcheryServiceStatus.stopped.includes(results)) {
403
420
  hatcheryStatus = HatcheryServiceState.stopped;
404
421
  }
405
- if (StatusStringToHatcheryServiceStatus.terminated.includes(results)) {
422
+ if (StatusStringToHatcheryServiceStatus.terminating.includes(results)) {
406
423
  hatcheryStatus = HatcheryServiceState.terminating;
407
424
  }
408
- // return other status
425
+ // return other stats from the hatchery response
409
426
  return {
410
427
  status: hatcheryStatus,
411
428
  idleTimeLimit: response.idleTimeLimit,
@@ -557,7 +574,7 @@ const { useDoesHatcheryOptionExistsQuery, useHatcheryOptionsQuery, useLazyHatche
557
574
  const workspaceContainerStatus = useCoreSelector(selectJEGActiveWorkspaceStatus);
558
575
  const [containerHash, setContainerHash] = useState(null);
559
576
  const coreDispatch = useCoreDispatch();
560
- // get the options for the workspace could move to parent since
577
+ // get the options for the workspace could move to parent
561
578
  const { data: optionData, error: optionsError } = useDoesHatcheryOptionExistsQuery(tag, {
562
579
  skip: containerHash !== null
563
580
  });
@@ -595,7 +612,8 @@ const { useDoesHatcheryOptionExistsQuery, useHatcheryOptionsQuery, useLazyHatche
595
612
  // launch error, will show error message and then reset
596
613
  coreDispatch(setJEGActiveWorkspaceStatus(WorkspaceStatus.LaunchError));
597
614
  } else {
598
- coreDispatch(setJEGActiveWorkspaceStatus(WorkspaceStatus.Running));
615
+ // Keep status as Launching — the monitor will promote to Running
616
+ // once the pod actually reports running status
599
617
  coreDispatch(setJEGActiveWorkspaceId({
600
618
  id: containerHash ?? 'default'
601
619
  }));
@@ -614,18 +632,11 @@ const { useDoesHatcheryOptionExistsQuery, useHatcheryOptionsQuery, useLazyHatche
614
632
  ]);
615
633
  const terminate = useCallback(async ()=>{
616
634
  if (!enabled || workspaceContainerStatus === WorkspaceStatus.Terminating) return; // skip if already terminating
617
- // coreDispatch(setJEGActiveWorkspaceStatus(WorkspaceStatus.Running));
618
635
  const containerId = containerHash ? encodeURIComponent(containerHash) : '';
619
- try {
620
- //
621
- // const status = await terminateWorkspace(containerId).unwrap();
622
- terminateWorkspace(containerId);
623
- coreDispatch(setJEGRequestedWorkspaceStatus(RequestedWorkspaceStatus.Terminate));
624
- coreDispatch(setJEGActiveWorkspaceStatus(WorkspaceStatus.Terminating));
625
- } catch (_error) {
626
- coreDispatch(setJEGRequestedWorkspaceStatus(RequestedWorkspaceStatus.Terminate));
627
- coreDispatch(setJEGActiveWorkspaceStatus(WorkspaceStatus.Terminating));
628
- }
636
+ // Fire-and-forget: errors are handled by the useDeepCompareEffect watching isTerminateError
637
+ terminateWorkspace(containerId);
638
+ coreDispatch(setJEGRequestedWorkspaceStatus(RequestedWorkspaceStatus.Terminate));
639
+ coreDispatch(setJEGActiveWorkspaceStatus(WorkspaceStatus.Terminating));
629
640
  }, [
630
641
  enabled,
631
642
  workspaceContainerStatus,
@@ -682,10 +693,10 @@ const notifyUser = (title, message, status = 0)=>{
682
693
  // TODO: convert to seconds/minutes for readability
683
694
  const WorkspacePollingInterval = {
684
695
  [WorkspaceStatus.NotFound]: 0,
685
- [WorkspaceStatus.Launching]: convertSecondsToMilliseconds(1),
686
- [WorkspaceStatus.Terminating]: convertSecondsToMilliseconds(1),
687
- [WorkspaceStatus.Running]: convertSecondsToMilliseconds(300),
688
- [WorkspaceStatus.Stopped]: convertSecondsToMilliseconds(5),
696
+ [WorkspaceStatus.Launching]: convertSecondsToMilliseconds(5),
697
+ [WorkspaceStatus.Terminating]: convertSecondsToMilliseconds(5),
698
+ [WorkspaceStatus.Running]: convertSecondsToMilliseconds(60),
699
+ [WorkspaceStatus.Stopped]: convertSecondsToMilliseconds(60),
689
700
  [WorkspaceStatus.Errored]: convertSecondsToMilliseconds(10),
690
701
  [WorkspaceStatus.LaunchError]: convertSecondsToMilliseconds(10),
691
702
  [WorkspaceStatus.TerminateError]: convertSecondsToMilliseconds(10),
@@ -696,7 +707,8 @@ const workspaceShutdownAlertLimit = 30000; // 5 minutes: 5 * 60 * 1000 TODO Figu
696
707
  * Monitors resource usage.
697
708
  * Handles state changes and polls for workspace status using the JEG APIs
698
709
  */ const useJEGWorkspaceResourceMonitor = (workspaceId = null, monitorWorkspace)=>{
699
- const [pollingInterval, setPollingInterval] = useState(0);
710
+ // start with default polling interval of 1 second
711
+ const [pollingInterval, setPollingInterval] = useState(convertSecondsToMilliseconds(1));
700
712
  const [error, setError] = useState(null);
701
713
  const { data: workspaceStatusData, isError: isWorkspaceStatusError, error: workspaceStatusError } = useHatcheryStatusQuery(workspaceId, {
702
714
  pollingInterval: pollingInterval,
@@ -742,17 +754,37 @@ const workspaceShutdownAlertLimit = 30000; // 5 minutes: 5 * 60 * 1000 TODO Figu
742
754
  error
743
755
  ]);
744
756
  useDeepCompareEffect(()=>{
757
+ // No status data means we are not polling
745
758
  if (!workspaceStatusData) return;
746
- // LaunchError is set client-side by the launch() call and cleared by the
759
+ // LaunchError is set client-side by the launch() call from useMicroContainerRedux and cleared by the
747
760
  // auto-reset timer in the panel. Polling data must not override it or the
748
- // timer will be cancelled before it fires.
761
+ // timer will be canceled before it fires.
749
762
  if (activeStatus === WorkspaceStatus.LaunchError) return;
750
763
  const workspaceQueryStatus = hatcheryStateToWorkspaceStatus(workspaceStatusData?.status);
764
+ // handle cases of unknown, running, terminating, or launching
765
+ if (workspaceStatusData.status === HatcheryServiceState.unknown) {
766
+ // check for unknown state
767
+ // NotFound means pod is not running
768
+ // either starting up
769
+ // or finally terminated.
770
+ if (requestedStatus === RequestedWorkspaceStatus.Launch) {
771
+ // if the workspace becomes idle too long after a Launch request, switch to
772
+ // Unset and NotFound.
773
+ console.warn("requested status is Launch, but workspace pod isn't running yet.");
774
+ return;
775
+ }
776
+ // both requested status and workspace pod status are the same, so stop all polling
777
+ setPollingInterval(WorkspacePollingInterval[WorkspaceStatus.NotFound]);
778
+ dispatch(setJEGActiveWorkspaceStatus(WorkspaceStatus.NotFound));
779
+ if (requestedStatus === RequestedWorkspaceStatus.Terminate) {
780
+ // Cleanup termination after terminated
781
+ dispatch(setJEGRequestedWorkspaceStatus(RequestedWorkspaceStatus.Unset));
782
+ }
783
+ return;
784
+ }
751
785
  // Check if the workspace is running.
752
786
  // If so: need to check workspace idle if set
753
- // and ensure the pay model is queried
754
787
  if (workspaceStatusData.status === HatcheryServiceState.running) {
755
- // const { idleTimeLimit, lastActivityTime } = workspaceStatusData;
756
788
  // in some state other than idle
757
789
  if (!idleTimeLimit || idleTimeLimit <= 0) {
758
790
  // Workspace is running, but no idle limit set.
@@ -762,6 +794,7 @@ const workspaceShutdownAlertLimit = 30000; // 5 minutes: 5 * 60 * 1000 TODO Figu
762
794
  setPollingInterval(WorkspacePollingInterval[WorkspaceStatus.Running]);
763
795
  return;
764
796
  }
797
+ // handle if idle time is defined
765
798
  if (idleTimeLimit && idleTimeLimit > 0 && lastActivityTime && lastActivityTime > 0) {
766
799
  const remainingWorkspaceKernelLife = idleTimeLimit - (Date.now() - lastActivityTime);
767
800
  if (remainingWorkspaceKernelLife <= 0) {
@@ -769,7 +802,7 @@ const workspaceShutdownAlertLimit = 30000; // 5 minutes: 5 * 60 * 1000 TODO Figu
769
802
  // so terminate
770
803
  (async ()=>{
771
804
  try {
772
- if (workspaceId) await terminateWorkspace(workspaceId).unwrap();
805
+ if (workspaceId) await terminateWorkspace(encodeURIComponent(workspaceId)).unwrap();
773
806
  } catch (error) {
774
807
  const errorMessage = error.message || 'Unknown error occurred';
775
808
  console.error('Workspace termination failed: ', errorMessage);
@@ -786,44 +819,48 @@ const workspaceShutdownAlertLimit = 30000; // 5 minutes: 5 * 60 * 1000 TODO Figu
786
819
  setError('Workspace has been idle for too long. Will shutdown soon');
787
820
  }
788
821
  }
789
- if (requestedStatus === RequestedWorkspaceStatus.Launch) {
790
- // if we have a launch error then requested status has not been met
791
- if (workspaceQueryStatus === WorkspaceStatus.LaunchError) {
792
- dispatch(setJEGRequestedWorkspaceStatus(RequestedWorkspaceStatus.Unset));
793
- dispatch(setJEGActiveWorkspaceStatus(WorkspaceStatus.NotFound));
794
- return;
822
+ }
823
+ // Stopped means the pod is in a failed state — auto-terminate it
824
+ if (workspaceStatusData.status === HatcheryServiceState.stopped) {
825
+ (async ()=>{
826
+ try {
827
+ if (workspaceId) await terminateWorkspace(encodeURIComponent(workspaceId)).unwrap();
828
+ } catch (error) {
829
+ const errorMessage = error.message || 'Unknown error occurred';
830
+ console.error('Workspace termination of stopped pod failed: ', errorMessage);
831
+ notifyUser('Workspace Error', `Failed to terminate stopped workspace: ${errorMessage}`, 2);
795
832
  }
796
- // if the workspace is running then requested status has been met
833
+ })();
834
+ dispatch(setJEGRequestedWorkspaceStatus(RequestedWorkspaceStatus.Terminate));
835
+ dispatch(setJEGActiveWorkspaceStatus(WorkspaceStatus.Terminating));
836
+ setPollingInterval(WorkspacePollingInterval[WorkspaceStatus.Terminating]);
837
+ notifyUser('Workspace Stopped', 'Workspace entered a failed state and is being terminated', 2);
838
+ return;
839
+ }
840
+ if (requestedStatus === RequestedWorkspaceStatus.Launch) {
841
+ // if we have a launch error then requested status has not been met
842
+ if (workspaceQueryStatus === WorkspaceStatus.LaunchError) {
797
843
  dispatch(setJEGRequestedWorkspaceStatus(RequestedWorkspaceStatus.Unset));
844
+ dispatch(setJEGActiveWorkspaceStatus(WorkspaceStatus.LaunchError));
845
+ return;
798
846
  }
799
- if (requestedStatus === RequestedWorkspaceStatus.Terminate) {
847
+ if (workspaceQueryStatus === WorkspaceStatus.NotFound) {
848
+ return; // pod not yet created, keep waiting
849
+ }
850
+ if (workspaceQueryStatus === WorkspaceStatus.Running) {
851
+ // workspace is running — requested status has been met
852
+ dispatch(setJEGRequestedWorkspaceStatus(RequestedWorkspaceStatus.Unset));
853
+ dispatch(setJEGActiveWorkspaceStatus(WorkspaceStatus.Running));
800
854
  return;
801
855
  }
856
+ // still launching — update active status but keep requestedStatus as Launch
802
857
  dispatch(setJEGActiveWorkspaceStatus(workspaceQueryStatus));
803
- setPollingInterval(WorkspacePollingInterval[workspaceQueryStatus]);
804
858
  return;
805
859
  }
806
- if (workspaceStatusData.status === HatcheryServiceState.unknown) {
807
- // NotFound means pod is not running
808
- // either starting up
809
- // or finally terminated.
810
- if (requestedStatus === RequestedWorkspaceStatus.Launch) {
811
- // if the workspace becomes idle too long after a Launch request, switch to
812
- // Unset and NotFound.
813
- console.warn("requested status is Launch, but workspace pod isn't running yet.");
814
- return;
815
- } else {
816
- // both requested status and workspace pod status are the same, so stop all polling
817
- setPollingInterval(WorkspacePollingInterval[WorkspaceStatus.NotFound]);
818
- dispatch(setJEGActiveWorkspaceStatus(WorkspaceStatus.NotFound));
819
- if (requestedStatus === RequestedWorkspaceStatus.Terminate) {
820
- // Cleanup termination after terminated
821
- dispatch(setJEGRequestedWorkspaceStatus(RequestedWorkspaceStatus.Unset));
822
- }
823
- }
860
+ if (requestedStatus === RequestedWorkspaceStatus.Terminate) {
824
861
  return;
825
862
  }
826
- // if here, update active workspace status and polling interval
863
+ // if here, update active workspace status and polling for other states
827
864
  dispatch(setJEGActiveWorkspaceStatus(workspaceQueryStatus));
828
865
  setPollingInterval(WorkspacePollingInterval[workspaceQueryStatus]);
829
866
  }, [
@@ -833,8 +870,9 @@ const workspaceShutdownAlertLimit = 30000; // 5 minutes: 5 * 60 * 1000 TODO Figu
833
870
  activeStatus
834
871
  ]);
835
872
  useEffect(()=>{
873
+ // time out if exceeding maximum start timee
836
874
  if (requestedStatus === RequestedWorkspaceStatus.Launch && isTimeGreaterThan(requestedStatusTimestamp, MAXIMUM_START_TIME_IN_MINUTES)) {
837
- if (workspaceId) terminateWorkspace(workspaceId);
875
+ if (workspaceId) terminateWorkspace(encodeURIComponent(workspaceId));
838
876
  dispatch(setJEGRequestedWorkspaceStatus(RequestedWorkspaceStatus.Terminate));
839
877
  setError('Workspace failed to start. Shutting down');
840
878
  }
@@ -898,21 +936,22 @@ const MicroContainerReduxPanel = ({ compact = false })=>{
898
936
  coreDispatch
899
937
  ]);
900
938
  /* ── Elapsed timer for launching state ── */ const [elapsedSec, setElapsedSec] = useState(0);
939
+ const interval = useInterval(()=>{
940
+ const elapsed = Math.floor((Date.now() - requestedStatusTimestamp) / 1000);
941
+ setElapsedSec(elapsed);
942
+ }, 1000);
901
943
  useEffect(()=>{
902
- if (status !== WorkspaceStatus.Launching) {
944
+ if (status === WorkspaceStatus.Launching) {
945
+ interval.start();
946
+ } else {
903
947
  setElapsedSec(0);
904
- return;
948
+ interval.stop();
905
949
  }
906
- const interval = Math.floor((Date.now() - requestedStatusTimestamp) / 1000);
907
- const t = setInterval(()=>{
908
- setElapsedSec(interval);
909
- }, 1000);
910
- return ()=>clearInterval(t);
950
+ return interval.stop;
911
951
  }, [
912
- requestedStatusTimestamp,
913
- status
952
+ status,
953
+ interval
914
954
  ]);
915
- console.log('MicroContainerReduxPanel: status', status);
916
955
  /* ── Auto-reset after 15 s in launch-error state ── */ useEffect(()=>{
917
956
  if (status !== WorkspaceStatus.LaunchError) return;
918
957
  const t = setTimeout(()=>resetStatus(), 6_000);
@@ -965,9 +1004,6 @@ const MicroContainerReduxPanel = ({ compact = false })=>{
965
1004
  });
966
1005
  }
967
1006
  /* ── launching ── */ if (status === WorkspaceStatus.Launching) {
968
- const mins = Math.floor(elapsedSec / 60);
969
- const secs = elapsedSec % 60;
970
- const elapsed = mins > 0 ? `${mins}m ${secs}s` : `${secs}s`;
971
1007
  return /*#__PURE__*/ jsxs("div", {
972
1008
  role: "status",
973
1009
  className: PanelStyle$2,
@@ -990,7 +1026,9 @@ const MicroContainerReduxPanel = ({ compact = false })=>{
990
1026
  className: "mt-1 text-sm text-base-darker",
991
1027
  children: [
992
1028
  "Elapsed: ",
993
- elapsed
1029
+ elapsedSec,
1030
+ " ",
1031
+ elapsedSec === 1 ? 'second' : 'seconds'
994
1032
  ]
995
1033
  }),
996
1034
  /*#__PURE__*/ jsx("p", {
@@ -1507,6 +1545,8 @@ const jegGatewayApi = GatewayWithTags.injectEndpoints({
1507
1545
  overrideExisting: true
1508
1546
  });
1509
1547
  const { useActiveKernelsQuery, useLaunchKernelMutation, useTerminateKernelMutation, useJegGatewayStatusQuery, useReapKernelsMutation } = jegGatewayApi;
1548
+ // select active kernels
1549
+ jegGatewayApi.endpoints.activeKernels.select();
1510
1550
 
1511
1551
  const ActiveKernelInfoPanel = ({ kernelId, kernelName, executionState, uptimeMinutes, onOpenNotebook, forceTerminate = false, rowSpec, connections = 0 })=>{
1512
1552
  const [terminateKernel, { isLoading: isTerminatingLoading, isError: isTerminatingError, error: terminatingError }] = useTerminateKernelMutation();
@@ -1651,6 +1691,8 @@ const PanelStyle$1 = 'min-w-0 rounded-sm border-2 border-base-lighter bg-base-ma
1651
1691
  const ActiveKernelsPanel = ()=>{
1652
1692
  const { data: kernels, isLoading, isError, error } = useActiveKernelsQuery(undefined, {
1653
1693
  pollingInterval: 10000,
1694
+ refetchOnMountOrArgChange: 1800,
1695
+ refetchOnFocus: true,
1654
1696
  selectFromResult: ({ data, isLoading, isError, error })=>({
1655
1697
  data,
1656
1698
  isLoading,
@@ -1949,7 +1991,11 @@ function useGatewayConnectionStatus() {
1949
1991
  setGatewayMessage(message ?? null);
1950
1992
  }, []);
1951
1993
  // get the status of the gateway
1952
- const { data: gatewayStatusData, isFetching: isGatewayFetching, isError } = useJegGatewayStatusQuery();
1994
+ const { data: gatewayStatusData, isFetching: isGatewayFetching, isError } = useJegGatewayStatusQuery(undefined, {
1995
+ pollingInterval: 10000,
1996
+ refetchOnMountOrArgChange: 1800,
1997
+ refetchOnFocus: true
1998
+ });
1953
1999
  const gatewayServiceStatus = useMemo(()=>{
1954
2000
  if (isGatewayFetching) return 'fetching';
1955
2001
  if (!isError) return 'service_unavailable';
@@ -2194,7 +2240,7 @@ function HorizontalAccordion({ label, expanded, setExpanded, children, expandedW
2194
2240
  });
2195
2241
  const mergedClassNames = mergeDefaultTailwindClassnames(STYLING_DEFAULTS, classNames);
2196
2242
  return /*#__PURE__*/ jsx("div", {
2197
- className: `overflow-hidden shrink-0 ${mergedClassNames.root}`,
2243
+ className: `${mergedClassNames.root}`,
2198
2244
  style: {
2199
2245
  width: expanded ? expandedWidth : collapsedWidth,
2200
2246
  transition: `width ${TRANSITION_MS}ms ease`
@@ -2229,7 +2275,7 @@ function HorizontalAccordion({ label, expanded, setExpanded, children, expandedW
2229
2275
  ]
2230
2276
  }),
2231
2277
  /*#__PURE__*/ jsx("div", {
2232
- className: "overflow-hidden h-full shrink-0 px-2",
2278
+ className: "overflow-hidden px-2",
2233
2279
  style: {
2234
2280
  opacity: expanded ? 1 : 0,
2235
2281
  pointerEvents: expanded ? 'auto' : 'none',
@@ -2257,9 +2303,8 @@ const SettingsPanel = ({ showKernels, expanded, setExpanded, width = 380 })=>{
2257
2303
  setExpanded: setExpanded,
2258
2304
  rightSide: true,
2259
2305
  expandedWidth: width,
2260
- children: /*#__PURE__*/ jsxs(Stack, {
2261
- gap: "sm",
2262
- className: PanelStyle,
2306
+ children: /*#__PURE__*/ jsxs("div", {
2307
+ className: `${PanelStyle} overflow-y-scroll`,
2263
2308
  children: [
2264
2309
  showKernels && /*#__PURE__*/ jsx(KernelLifecyclePanel, {}),
2265
2310
  /*#__PURE__*/ jsx(UpgradeActionsPanel, {