skypilot-nightly 1.0.0.dev20251203__py3-none-any.whl → 1.0.0.dev20260112__py3-none-any.whl

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 (245) hide show
  1. sky/__init__.py +6 -2
  2. sky/adaptors/aws.py +1 -61
  3. sky/adaptors/slurm.py +565 -0
  4. sky/backends/backend_utils.py +95 -12
  5. sky/backends/cloud_vm_ray_backend.py +224 -65
  6. sky/backends/task_codegen.py +380 -4
  7. sky/catalog/__init__.py +0 -3
  8. sky/catalog/data_fetchers/fetch_gcp.py +9 -1
  9. sky/catalog/data_fetchers/fetch_nebius.py +1 -1
  10. sky/catalog/data_fetchers/fetch_vast.py +4 -2
  11. sky/catalog/kubernetes_catalog.py +12 -4
  12. sky/catalog/seeweb_catalog.py +30 -15
  13. sky/catalog/shadeform_catalog.py +5 -2
  14. sky/catalog/slurm_catalog.py +236 -0
  15. sky/catalog/vast_catalog.py +30 -6
  16. sky/check.py +25 -11
  17. sky/client/cli/command.py +391 -32
  18. sky/client/interactive_utils.py +190 -0
  19. sky/client/sdk.py +64 -2
  20. sky/client/sdk_async.py +9 -0
  21. sky/clouds/__init__.py +2 -0
  22. sky/clouds/aws.py +60 -2
  23. sky/clouds/azure.py +2 -0
  24. sky/clouds/cloud.py +7 -0
  25. sky/clouds/kubernetes.py +2 -0
  26. sky/clouds/runpod.py +38 -7
  27. sky/clouds/slurm.py +610 -0
  28. sky/clouds/ssh.py +3 -2
  29. sky/clouds/vast.py +39 -16
  30. sky/core.py +197 -37
  31. sky/dashboard/out/404.html +1 -1
  32. sky/dashboard/out/_next/static/3nu-b8raeKRNABZ2d4GAG/_buildManifest.js +1 -0
  33. sky/dashboard/out/_next/static/chunks/1871-0565f8975a7dcd10.js +6 -0
  34. sky/dashboard/out/_next/static/chunks/2109-55a1546d793574a7.js +11 -0
  35. sky/dashboard/out/_next/static/chunks/2521-099b07cd9e4745bf.js +26 -0
  36. sky/dashboard/out/_next/static/chunks/2755.a636e04a928a700e.js +31 -0
  37. sky/dashboard/out/_next/static/chunks/3495.05eab4862217c1a5.js +6 -0
  38. sky/dashboard/out/_next/static/chunks/3785.cfc5dcc9434fd98c.js +1 -0
  39. sky/dashboard/out/_next/static/chunks/3850-fd5696f3bbbaddae.js +1 -0
  40. sky/dashboard/out/_next/static/chunks/3981.645d01bf9c8cad0c.js +21 -0
  41. sky/dashboard/out/_next/static/chunks/4083-0115d67c1fb57d6c.js +21 -0
  42. sky/dashboard/out/_next/static/chunks/{8640.5b9475a2d18c5416.js → 429.a58e9ba9742309ed.js} +2 -2
  43. sky/dashboard/out/_next/static/chunks/4555.8e221537181b5dc1.js +6 -0
  44. sky/dashboard/out/_next/static/chunks/4725.937865b81fdaaebb.js +6 -0
  45. sky/dashboard/out/_next/static/chunks/6082-edabd8f6092300ce.js +25 -0
  46. sky/dashboard/out/_next/static/chunks/6989-49cb7dca83a7a62d.js +1 -0
  47. sky/dashboard/out/_next/static/chunks/6990-630bd2a2257275f8.js +1 -0
  48. sky/dashboard/out/_next/static/chunks/7248-a99800d4db8edabd.js +1 -0
  49. sky/dashboard/out/_next/static/chunks/754-cfc5d4ad1b843d29.js +18 -0
  50. sky/dashboard/out/_next/static/chunks/8050-dd8aa107b17dce00.js +16 -0
  51. sky/dashboard/out/_next/static/chunks/8056-d4ae1e0cb81e7368.js +1 -0
  52. sky/dashboard/out/_next/static/chunks/8555.011023e296c127b3.js +6 -0
  53. sky/dashboard/out/_next/static/chunks/8821-93c25df904a8362b.js +1 -0
  54. sky/dashboard/out/_next/static/chunks/8969-0662594b69432ade.js +1 -0
  55. sky/dashboard/out/_next/static/chunks/9025.f15c91c97d124a5f.js +6 -0
  56. sky/dashboard/out/_next/static/chunks/9353-7ad6bd01858556f1.js +1 -0
  57. sky/dashboard/out/_next/static/chunks/pages/_app-5a86569acad99764.js +34 -0
  58. sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]/[job]-8297476714acb4ac.js +6 -0
  59. sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]-337c3ba1085f1210.js +1 -0
  60. sky/dashboard/out/_next/static/chunks/pages/{clusters-ee39056f9851a3ff.js → clusters-57632ff3684a8b5c.js} +1 -1
  61. sky/dashboard/out/_next/static/chunks/pages/{config-dfb9bf07b13045f4.js → config-718cdc365de82689.js} +1 -1
  62. sky/dashboard/out/_next/static/chunks/pages/infra/[context]-5fd3a453c079c2ea.js +1 -0
  63. sky/dashboard/out/_next/static/chunks/pages/infra-9f85c02c9c6cae9e.js +1 -0
  64. sky/dashboard/out/_next/static/chunks/pages/jobs/[job]-90f16972cbecf354.js +1 -0
  65. sky/dashboard/out/_next/static/chunks/pages/jobs/pools/[pool]-2dd42fc37aad427a.js +16 -0
  66. sky/dashboard/out/_next/static/chunks/pages/jobs-ed806aeace26b972.js +1 -0
  67. sky/dashboard/out/_next/static/chunks/pages/plugins/[...slug]-449a9f5a3bb20fb3.js +1 -0
  68. sky/dashboard/out/_next/static/chunks/pages/users-bec34706b36f3524.js +1 -0
  69. sky/dashboard/out/_next/static/chunks/pages/{volumes-b84b948ff357c43e.js → volumes-a83ba9b38dff7ea9.js} +1 -1
  70. sky/dashboard/out/_next/static/chunks/pages/workspaces/{[name]-84a40f8c7c627fe4.js → [name]-c781e9c3e52ef9fc.js} +1 -1
  71. sky/dashboard/out/_next/static/chunks/pages/workspaces-91e0942f47310aae.js +1 -0
  72. sky/dashboard/out/_next/static/chunks/webpack-cfe59cf684ee13b9.js +1 -0
  73. sky/dashboard/out/_next/static/css/b0dbca28f027cc19.css +3 -0
  74. sky/dashboard/out/clusters/[cluster]/[job].html +1 -1
  75. sky/dashboard/out/clusters/[cluster].html +1 -1
  76. sky/dashboard/out/clusters.html +1 -1
  77. sky/dashboard/out/config.html +1 -1
  78. sky/dashboard/out/index.html +1 -1
  79. sky/dashboard/out/infra/[context].html +1 -1
  80. sky/dashboard/out/infra.html +1 -1
  81. sky/dashboard/out/jobs/[job].html +1 -1
  82. sky/dashboard/out/jobs/pools/[pool].html +1 -1
  83. sky/dashboard/out/jobs.html +1 -1
  84. sky/dashboard/out/plugins/[...slug].html +1 -0
  85. sky/dashboard/out/users.html +1 -1
  86. sky/dashboard/out/volumes.html +1 -1
  87. sky/dashboard/out/workspace/new.html +1 -1
  88. sky/dashboard/out/workspaces/[name].html +1 -1
  89. sky/dashboard/out/workspaces.html +1 -1
  90. sky/data/data_utils.py +26 -12
  91. sky/data/mounting_utils.py +44 -5
  92. sky/global_user_state.py +111 -19
  93. sky/jobs/client/sdk.py +8 -3
  94. sky/jobs/controller.py +191 -31
  95. sky/jobs/recovery_strategy.py +109 -11
  96. sky/jobs/server/core.py +81 -4
  97. sky/jobs/server/server.py +14 -0
  98. sky/jobs/state.py +417 -19
  99. sky/jobs/utils.py +73 -80
  100. sky/models.py +11 -0
  101. sky/optimizer.py +8 -6
  102. sky/provision/__init__.py +12 -9
  103. sky/provision/common.py +20 -0
  104. sky/provision/docker_utils.py +15 -2
  105. sky/provision/kubernetes/utils.py +163 -20
  106. sky/provision/kubernetes/volume.py +52 -17
  107. sky/provision/provisioner.py +17 -7
  108. sky/provision/runpod/instance.py +3 -1
  109. sky/provision/runpod/utils.py +13 -1
  110. sky/provision/runpod/volume.py +25 -9
  111. sky/provision/slurm/__init__.py +12 -0
  112. sky/provision/slurm/config.py +13 -0
  113. sky/provision/slurm/instance.py +618 -0
  114. sky/provision/slurm/utils.py +689 -0
  115. sky/provision/vast/instance.py +4 -1
  116. sky/provision/vast/utils.py +11 -6
  117. sky/resources.py +135 -13
  118. sky/schemas/api/responses.py +4 -0
  119. sky/schemas/db/global_user_state/010_save_ssh_key.py +1 -1
  120. sky/schemas/db/spot_jobs/008_add_full_resources.py +34 -0
  121. sky/schemas/db/spot_jobs/009_job_events.py +32 -0
  122. sky/schemas/db/spot_jobs/010_job_events_timestamp_with_timezone.py +43 -0
  123. sky/schemas/db/spot_jobs/011_add_links.py +34 -0
  124. sky/schemas/generated/jobsv1_pb2.py +9 -5
  125. sky/schemas/generated/jobsv1_pb2.pyi +12 -0
  126. sky/schemas/generated/jobsv1_pb2_grpc.py +44 -0
  127. sky/schemas/generated/managed_jobsv1_pb2.py +32 -28
  128. sky/schemas/generated/managed_jobsv1_pb2.pyi +11 -2
  129. sky/serve/serve_utils.py +232 -40
  130. sky/serve/server/impl.py +1 -1
  131. sky/server/common.py +17 -0
  132. sky/server/constants.py +1 -1
  133. sky/server/metrics.py +6 -3
  134. sky/server/plugins.py +238 -0
  135. sky/server/requests/executor.py +5 -2
  136. sky/server/requests/payloads.py +30 -1
  137. sky/server/requests/request_names.py +4 -0
  138. sky/server/requests/requests.py +33 -11
  139. sky/server/requests/serializers/encoders.py +22 -0
  140. sky/server/requests/serializers/return_value_serializers.py +70 -0
  141. sky/server/server.py +506 -109
  142. sky/server/server_utils.py +30 -0
  143. sky/server/uvicorn.py +5 -0
  144. sky/setup_files/MANIFEST.in +1 -0
  145. sky/setup_files/dependencies.py +22 -9
  146. sky/sky_logging.py +2 -1
  147. sky/skylet/attempt_skylet.py +13 -3
  148. sky/skylet/constants.py +55 -13
  149. sky/skylet/events.py +10 -4
  150. sky/skylet/executor/__init__.py +1 -0
  151. sky/skylet/executor/slurm.py +187 -0
  152. sky/skylet/job_lib.py +91 -5
  153. sky/skylet/log_lib.py +22 -6
  154. sky/skylet/log_lib.pyi +8 -6
  155. sky/skylet/services.py +18 -3
  156. sky/skylet/skylet.py +5 -1
  157. sky/skylet/subprocess_daemon.py +2 -1
  158. sky/ssh_node_pools/constants.py +12 -0
  159. sky/ssh_node_pools/core.py +40 -3
  160. sky/ssh_node_pools/deploy/__init__.py +4 -0
  161. sky/{utils/kubernetes/deploy_ssh_node_pools.py → ssh_node_pools/deploy/deploy.py} +279 -504
  162. sky/ssh_node_pools/deploy/tunnel/ssh-tunnel.sh +379 -0
  163. sky/ssh_node_pools/deploy/tunnel_utils.py +199 -0
  164. sky/ssh_node_pools/deploy/utils.py +173 -0
  165. sky/ssh_node_pools/server.py +11 -13
  166. sky/{utils/kubernetes/ssh_utils.py → ssh_node_pools/utils.py} +9 -6
  167. sky/templates/kubernetes-ray.yml.j2 +12 -6
  168. sky/templates/slurm-ray.yml.j2 +115 -0
  169. sky/templates/vast-ray.yml.j2 +1 -0
  170. sky/templates/websocket_proxy.py +18 -41
  171. sky/users/model.conf +1 -1
  172. sky/users/permission.py +85 -52
  173. sky/users/rbac.py +31 -3
  174. sky/utils/annotations.py +108 -8
  175. sky/utils/auth_utils.py +42 -0
  176. sky/utils/cli_utils/status_utils.py +19 -5
  177. sky/utils/cluster_utils.py +10 -3
  178. sky/utils/command_runner.py +389 -35
  179. sky/utils/command_runner.pyi +43 -4
  180. sky/utils/common_utils.py +47 -31
  181. sky/utils/context.py +32 -0
  182. sky/utils/db/db_utils.py +36 -6
  183. sky/utils/db/migration_utils.py +41 -21
  184. sky/utils/infra_utils.py +5 -1
  185. sky/utils/instance_links.py +139 -0
  186. sky/utils/interactive_utils.py +49 -0
  187. sky/utils/kubernetes/generate_kubeconfig.sh +42 -33
  188. sky/utils/kubernetes/kubernetes_deploy_utils.py +2 -94
  189. sky/utils/kubernetes/rsync_helper.sh +5 -1
  190. sky/utils/kubernetes/ssh-tunnel.sh +7 -376
  191. sky/utils/plugin_extensions/__init__.py +14 -0
  192. sky/utils/plugin_extensions/external_failure_source.py +176 -0
  193. sky/utils/resources_utils.py +10 -8
  194. sky/utils/rich_utils.py +9 -11
  195. sky/utils/schemas.py +93 -19
  196. sky/utils/status_lib.py +7 -0
  197. sky/utils/subprocess_utils.py +17 -0
  198. sky/volumes/client/sdk.py +6 -3
  199. sky/volumes/server/core.py +65 -27
  200. sky_templates/ray/start_cluster +8 -4
  201. {skypilot_nightly-1.0.0.dev20251203.dist-info → skypilot_nightly-1.0.0.dev20260112.dist-info}/METADATA +67 -59
  202. {skypilot_nightly-1.0.0.dev20251203.dist-info → skypilot_nightly-1.0.0.dev20260112.dist-info}/RECORD +208 -180
  203. sky/dashboard/out/_next/static/96_E2yl3QAiIJGOYCkSpB/_buildManifest.js +0 -1
  204. sky/dashboard/out/_next/static/chunks/1141-e6aa9ab418717c59.js +0 -11
  205. sky/dashboard/out/_next/static/chunks/1871-7e202677c42f43fe.js +0 -6
  206. sky/dashboard/out/_next/static/chunks/2260-7703229c33c5ebd5.js +0 -1
  207. sky/dashboard/out/_next/static/chunks/2350.fab69e61bac57b23.js +0 -1
  208. sky/dashboard/out/_next/static/chunks/2369.fc20f0c2c8ed9fe7.js +0 -15
  209. sky/dashboard/out/_next/static/chunks/2755.edd818326d489a1d.js +0 -26
  210. sky/dashboard/out/_next/static/chunks/3294.20a8540fe697d5ee.js +0 -1
  211. sky/dashboard/out/_next/static/chunks/3785.7e245f318f9d1121.js +0 -1
  212. sky/dashboard/out/_next/static/chunks/3800-7b45f9fbb6308557.js +0 -1
  213. sky/dashboard/out/_next/static/chunks/3850-ff4a9a69d978632b.js +0 -1
  214. sky/dashboard/out/_next/static/chunks/4725.172ede95d1b21022.js +0 -1
  215. sky/dashboard/out/_next/static/chunks/4937.a2baa2df5572a276.js +0 -15
  216. sky/dashboard/out/_next/static/chunks/6212-7bd06f60ba693125.js +0 -13
  217. sky/dashboard/out/_next/static/chunks/6856-8f27d1c10c98def8.js +0 -1
  218. sky/dashboard/out/_next/static/chunks/6989-01359c57e018caa4.js +0 -1
  219. sky/dashboard/out/_next/static/chunks/6990-9146207c4567fdfd.js +0 -1
  220. sky/dashboard/out/_next/static/chunks/7359-c8d04e06886000b3.js +0 -30
  221. sky/dashboard/out/_next/static/chunks/7411-b15471acd2cba716.js +0 -41
  222. sky/dashboard/out/_next/static/chunks/7615-019513abc55b3b47.js +0 -1
  223. sky/dashboard/out/_next/static/chunks/8969-452f9d5cbdd2dc73.js +0 -1
  224. sky/dashboard/out/_next/static/chunks/9025.fa408f3242e9028d.js +0 -6
  225. sky/dashboard/out/_next/static/chunks/9353-cff34f7e773b2e2b.js +0 -1
  226. sky/dashboard/out/_next/static/chunks/9360.a536cf6b1fa42355.js +0 -31
  227. sky/dashboard/out/_next/static/chunks/9847.3aaca6bb33455140.js +0 -30
  228. sky/dashboard/out/_next/static/chunks/pages/_app-bde01e4a2beec258.js +0 -34
  229. sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]/[job]-792db96d918c98c9.js +0 -16
  230. sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]-abfcac9c137aa543.js +0 -1
  231. sky/dashboard/out/_next/static/chunks/pages/infra/[context]-c0b5935149902e6f.js +0 -1
  232. sky/dashboard/out/_next/static/chunks/pages/infra-aed0ea19df7cf961.js +0 -1
  233. sky/dashboard/out/_next/static/chunks/pages/jobs/[job]-d66997e2bfc837cf.js +0 -16
  234. sky/dashboard/out/_next/static/chunks/pages/jobs/pools/[pool]-9faf940b253e3e06.js +0 -21
  235. sky/dashboard/out/_next/static/chunks/pages/jobs-2072b48b617989c9.js +0 -1
  236. sky/dashboard/out/_next/static/chunks/pages/users-f42674164aa73423.js +0 -1
  237. sky/dashboard/out/_next/static/chunks/pages/workspaces-531b2f8c4bf89f82.js +0 -1
  238. sky/dashboard/out/_next/static/chunks/webpack-64e05f17bf2cf8ce.js +0 -1
  239. sky/dashboard/out/_next/static/css/0748ce22df867032.css +0 -3
  240. /sky/dashboard/out/_next/static/{96_E2yl3QAiIJGOYCkSpB → 3nu-b8raeKRNABZ2d4GAG}/_ssgManifest.js +0 -0
  241. /sky/{utils/kubernetes → ssh_node_pools/deploy/tunnel}/cleanup-tunnel.sh +0 -0
  242. {skypilot_nightly-1.0.0.dev20251203.dist-info → skypilot_nightly-1.0.0.dev20260112.dist-info}/WHEEL +0 -0
  243. {skypilot_nightly-1.0.0.dev20251203.dist-info → skypilot_nightly-1.0.0.dev20260112.dist-info}/entry_points.txt +0 -0
  244. {skypilot_nightly-1.0.0.dev20251203.dist-info → skypilot_nightly-1.0.0.dev20260112.dist-info}/licenses/LICENSE +0 -0
  245. {skypilot_nightly-1.0.0.dev20251203.dist-info → skypilot_nightly-1.0.0.dev20260112.dist-info}/top_level.txt +0 -0
sky/clouds/vast.py CHANGED
@@ -6,6 +6,7 @@ from typing import Dict, Iterator, List, Optional, Tuple, Union
6
6
 
7
7
  from sky import catalog
8
8
  from sky import clouds
9
+ from sky import skypilot_config
9
10
  from sky.adaptors import common
10
11
  from sky.utils import registry
11
12
  from sky.utils import resources_utils
@@ -146,20 +147,24 @@ class Vast(clouds.Cloud):
146
147
  return 0.0
147
148
 
148
149
  @classmethod
149
- def get_default_instance_type(cls,
150
- cpus: Optional[str] = None,
151
- memory: Optional[str] = None,
152
- disk_tier: Optional[
153
- resources_utils.DiskTier] = None,
154
- region: Optional[str] = None,
155
- zone: Optional[str] = None) -> Optional[str]:
150
+ def get_default_instance_type(
151
+ cls,
152
+ cpus: Optional[str] = None,
153
+ memory: Optional[str] = None,
154
+ disk_tier: Optional[resources_utils.DiskTier] = None,
155
+ region: Optional[str] = None,
156
+ zone: Optional[str] = None,
157
+ datacenter_only: bool = False) -> Optional[str]:
156
158
  """Returns the default instance type for Vast."""
157
- return catalog.get_default_instance_type(cpus=cpus,
158
- memory=memory,
159
- disk_tier=disk_tier,
160
- region=region,
161
- zone=zone,
162
- clouds='vast')
159
+ # pylint: disable=import-outside-toplevel
160
+ from sky.catalog import vast_catalog
161
+ return vast_catalog.get_default_instance_type(
162
+ cpus=cpus,
163
+ memory=memory,
164
+ disk_tier=disk_tier,
165
+ region=region,
166
+ zone=zone,
167
+ datacenter_only=datacenter_only)
163
168
 
164
169
  @classmethod
165
170
  def get_accelerators_from_instance_type(
@@ -196,17 +201,28 @@ class Vast(clouds.Cloud):
196
201
  else:
197
202
  image_id = resources.image_id[resources.region]
198
203
 
204
+ secure_only = skypilot_config.get_effective_region_config(
205
+ cloud='vast',
206
+ region=region.name,
207
+ keys=('datacenter_only',),
208
+ default_value=False,
209
+ override_configs=resources.cluster_config_overrides,
210
+ )
211
+
199
212
  return {
200
213
  'instance_type': resources.instance_type,
201
214
  'custom_resources': custom_resources,
202
215
  'region': region.name,
203
216
  'image_id': image_id,
217
+ 'secure_only': secure_only,
204
218
  }
205
219
 
206
220
  def _get_feasible_launchable_resources(
207
221
  self, resources: 'resources_lib.Resources'
208
222
  ) -> 'resources_utils.FeasibleResources':
209
223
  """Returns a list of feasible resources for the given resources."""
224
+ # pylint: disable=import-outside-toplevel
225
+ from sky.catalog import vast_catalog
210
226
  if resources.instance_type is not None:
211
227
  assert resources.is_launchable(), resources
212
228
  resources = resources.copy(accelerators=None)
@@ -224,6 +240,12 @@ class Vast(clouds.Cloud):
224
240
  resource_list.append(r)
225
241
  return resource_list
226
242
 
243
+ # Resolve datacenter_only config first (used for all instance filtering)
244
+ datacenter_only = skypilot_config.get_nested(
245
+ ('vast', 'datacenter_only'),
246
+ False,
247
+ override_configs=resources.cluster_config_overrides)
248
+
227
249
  # Currently, handle a filter on accelerators only.
228
250
  accelerators = resources.accelerators
229
251
  if accelerators is None:
@@ -233,7 +255,8 @@ class Vast(clouds.Cloud):
233
255
  memory=resources.memory,
234
256
  disk_tier=resources.disk_tier,
235
257
  region=resources.region,
236
- zone=resources.zone)
258
+ zone=resources.zone,
259
+ datacenter_only=datacenter_only)
237
260
  if default_instance_type is None:
238
261
  # TODO: Add hints to all return values in this method to help
239
262
  # users understand why the resources are not launchable.
@@ -245,7 +268,7 @@ class Vast(clouds.Cloud):
245
268
  assert len(accelerators) == 1, resources
246
269
  acc, acc_count = list(accelerators.items())[0]
247
270
  (instance_list,
248
- fuzzy_candidate_list) = catalog.get_instance_type_for_accelerator(
271
+ fuzzy_candidate_list) = vast_catalog.get_instance_type_for_accelerator(
249
272
  acc,
250
273
  acc_count,
251
274
  use_spot=resources.use_spot,
@@ -253,7 +276,7 @@ class Vast(clouds.Cloud):
253
276
  region=resources.region,
254
277
  zone=resources.zone,
255
278
  memory=resources.memory,
256
- clouds='vast')
279
+ datacenter_only=datacenter_only)
257
280
  if instance_list is None:
258
281
  return resources_utils.FeasibleResources([], fuzzy_candidate_list,
259
282
  None)
sky/core.py CHANGED
@@ -1,6 +1,6 @@
1
1
  """SDK functions for cluster/job management."""
2
2
  import typing
3
- from typing import Any, Dict, List, Optional, Tuple, Union
3
+ from typing import Any, Dict, List, Literal, Optional, Tuple, Union
4
4
 
5
5
  import colorama
6
6
 
@@ -279,6 +279,74 @@ all_clusters, unmanaged_clusters, all_jobs, context
279
279
  return all_clusters, unmanaged_clusters, all_jobs, context
280
280
 
281
281
 
282
+ @typing.overload
283
+ def get_cluster_events(
284
+ cluster_name: Optional[str] = ...,
285
+ cluster_hash: Optional[str] = ...,
286
+ event_type: str = ...,
287
+ include_timestamps: Literal[False] = ...,
288
+ limit: Optional[int] = ...,
289
+ ) -> List[str]:
290
+ ...
291
+
292
+
293
+ @typing.overload
294
+ def get_cluster_events(
295
+ cluster_name: Optional[str] = ...,
296
+ cluster_hash: Optional[str] = ...,
297
+ event_type: str = ...,
298
+ include_timestamps: Literal[True] = ...,
299
+ limit: Optional[int] = ...,
300
+ ) -> List[Dict[str, Union[str, int]]]:
301
+ ...
302
+
303
+
304
+ @typing.overload
305
+ def get_cluster_events(
306
+ cluster_name: Optional[str] = ...,
307
+ cluster_hash: Optional[str] = ...,
308
+ event_type: str = ...,
309
+ include_timestamps: bool = ...,
310
+ limit: Optional[int] = ...,
311
+ ) -> Union[List[str], List[Dict[str, Union[str, int]]]]:
312
+ ...
313
+
314
+
315
+ def get_cluster_events(
316
+ cluster_name: Optional[str] = None,
317
+ cluster_hash: Optional[str] = None,
318
+ event_type: str = 'STATUS_CHANGE',
319
+ include_timestamps: bool = False,
320
+ limit: Optional[int] = None
321
+ ) -> Union[List[str], List[Dict[str, Union[str, int]]]]:
322
+ """Get events for a cluster.
323
+
324
+ Args:
325
+ cluster_name: Name of the cluster. Cannot be specified if cluster_hash
326
+ is specified.
327
+ cluster_hash: Hash of the cluster. Cannot be specified if cluster_name
328
+ is specified.
329
+ event_type: Type of events to retrieve ('STATUS_CHANGE' or 'DEBUG').
330
+ include_timestamps: If True, returns list of dicts with 'reason' and
331
+ 'transitioned_at' fields. If False, returns list of reason strings.
332
+ limit: If specified, returns at most this many events (most recent).
333
+ If None, returns all events.
334
+
335
+ Returns:
336
+ If include_timestamps is False: List of event reason strings.
337
+ If include_timestamps is True: List of dicts with 'reason' and
338
+ 'transitioned_at' (unix timestamp) fields.
339
+ Events are ordered from oldest to newest.
340
+ """
341
+ event_type_enum = global_user_state.ClusterEventType(event_type)
342
+ return global_user_state.get_cluster_events(
343
+ cluster_name=cluster_name,
344
+ cluster_hash=cluster_hash,
345
+ event_type=event_type_enum,
346
+ include_timestamps=include_timestamps,
347
+ limit=limit)
348
+
349
+
282
350
  def endpoints(cluster: str,
283
351
  port: Optional[Union[int, str]] = None) -> Dict[int, str]:
284
352
  """Gets the endpoint for a given cluster and port number (endpoint).
@@ -1211,6 +1279,7 @@ def enabled_clouds(workspace: Optional[str] = None,
1211
1279
  return [cloud.canonical_name() for cloud in cached_clouds]
1212
1280
  enabled_ssh_infras = []
1213
1281
  enabled_k8s_infras = []
1282
+ enabled_slurm_infras = []
1214
1283
  enabled_cloud_infras = []
1215
1284
  for cloud in cached_clouds:
1216
1285
  cloud_infra = cloud.expand_infras()
@@ -1218,10 +1287,16 @@ def enabled_clouds(workspace: Optional[str] = None,
1218
1287
  enabled_ssh_infras.extend(cloud_infra)
1219
1288
  elif isinstance(cloud, clouds.Kubernetes):
1220
1289
  enabled_k8s_infras.extend(cloud_infra)
1290
+ elif isinstance(cloud, clouds.Slurm):
1291
+ enabled_slurm_infras.extend(cloud_infra)
1221
1292
  else:
1222
1293
  enabled_cloud_infras.extend(cloud_infra)
1294
+ # We do not sort slurm infras alphabetically because the
1295
+ # default partition should appear first.
1296
+ # Ordering of slurm infras is enforced in Slurm implementation.
1223
1297
  all_infras = sorted(enabled_ssh_infras) + sorted(
1224
- enabled_k8s_infras) + sorted(enabled_cloud_infras)
1298
+ enabled_k8s_infras) + enabled_slurm_infras + sorted(
1299
+ enabled_cloud_infras)
1225
1300
  return all_infras
1226
1301
 
1227
1302
 
@@ -1232,7 +1307,14 @@ def realtime_kubernetes_gpu_availability(
1232
1307
  quantity_filter: Optional[int] = None,
1233
1308
  is_ssh: Optional[bool] = None
1234
1309
  ) -> List[Tuple[str, List[models.RealtimeGpuAvailability]]]:
1310
+ """Gets the real-time Kubernetes GPU availability.
1235
1311
 
1312
+ Returns:
1313
+ A list of tuples, where each tuple contains:
1314
+ - context (str): The Kubernetes context.
1315
+ - availability_list (List[models.RealtimeGpuAvailability]): A list
1316
+ of RealtimeGpuAvailability objects for that context.
1317
+ """
1236
1318
  if context is None:
1237
1319
  # Include contexts from both Kubernetes and SSH clouds
1238
1320
  kubernetes_contexts = clouds.Kubernetes.existing_allowed_contexts()
@@ -1314,6 +1396,119 @@ def realtime_kubernetes_gpu_availability(
1314
1396
  return availability_lists
1315
1397
 
1316
1398
 
1399
+ def realtime_slurm_gpu_availability(
1400
+ slurm_cluster_name: Optional[str] = None,
1401
+ name_filter: Optional[str] = None,
1402
+ quantity_filter: Optional[int] = None,
1403
+ env_vars: Optional[Dict[str, str]] = None,
1404
+ **kwargs) -> List[Tuple[str, List[models.RealtimeGpuAvailability]]]:
1405
+ """Gets Slurm real-time GPU availability grouped by partition.
1406
+
1407
+ This function calls the Slurm backend to fetch GPU info.
1408
+
1409
+ Args:
1410
+ name_filter: Optional name filter for GPUs.
1411
+ quantity_filter: Optional quantity filter for GPUs.
1412
+ env_vars: Environment variables (may be needed for backend).
1413
+ kwargs: Additional keyword arguments.
1414
+
1415
+ Returns:
1416
+ A list of tuples, where each tuple contains:
1417
+ - partition_name (str): The name of the Slurm partition.
1418
+ - availability_list (List[models.RealtimeGpuAvailability]): A list
1419
+ of RealtimeGpuAvailability objects for that partition.
1420
+ Example structure:
1421
+ [
1422
+ ('gpu_partition_1', [
1423
+ RealtimeGpuAvailability(gpu='V100', counts=[4, 8],
1424
+ capacity=16, available=10),
1425
+ RealtimeGpuAvailability(gpu='A100', counts=[8],
1426
+ capacity=8, available=0),
1427
+ ]),
1428
+ ('gpu_partition_2', [
1429
+ RealtimeGpuAvailability(gpu='V100', counts=[4],
1430
+ capacity=4, available=4),
1431
+ ])
1432
+ ]
1433
+
1434
+ Raises:
1435
+ ValueError: If Slurm is not configured or no matching GPUs are found.
1436
+ exceptions.NotSupportedError: If Slurm is not enabled or configured.
1437
+ """
1438
+ del env_vars, kwargs # Currently unused
1439
+
1440
+ if slurm_cluster_name is None:
1441
+ # Include contexts from both Kubernetes and SSH clouds
1442
+ slurm_cluster_names = clouds.Slurm.existing_allowed_clusters()
1443
+ else:
1444
+ slurm_cluster_names = [slurm_cluster_name]
1445
+
1446
+ # Optional: Check if Slurm is enabled first
1447
+ # enabled = global_user_state.get_enabled_clouds(
1448
+ # capability=sky_cloud.CloudCapability.COMPUTE)
1449
+ # if not clouds.Slurm() in enabled:
1450
+ # raise exceptions.NotSupportedError(
1451
+ # "Slurm is not enabled. Run 'sky check' to enable it.")
1452
+
1453
+ def realtime_slurm_gpu_availability_single(
1454
+ slurm_cluster_name: str) -> List[models.RealtimeGpuAvailability]:
1455
+ try:
1456
+ # This function now returns aggregated data per GPU type:
1457
+ # Tuple[Dict[str, List[InstanceTypeInfo]], Dict[str, int],
1458
+ # Dict[str, int]]
1459
+ # (qtys_map, total_capacity, total_available)
1460
+ accelerator_counts, total_capacity, total_available = (
1461
+ catalog.list_accelerator_realtime(
1462
+ gpus_only=True, # Ensure we only query for GPUs
1463
+ name_filter=name_filter,
1464
+ # Pass None for region_filter here; filtering happens
1465
+ # inside if needed, but we want all partitions returned
1466
+ # for grouping.
1467
+ region_filter=slurm_cluster_name,
1468
+ quantity_filter=quantity_filter,
1469
+ clouds='slurm',
1470
+ case_sensitive=False,
1471
+ ))
1472
+ except exceptions.NotSupportedError as e:
1473
+ logger.error(f'Failed to query Slurm GPU availability: {e}')
1474
+ raise
1475
+ except ValueError as e:
1476
+ # Re-raise ValueError if no GPUs are found matching the filters
1477
+ logger.error(f'Error querying Slurm GPU availability: {e}')
1478
+ raise
1479
+ except Exception as e:
1480
+ logger.error(
1481
+ 'Error querying Slurm GPU availability: '
1482
+ f'{common_utils.format_exception(e, use_bracket=True)}')
1483
+ raise ValueError(
1484
+ f'Error querying Slurm GPU availability: {e}') from e
1485
+
1486
+ # --- Format the output ---
1487
+ realtime_gpu_availability_list: List[
1488
+ models.RealtimeGpuAvailability] = []
1489
+ for gpu_type, _ in sorted(accelerator_counts.items()):
1490
+ realtime_gpu_availability_list.append(
1491
+ models.RealtimeGpuAvailability(
1492
+ gpu_type,
1493
+ accelerator_counts.pop(gpu_type),
1494
+ total_capacity[gpu_type],
1495
+ total_available[gpu_type],
1496
+ ))
1497
+ return realtime_gpu_availability_list
1498
+
1499
+ parallel_queried = subprocess_utils.run_in_parallel(
1500
+ realtime_slurm_gpu_availability_single, slurm_cluster_names)
1501
+ availability_lists: List[Tuple[str,
1502
+ List[models.RealtimeGpuAvailability]]] = []
1503
+ for slurm_cluster_name, queried in zip(slurm_cluster_names,
1504
+ parallel_queried):
1505
+ if len(queried) == 0:
1506
+ logger.debug(f'No gpus found in Slurm cluster {slurm_cluster_name}')
1507
+ continue
1508
+ availability_lists.append((slurm_cluster_name, queried))
1509
+ return availability_lists
1510
+
1511
+
1317
1512
  # =================
1318
1513
  # = Local Cluster =
1319
1514
  # =================
@@ -1330,41 +1525,6 @@ def local_down(name: Optional[str] = None) -> None:
1330
1525
  kubernetes_deploy_utils.teardown_local_cluster(name)
1331
1526
 
1332
1527
 
1333
- @usage_lib.entrypoint
1334
- def ssh_up(infra: Optional[str] = None, cleanup: bool = False) -> None:
1335
- """Deploys or tears down a Kubernetes cluster on SSH targets.
1336
-
1337
- Args:
1338
- infra: Name of the cluster configuration in ssh_node_pools.yaml.
1339
- If None, the first cluster in the file is used.
1340
- cleanup: If True, clean up the cluster instead of deploying.
1341
- """
1342
- kubernetes_deploy_utils.deploy_ssh_cluster(
1343
- cleanup=cleanup,
1344
- infra=infra,
1345
- )
1346
-
1347
-
1348
- @usage_lib.entrypoint
1349
- def ssh_status(context_name: str) -> Tuple[bool, str]:
1350
- """Check the status of an SSH Node Pool context.
1351
-
1352
- Args:
1353
- context_name: The SSH context name (e.g., 'ssh-my-cluster')
1354
-
1355
- Returns:
1356
- Tuple[bool, str]: (is_ready, reason)
1357
- - is_ready: True if the SSH Node Pool is ready, False otherwise
1358
- - reason: Explanation of the status
1359
- """
1360
- try:
1361
- is_ready, reason = clouds.SSH.check_single_context(context_name)
1362
- return is_ready, reason
1363
- except Exception as e: # pylint: disable=broad-except
1364
- return False, ('Failed to check SSH context: '
1365
- f'{common_utils.format_exception(e)}')
1366
-
1367
-
1368
1528
  def get_all_contexts() -> List[str]:
1369
1529
  """Get all available contexts from Kubernetes and SSH clouds.
1370
1530
 
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/0748ce22df867032.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/0748ce22df867032.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-64e05f17bf2cf8ce.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-bde01e4a2beec258.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_error-c66a4e8afc46f17b.js" defer=""></script><script src="/dashboard/_next/static/96_E2yl3QAiIJGOYCkSpB/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/96_E2yl3QAiIJGOYCkSpB/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"statusCode":404}},"page":"/_error","query":{},"buildId":"96_E2yl3QAiIJGOYCkSpB","assetPrefix":"/dashboard","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
1
+ <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/b0dbca28f027cc19.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/b0dbca28f027cc19.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-cfe59cf684ee13b9.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-5a86569acad99764.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_error-c66a4e8afc46f17b.js" defer=""></script><script src="/dashboard/_next/static/3nu-b8raeKRNABZ2d4GAG/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/3nu-b8raeKRNABZ2d4GAG/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"statusCode":404}},"page":"/_error","query":{},"buildId":"3nu-b8raeKRNABZ2d4GAG","assetPrefix":"/dashboard","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
@@ -0,0 +1 @@
1
+ self.__BUILD_MANIFEST=function(s,c,a,e,t,u,n,f,i,b,j,o,r,k,d,l){return{__rewrites:{afterFiles:[],beforeFiles:[],fallback:[]},"/":["static/chunks/pages/index-444f1804401f04ea.js"],"/_error":["static/chunks/pages/_error-c66a4e8afc46f17b.js"],"/clusters":["static/chunks/pages/clusters-57632ff3684a8b5c.js"],"/clusters/[cluster]":[c,s,a,b,u,j,f,e,t,n,o,r,i,k,d,"static/chunks/1871-0565f8975a7dcd10.js","static/chunks/pages/clusters/[cluster]-337c3ba1085f1210.js"],"/clusters/[cluster]/[job]":[c,s,a,e,t,l,"static/chunks/pages/clusters/[cluster]/[job]-8297476714acb4ac.js"],"/config":["static/chunks/pages/config-718cdc365de82689.js"],"/infra":["static/chunks/pages/infra-9f85c02c9c6cae9e.js"],"/infra/[context]":["static/chunks/pages/infra/[context]-5fd3a453c079c2ea.js"],"/jobs":["static/chunks/pages/jobs-ed806aeace26b972.js"],"/jobs/pools/[pool]":[c,s,a,u,f,"static/chunks/8821-93c25df904a8362b.js",e,t,n,i,"static/chunks/pages/jobs/pools/[pool]-2dd42fc37aad427a.js"],"/jobs/[job]":[c,s,a,u,f,e,t,n,l,"static/chunks/pages/jobs/[job]-90f16972cbecf354.js"],"/plugins/[...slug]":[s,"static/chunks/pages/plugins/[...slug]-449a9f5a3bb20fb3.js"],"/users":["static/chunks/pages/users-bec34706b36f3524.js"],"/volumes":["static/chunks/pages/volumes-a83ba9b38dff7ea9.js"],"/workspace/new":["static/chunks/pages/workspace/new-3f88a1c7e86a3f86.js"],"/workspaces":["static/chunks/pages/workspaces-91e0942f47310aae.js"],"/workspaces/[name]":[c,s,a,b,u,j,e,t,n,o,r,i,k,d,"static/chunks/8050-dd8aa107b17dce00.js","static/chunks/pages/workspaces/[name]-c781e9c3e52ef9fc.js"],sortedPages:["/","/_app","/_error","/clusters","/clusters/[cluster]","/clusters/[cluster]/[job]","/config","/infra","/infra/[context]","/jobs","/jobs/pools/[pool]","/jobs/[job]","/plugins/[...slug]","/users","/volumes","/workspace/new","/workspaces","/workspaces/[name]"]}}("static/chunks/5739-d67458fcb1386c92.js","static/chunks/616-3d59f75e2ccf9321.js","static/chunks/6130-2be46d70a38f1e82.js","static/chunks/6989-49cb7dca83a7a62d.js","static/chunks/3850-fd5696f3bbbaddae.js","static/chunks/1272-1ef0bf0237faccdb.js","static/chunks/8969-0662594b69432ade.js","static/chunks/754-cfc5d4ad1b843d29.js","static/chunks/7248-a99800d4db8edabd.js","static/chunks/6082-edabd8f6092300ce.js","static/chunks/2521-099b07cd9e4745bf.js","static/chunks/6990-630bd2a2257275f8.js","static/chunks/8056-d4ae1e0cb81e7368.js","static/chunks/9353-7ad6bd01858556f1.js","static/chunks/2109-55a1546d793574a7.js","static/chunks/4083-0115d67c1fb57d6c.js"),self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();
@@ -0,0 +1,6 @@
1
+ "use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[1871],{39037:function(e,s,t){t.r(s),t.d(s,{ClusterTable:function(){return P},Clusters:function(){return O},Status2Actions:function(){return F},enabledActions:function(){return H},handleVSCodeConnection:function(){return Z}});var r=t(85893),l=t(67294),a=t(11163),n=t(55739),i=t(36989),c=t(41664),o=t.n(c),u=t(30803),d=t(37673),h=t(68764),x=t(23266),p=t(17324),m=t(94545),f=t(13626),j=t(60998);/**
2
+ * @license lucide-react v0.407.0 - ISC
3
+ *
4
+ * This source code is licensed under the ISC license.
5
+ * See the LICENSE file in the root directory of this source tree.
6
+ */let v=(0,j.Z)("Terminal",[["polyline",{points:"4 17 10 11 4 5",key:"akl6gq"}],["line",{x1:"12",x2:"20",y1:"19",y2:"19",key:"q2wloq"}]]),g=(0,j.Z)("SquareCode",[["path",{d:"M10 9.5 8 12l2 2.5",key:"3mjy60"}],["path",{d:"m14 9.5 2 2.5-2 2.5",key:"1bir2l"}],["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}]]);t(9353);var y=t(92128),b=t(99307),w=t(23001),k=t(55988),N=t(88950),C=t(6378),S=t(36856);t(1272);var L=t(20546),M=t(10546);let E=[{label:"Status",value:"status"},{label:"Cluster",value:"cluster"},{label:"User",value:"user"},{label:"Workspace",value:"workspace"},{label:"Infra",value:"infra"},{label:"Labels",value:"labels"}],R=(e,s)=>{let t="",r="";return e>=0&&(t=e+"m",r=" "),s&&(t+="".concat(r,"(down)")),""===t&&(t="-"),t},I=(e,s)=>{if(e&&e.includes("@")){let t=e.split("@")[0];return s&&s!==t?"".concat(t," (").concat(s,")"):t}let t=e||s||"N/A";return s&&s!==t?"".concat(t," (").concat(s,")"):t},_=e=>{if(!e||0===e)return"-";let s=e=Math.floor(e),t="",r=0;for(let e of[{value:31536e3,label:"y"},{value:2592e3,label:"mo"},{value:86400,label:"d"},{value:3600,label:"h"},{value:60,label:"m"},{value:1,label:"s"}])if(s>=e.value&&r<2){let l=Math.floor(s/e.value);t+="".concat(l).concat(e.label," "),s%=e.value,r++}return t.trim()||"0s"};function O(){let e=(0,a.useRouter)(),[s,t]=(0,l.useState)(!1),c=l.useRef(null),[u,d]=(0,l.useState)(!1),[h,m]=(0,l.useState)(!1),[j,v]=(0,l.useState)(null),[g,b]=(0,l.useState)(()=>!!e.isReady&&"true"===e.query.history),[k,L]=(0,l.useState)(!0),[M,R]=(0,l.useState)(()=>{if(e.isReady){let s=e.query.historyDays;if(s&&"string"==typeof s&&["1","5","10","30"].includes(s))return parseInt(s)}return 1}),_=(0,w.X)(),[O,Z]=(0,l.useState)([]),[q,H]=(0,l.useState)({status:[],cluster:[],user:[],workspace:[],infra:[],labels:[]}),[W,F]=(0,l.useState)(!1),[z,A]=(0,l.useState)(null);(0,l.useEffect)(()=>{if(e.isReady){T();let s="true"===e.query.history;g!==s&&(L(!1),b(s),setTimeout(()=>L(!0),50));let t=e.query.historyDays;if(t&&"string"==typeof t&&["1","5","10","30"].includes(t)){let e=parseInt(t);M!==e&&R(e)}}},[e.isReady,e.query.history,e.query.historyDays]),(0,l.useEffect)(()=>{(async()=>{try{await S.ZP.preloadForPage("clusters");let e=await C.ZP.get(p.getWorkspaces),s=Object.keys(e),t=await C.ZP.get(x.getClusters),r=[...new Set(t.map(e=>e.workspace||"default").filter(e=>e))],l=new Set(s);r.includes("default")&&l.has("default"),r.forEach(e=>l.add(e));let a=[...new Set(t.map(e=>({userId:e.user_hash||e.user,username:e.user})).filter(e=>e.userId)).values()],n=new Map;a.forEach(e=>{n.set(e.userId,{userId:e.userId,username:e.username,display:I(e.username,e.userId)})}),F(!0),A(new Date)}catch(e){console.error("Error fetching data for filters:",e),F(!0),A(new Date)}})()},[]);let B=s=>{let t={...e.query},r=[],l=[],a=[];s.map((e,s)=>{var t;r.push(null!==(t=e.property.toLowerCase())&&void 0!==t?t:""),l.push(e.operator),a.push(e.value)}),t.property=r,t.operator=l,t.value=a,e.replace({pathname:e.pathname,query:t},void 0,{shallow:!0})},U=s=>{let t={...e.query};t.history=s.toString(),e.replace({pathname:e.pathname,query:t},void 0,{shallow:!0})},Q=s=>{let t={...e.query};t.historyDays=s.toString(),e.replace({pathname:e.pathname,query:t},void 0,{shallow:!0})},T=()=>{let s={...e.query},t=s.property,r=s.operator,l=s.value;if(void 0===t)return;let a=[],n=Array.isArray(t)?t.length:1,i=new Map;if(i.set("",""),i.set("status","Status"),i.set("cluster","Cluster"),i.set("user","User"),i.set("workspace","Workspace"),i.set("infra","Infra"),1===n)a.push({property:i.get(t),operator:r,value:l});else for(let e=0;e<n;e++)a.push({property:i.get(t[e]),operator:r[e],value:l[e]});Z(a)};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)("div",{className:"flex flex-wrap items-center gap-2 mb-1 min-h-[20px]",children:[(0,r.jsx)("div",{className:"flex items-center gap-2",children:(0,r.jsx)(o(),{href:"/clusters",className:"text-sky-blue hover:underline leading-none text-base",children:"Sky Clusters"})}),(0,r.jsx)("div",{className:"w-full sm:w-auto",children:(0,r.jsx)(V,{propertyList:E,valueList:q,setFilters:Z,updateURLParams:B,placeholder:"Filter clusters",filters:O})}),(0,r.jsxs)("div",{className:"flex items-center gap-2 ml-auto",children:[(0,r.jsxs)("div",{className:"flex items-center gap-2",children:[(0,r.jsxs)("label",{className:"flex items-center cursor-pointer",children:[(0,r.jsx)("input",{type:"checkbox",checked:g,onChange:e=>{let s=e.target.checked;b(s),U(s)},className:"sr-only"}),(0,r.jsx)("div",{className:"relative inline-flex h-5 w-9 items-center rounded-full ".concat(k?"transition-colors":""," ").concat(g?"bg-sky-600":"bg-gray-300"),children:(0,r.jsx)("span",{className:"inline-block h-3 w-3 transform rounded-full bg-white ".concat(k?"transition-transform":""," ").concat(g?"translate-x-5":"translate-x-1")})}),(0,r.jsx)("span",{className:"ml-2 text-sm text-gray-700",children:"Show history"})]}),g&&(0,r.jsxs)(N.Ph,{value:M.toString(),onValueChange:e=>{let s=parseInt(e);R(s),Q(s)},children:[(0,r.jsx)(N.i4,{className:"w-24 h-8 text-xs",children:(0,r.jsx)(N.ki,{})}),(0,r.jsxs)(N.Bw,{children:[(0,r.jsx)(N.Ql,{value:"1",children:"1 day"}),(0,r.jsx)(N.Ql,{value:"5",children:"5 days"}),(0,r.jsx)(N.Ql,{value:"10",children:"10 days"}),(0,r.jsx)(N.Ql,{value:"30",children:"30 days"})]})]})]}),s&&(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)(n.Z,{size:15,className:"mt-0"}),(0,r.jsx)("span",{className:"ml-2 text-gray-500 text-sm",children:"Loading..."})]}),!s&&z&&(0,r.jsx)(i.$3,{timestamp:z}),(0,r.jsxs)("button",{onClick:()=>{C.ZP.invalidate(x.getClusters),C.ZP.invalidate(p.getWorkspaces),g&&C.ZP.invalidate(x.uR),F(!1),S.ZP.preloadForPage("clusters",{force:!0}).then(()=>{F(!0),A(new Date),c.current&&c.current()})},disabled:s,className:"text-sky-blue hover:text-sky-blue-bright flex items-center",children:[(0,r.jsx)(f.Z,{className:"h-4 w-4 mr-1.5"}),!_&&(0,r.jsx)("span",{children:"Refresh"})]})]})]}),(0,r.jsx)(D,{filters:O,setFilters:Z,updateURLParams:B}),(0,r.jsx)(P,{refreshInterval:i.yc,setLoading:t,refreshDataRef:c,filters:O,showHistory:g,historyDays:M,onOpenSSHModal:e=>{v(e),d(!0)},onOpenVSCodeModal:e=>{v(e),m(!0)},setOptionValues:H,preloadingComplete:W}),(0,r.jsx)(y.Oh,{isOpen:u,onClose:()=>d(!1),cluster:j}),(0,r.jsx)(y._R,{isOpen:h,onClose:()=>m(!1),cluster:j})]})}function P(e){let{refreshInterval:s,setLoading:t,refreshDataRef:a,filters:c,showHistory:p,historyDays:f,onOpenSSHModal:j,onOpenVSCodeModal:v,setOptionValues:g,preloadingComplete:y}=e,[w,N]=(0,l.useState)([]),[S,E]=(0,l.useState)({key:null,direction:"ascending"}),[I,O]=(0,l.useState)(!1),[P,Z]=(0,l.useState)(!0),[q,H]=(0,l.useState)(1),[W,V]=(0,l.useState)(10),D=e=>{let s={status:[],cluster:[],user:[],workspace:[],infra:[],labels:[]},t=(e,s)=>{e.includes(s)||e.push(s)};return e.map(e=>{t(s.status,e.status),t(s.cluster,e.cluster),t(s.user,e.user),t(s.workspace,e.workspace),t(s.infra,e.infra);let r=e.labels||{};r&&"object"==typeof r&&Object.entries(r).forEach(e=>{let[r,l]=e;r&&l&&t(s.labels,"".concat(r,":").concat(l))})}),s},z=l.useCallback(async()=>{t(!0),O(!0);try{let e=await C.ZP.get(x.getClusters);if(p){let s=[];try{s=await C.ZP.get(x.uR,[null,f])}catch(e){console.error("Error fetching cluster history:",e)}let t=e.map(e=>({...e,isHistorical:!1})),r=s.map(e=>({...e,isHistorical:!0})),l=[...t];r.forEach(s=>{e.some(e=>e.cluster_hash===s.cluster_hash)||l.push(s)}),g(D(l)),N(l)}else{let s=e.map(e=>({...e,isHistorical:!1}));g(D(s)),N(s)}}catch(e){console.error("Error fetching cluster data:",e),g(D([])),N([])}t(!1),O(!1),Z(!1)},[t,p,f,g]),A=l.useMemo(()=>{let e=0===c.length?w:w.filter(e=>{let s=null;for(let t=0;t<c.length;t++){let r=c[t],l=(0,M.mu)(e,r);s=null===s?l:s&&l}return s});return(0,m.R0)(e,S.key,S.direction)},[w,S,c]);l.useEffect(()=>{a&&(a.current=z)},[a,z]),(0,l.useEffect)(()=>{N([]);let e=!0;if(y){z();let t=setInterval(()=>{e&&"visible"===window.document.visibilityState&&z()},s);return()=>{e=!1,clearInterval(t)}}return()=>{e=!1}},[s,z,y]),(0,l.useEffect)(()=>{H(1)},[w.length]);let B=e=>{let s="ascending";S.key===e&&"ascending"===S.direction&&(s="descending"),E({key:e,direction:s})},U=e=>S.key===e?"ascending"===S.direction?" ↑":" ↓":"",Q=Math.ceil(A.length/W),T=(q-1)*W,X=T+W,$=A.slice(T,X);return(0,r.jsxs)("div",{children:[(0,r.jsx)(d.Zb,{children:(0,r.jsx)("div",{className:"overflow-x-auto rounded-lg",children:(0,r.jsxs)(h.iA,{className:"min-w-full",children:[(0,r.jsx)(h.xD,{children:(0,r.jsxs)(h.SC,{children:[(0,r.jsxs)(h.ss,{className:"sortable whitespace-nowrap",onClick:()=>B("status"),children:["Status",U("status")]}),(0,r.jsxs)(h.ss,{className:"sortable whitespace-nowrap",onClick:()=>B("cluster"),children:["Cluster",U("cluster")]}),(0,r.jsxs)(h.ss,{className:"sortable whitespace-nowrap",onClick:()=>B("user"),children:["User",U("user")]}),(0,r.jsxs)(h.ss,{className:"sortable whitespace-nowrap",onClick:()=>B("workspace"),children:["Workspace",U("workspace")]}),(0,r.jsxs)(h.ss,{className:"sortable whitespace-nowrap",onClick:()=>B("infra"),children:["Infra",U("infra")]}),(0,r.jsxs)(h.ss,{className:"sortable whitespace-nowrap",onClick:()=>B("resources_str"),children:["Resources",U("resources_str")]}),(0,r.jsxs)(h.ss,{className:"sortable whitespace-nowrap",onClick:()=>B("time"),children:["Started",U("time")]}),p&&(0,r.jsxs)(h.ss,{className:"sortable whitespace-nowrap",onClick:()=>B("duration"),children:["Duration",U("duration")]}),(0,r.jsxs)(h.ss,{className:"sortable whitespace-nowrap",onClick:()=>B("autostop"),children:["Autostop",U("autostop")]}),(0,r.jsx)(h.ss,{className:"md:sticky md:right-0 md:bg-white",children:"Actions"})]})}),(0,r.jsx)(h.RM,{children:I||!y?(0,r.jsx)(h.SC,{children:(0,r.jsx)(h.pj,{colSpan:9,className:"text-center py-6 text-gray-500",children:(0,r.jsxs)("div",{className:"flex justify-center items-center",children:[(0,r.jsx)(n.Z,{size:20,className:"mr-2"}),(0,r.jsx)("span",{children:"Loading..."})]})})}):$.length>0?$.map((e,s)=>(0,r.jsxs)(h.SC,{children:[(0,r.jsx)(h.pj,{children:(0,r.jsx)(k.j,{name:"clusters.table.status.badge",context:e,fallback:(0,r.jsx)(b.OE,{status:e.status,statusTooltip:e.statusTooltip})})}),(0,r.jsx)(h.pj,{children:(0,r.jsx)(o(),{href:"/clusters/".concat(e.isHistorical?e.cluster_hash:e.cluster||e.name),className:"text-blue-600",children:e.cluster||e.name})}),(0,r.jsx)(h.pj,{children:(0,r.jsx)(L.H,{username:e.user,userHash:e.user_hash})}),(0,r.jsx)(h.pj,{children:(0,r.jsx)(o(),{href:"/workspaces",className:"text-gray-700 hover:text-blue-600 hover:underline",children:e.workspace||"default"})}),(0,r.jsx)(h.pj,{children:(0,r.jsx)(i.Md,{content:e.full_infra||e.infra,className:"text-sm text-muted-foreground",children:(0,r.jsxs)("span",{children:[(0,r.jsx)(o(),{href:"/infra",className:"text-blue-600 hover:underline",children:e.cloud}),e.infra.includes("(")&&(0,r.jsx)("span",{children:" "+e.infra.substring(e.infra.indexOf("("))})]})})}),(0,r.jsx)(h.pj,{children:(0,r.jsx)(i.Md,{content:e.resources_str_full||e.resources_str,className:"text-sm text-muted-foreground",children:(0,r.jsx)("span",{children:e.resources_str})})}),(0,r.jsx)(h.pj,{children:(0,r.jsx)(i.Zg,{date:e.time})}),p&&(0,r.jsx)(h.pj,{children:_(e.duration)}),(0,r.jsx)(h.pj,{children:e.isHistorical?"-":R(e.autostop,e.to_down)}),(0,r.jsx)(h.pj,{className:"text-left md:sticky md:right-0 md:bg-white",children:!e.isHistorical&&(0,r.jsx)(F,{cluster:e.cluster,status:e.status,onOpenSSHModal:j,onOpenVSCodeModal:v})})]},s)):(0,r.jsx)(h.SC,{children:(0,r.jsx)(h.pj,{colSpan:9,className:"text-center py-6 text-gray-500",children:p?"No clusters found":"No active clusters"})})})]})})}),w.length>0&&(0,r.jsx)("div",{className:"flex justify-end items-center py-2 px-4 text-sm text-gray-700",children:(0,r.jsxs)("div",{className:"flex items-center space-x-4",children:[(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)("span",{className:"mr-2",children:"Rows per page:"}),(0,r.jsxs)("div",{className:"relative inline-block",children:[(0,r.jsxs)("select",{value:W,onChange:e=>{V(parseInt(e.target.value,10)),H(1)},className:"py-1 pl-2 pr-6 appearance-none outline-none cursor-pointer border-none bg-transparent",style:{minWidth:"40px"},children:[(0,r.jsx)("option",{value:10,children:"10"}),(0,r.jsx)("option",{value:30,children:"30"}),(0,r.jsx)("option",{value:50,children:"50"}),(0,r.jsx)("option",{value:100,children:"100"}),(0,r.jsx)("option",{value:200,children:"200"})]}),(0,r.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-4 w-4 text-gray-500 absolute right-0 top-1/2 transform -translate-y-1/2 pointer-events-none",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:(0,r.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"})})]})]}),(0,r.jsx)("div",{children:"".concat(T+1," - ").concat(Math.min(X,A.length)," of ").concat(A.length)}),(0,r.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,r.jsx)(u.z,{variant:"ghost",size:"icon",onClick:()=>{H(e=>Math.max(e-1,1))},disabled:1===q,className:"text-gray-500 h-8 w-8 p-0",children:(0,r.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:"chevron-left",children:(0,r.jsx)("path",{d:"M15 18l-6-6 6-6"})})}),(0,r.jsx)(u.z,{variant:"ghost",size:"icon",onClick:()=>{H(e=>Math.min(e+1,Q))},disabled:q===Q||0===Q,className:"text-gray-500 h-8 w-8 p-0",children:(0,r.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:"chevron-right",children:(0,r.jsx)("path",{d:"M9 18l6-6-6-6"})})})]})]})})]})}let Z=(e,s)=>{s&&s(e)},q=(e,s)=>{s?s(e):window.open("ssh://".concat(e))},H=e=>"RUNNING"===e?["connect","VSCode"]:[],W={connect:(0,r.jsx)(v,{className:"w-4 h-4 text-gray-500 inline-block"}),VSCode:(0,r.jsx)(g,{className:"w-4 h-4 text-gray-500 inline-block"})};function F(e){let{withLabel:s=!1,cluster:t,status:l,onOpenSSHModal:a,onOpenVSCodeModal:n}=e,c=H(l),o=(0,w.X)(),u=e=>{switch(e){case"connect":q(t,a);break;case"VSCode":Z(t,n);break;default:return}};return(0,r.jsx)(r.Fragment,{children:(0,r.jsx)("div",{className:"flex items-center space-x-4",children:Object.entries(W).map(e=>{let t,l,[a,n]=e;switch(a){case"connect":t="Connect",l="Connect with SSH";break;case"VSCode":t="VSCode",l="Open in VS Code"}return(s||(t=""),c.includes(a))?(0,r.jsx)(i.WH,{content:l,className:"capitalize text-sm text-muted-foreground",children:(0,r.jsxs)("button",{onClick:()=>u(a),className:"text-sky-blue hover:text-sky-blue-bright font-medium inline-flex items-center",children:[n,!o&&(0,r.jsx)("span",{className:"ml-1.5",children:t})]})},a):(0,r.jsx)(i.WH,{content:l,className:"capitalize text-sm text-muted-foreground",children:(0,r.jsxs)("span",{className:"opacity-30 flex items-center cursor-not-allowed text-sm",title:a,children:[n,!o&&(0,r.jsx)("span",{className:"ml-1.5",children:t})]})},a)})})})}let V=e=>{let{propertyList:s=[],valueList:t,setFilters:a,updateURLParams:n,placeholder:i="Filter clusters",filters:c=[]}=e,o=(0,l.useRef)(null),u=(0,l.useRef)(null),[d,h]=(0,l.useState)(!1),[x,p]=(0,l.useState)(""),[m,f]=(0,l.useState)("status"),[j,v]=(0,l.useState)([]);(0,l.useEffect)(()=>{let e=e=>{u.current&&!u.current.contains(e.target)&&o.current&&!o.current.contains(e.target)&&h(!1)};return document.addEventListener("mousedown",e),()=>{document.removeEventListener("mousedown",e)}},[]),(0,l.useEffect)(()=>{let e=[],s=m||"";if(s.length>1){s=m[0].toUpperCase();for(let e=1;e<m.length;e++)s+=m[e]}let r=c.filter(e=>e.property===s).map(e=>e.value);if(t&&"object"==typeof t)switch(m){case"status":e=t.status.filter(e=>!r.find(s=>s===e))||[];break;case"user":e=t.user.filter(e=>!r.find(s=>s===e))||[];break;case"cluster":e=t.cluster.filter(e=>!r.find(s=>s===e))||[];break;case"workspace":e=t.workspace.filter(e=>!r.find(s=>s===e))||[];break;case"infra":e=t.infra.filter(e=>!r.find(s=>s===e))||[];break;case"labels":e=t.labels.filter(e=>!r.find(s=>s===e))||[]}""!==x.trim()&&(e=e.filter(e=>e&&e.toString().toLowerCase().includes(x.toLowerCase()))),v(e)},[m,t,x,c]);let g=e=>{let t=s.find(s=>s.value===e);return t?t.label:e},y=e=>{a(s=>{let t=[...s,{property:g(m),operator:":",value:e}];return n(t),t}),h(!1),p(""),o.current.focus()};return(0,r.jsxs)("div",{className:"flex flex-row border border-gray-300 rounded-md overflow-visible",children:[(0,r.jsx)("div",{className:"border-r border-gray-300 flex-shrink-0",children:(0,r.jsxs)(N.Ph,{onValueChange:f,value:m,children:[(0,r.jsx)(N.i4,{"aria-label":"Filter Property",className:"focus:ring-0 focus:ring-offset-0 border-none rounded-l-md rounded-r-none w-20 sm:w-24 md:w-32 h-8 text-xs sm:text-sm",children:(0,r.jsx)(N.ki,{placeholder:"Status"})}),(0,r.jsx)(N.Bw,{children:s.map((e,s)=>(0,r.jsx)(N.Ql,{value:e.value,children:e.label},"property-item-".concat(s)))})]})}),(0,r.jsxs)("div",{className:"relative flex-1",children:[(0,r.jsx)("input",{type:"text",ref:o,placeholder:i,value:x,onChange:e=>{p(e.target.value),d||h(!0)},onFocus:()=>{h(!0)},onKeyDown:e=>{"Enter"===e.key&&""!==x.trim()?(a(e=>{let s=[...e,{property:g(m),operator:":",value:x}];return n(s),s}),p(""),h(!1)):"Escape"===e.key&&(h(!1),o.current.blur())},className:"h-8 w-full sm:w-96 px-3 pr-8 text-sm border-none rounded-l-none rounded-r-md focus:ring-0 focus:outline-none",autoComplete:"off"}),x&&(0,r.jsx)("button",{onClick:()=>{p(""),h(!1)},className:"absolute right-2 top-1/2 transform -translate-y-1/2 text-gray-400 hover:text-gray-600",title:"Clear filter",tabIndex:-1,children:(0,r.jsx)("svg",{className:"h-4 w-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,r.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})}),d&&j.length>0&&(0,r.jsx)("div",{ref:u,className:"absolute z-50 mt-1 w-full bg-white border border-gray-200 rounded-md shadow-lg max-h-60 overflow-y-auto",style:{zIndex:9999},children:j.map((e,s)=>(0,r.jsx)("div",{className:"px-3 py-2 cursor-pointer hover:bg-gray-50 text-sm ".concat(s!==j.length-1?"border-b border-gray-100":""),onClick:()=>y(e),children:(0,r.jsx)("span",{className:"text-sm text-gray-700",children:e})},"".concat(e,"-").concat(s)))})]})]})},D=e=>{let{filters:s=[],setFilters:t,updateURLParams:l}=e,a=e=>{t(s=>{let t=s.filter((s,t)=>t!==e);return l(t),t})};return(0,r.jsx)(r.Fragment,{children:(0,r.jsx)("div",{className:"flex items-center gap-4 py-2 px-2",children:(0,r.jsxs)("div",{className:"flex flex-wrap items-content gap-2",children:[s.map((e,s)=>(0,r.jsx)(z,{filter:e,onRemove:()=>a(s)},"filteritem-".concat(s))),s.length>0&&(0,r.jsx)(r.Fragment,{children:(0,r.jsx)("button",{onClick:()=>{l([]),t([])},className:"rounded-full px-4 py-1 text-sm text-gray-700 bg-gray-200 hover:bg-gray-300",children:"Clear filters"})})]})})})},z=e=>{let{filter:s,onRemove:t}=e;return(0,r.jsx)(r.Fragment,{children:(0,r.jsxs)("div",{className:"flex items-center text-blue-600 bg-blue-100 px-1 py-1 rounded-full text-sm",children:[(0,r.jsxs)("div",{className:"flex items-center gap-1 px-2",children:[(0,r.jsx)("span",{children:"".concat(s.property," ")}),(0,r.jsx)("span",{children:"".concat(s.operator," ")}),(0,r.jsx)("span",{children:" ".concat(s.value)})]}),(0,r.jsx)("button",{onClick:()=>t(),className:"p-0.5 ml-1 transform text-gray-400 hover:text-gray-600 bg-blue-500 hover:bg-blue-600 rounded-full flex flex-col items-center",title:"Clear filter",children:(0,r.jsx)("svg",{className:"h-3 w-3",fill:"none",stroke:"white",viewBox:"0 0 24 24",children:(0,r.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:5,d:"M6 18L18 6M6 6l12 12"})})})]})})}},12003:function(e,s,t){t.d(s,{j:function(){return n}});var r=t(90512);let l=e=>"boolean"==typeof e?`${e}`:0===e?"0":e,a=r.W,n=(e,s)=>t=>{var r;if((null==s?void 0:s.variants)==null)return a(e,null==t?void 0:t.class,null==t?void 0:t.className);let{variants:n,defaultVariants:i}=s,c=Object.keys(n).map(e=>{let s=null==t?void 0:t[e],r=null==i?void 0:i[e];if(null===s)return null;let a=l(s)||l(r);return n[e][a]}),o=t&&Object.entries(t).reduce((e,s)=>{let[t,r]=s;return void 0===r||(e[t]=r),e},{});return a(e,c,null==s?void 0:null===(r=s.compoundVariants)||void 0===r?void 0:r.reduce((e,s)=>{let{class:t,className:r,...l}=s;return Object.entries(l).every(e=>{let[s,t]=e;return Array.isArray(t)?t.includes({...i,...o}[s]):({...i,...o})[s]===t})?[...e,t,r]:e},[]),null==t?void 0:t.class,null==t?void 0:t.className)}}}]);
@@ -0,0 +1,11 @@
1
+ "use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[2109],{16826:function(e,s,t){t.d(s,{Z:function(){return a}});/**
2
+ * @license lucide-react v0.407.0 - ISC
3
+ *
4
+ * This source code is licensed under the ISC license.
5
+ * See the LICENSE file in the root directory of this source tree.
6
+ */let a=(0,t(60998).Z)("Download",[["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["polyline",{points:"7 10 12 15 17 10",key:"2ggqvy"}],["line",{x1:"12",x2:"12",y1:"15",y2:"3",key:"1vk2je"}]])},20546:function(e,s,t){t.d(s,{H:function(){return d}});var a=t(85893);t(67294);var n=t(41664),r=t.n(n),l=t(45697),i=t.n(l);function c(e){return!!e&&"string"==typeof e&&e.toLowerCase().startsWith("sa-")}let o=()=>(0,a.jsx)("span",{className:"px-2 py-0.5 text-xs bg-blue-100 text-blue-700 rounded font-medium ml-1",children:"SA"}),d=e=>{let{username:s,userHash:t,className:n="flex items-center gap-1",linkClassName:l="text-gray-700 hover:text-blue-600 hover:underline",showBadge:i=!0}=e,d=c(t),h=c(t)?"/users?tab=service-accounts":"/users";return(0,a.jsxs)("div",{className:n,children:[(0,a.jsx)(r(),{href:h,className:l,children:s}),i&&d&&(0,a.jsx)(o,{})]})};d.propTypes={username:i().string.isRequired,userHash:i().string,className:i().string,linkClassName:i().string,showBadge:i().bool}},92128:function(e,s,t){t.d(s,{Oh:function(){return u},_R:function(){return x},cV:function(){return m}});var a=t(85893),n=t(67294),r=t(50326),l=t(30803),i=t(37673),c=t(27325),o=t(36989),d=t(93225),h=t(23001);function u(e){let{isOpen:s,onClose:t,cluster:d}=e,[h,u]=n.useState(!1),x=e=>{navigator.clipboard.writeText(e),u(!0),setTimeout(()=>u(!1),2e3)},m=["sky status ".concat(d),"ssh ".concat(d)],j=m.join("\n");return(0,a.jsx)(r.Vq,{open:s,onOpenChange:t,children:(0,a.jsxs)(r.cZ,{className:"sm:max-w-md",children:[(0,a.jsxs)(r.fK,{children:[(0,a.jsxs)(r.$N,{children:["Connect to: ",(0,a.jsx)("span",{className:"font-light",children:d})]}),(0,a.jsx)(r.Be,{children:"Use these instructions to connect to your cluster via SSH."})]}),(0,a.jsxs)("div",{className:"flex flex-col space-y-4",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("h3",{className:"text-sm font-medium mb-2",children:"SSH Command"}),(0,a.jsx)(i.Zb,{className:"p-3 bg-gray-50",children:(0,a.jsxs)("div",{className:"flex items-center justify-between",children:[(0,a.jsx)("pre",{className:"text-sm w-full whitespace-pre-wrap",children:m.map((e,s)=>(0,a.jsx)("code",{className:"block",children:e},s))}),(0,a.jsx)(o.WH,{content:h?"Copied!":"Copy command",children:(0,a.jsx)(l.z,{variant:"ghost",size:"icon",onClick:()=>x(j),className:"h-8 w-8 rounded-full",children:(0,a.jsx)(c.Z,{className:"h-4 w-4"})})})]})})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("h3",{className:"text-sm font-medium mb-2",children:"Additional Information"}),(0,a.jsxs)("p",{className:"text-sm text-secondary-foreground",children:["Make sure to run"," ",(0,a.jsxs)("code",{className:"text-sm",children:["sky status ",d]})," first to have SkyPilot set up the SSH access."]})]})]})]})})}function x(e){let{isOpen:s,onClose:t,cluster:n}=e,u=(0,h.X)();return(0,a.jsx)(r.Vq,{open:s,onOpenChange:t,children:(0,a.jsx)(r.cZ,{className:"sm:max-w-3xl",children:(0,a.jsxs)(r.fK,{children:[(0,a.jsxs)(r.$N,{children:["Connect to: ",(0,a.jsx)("span",{className:"font-light",children:n})]}),(0,a.jsx)(r.Be,{children:(0,a.jsxs)("div",{className:"flex flex-col space-y-4",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("h3",{className:"text-sm font-medium mb-2 my-2",children:"Setup SSH access"}),(0,a.jsx)(i.Zb,{className:"p-3 bg-gray-50",children:(0,a.jsxs)("div",{className:"flex items-center justify-between",children:[(0,a.jsx)("pre",{className:"text-sm",children:(0,a.jsxs)("code",{children:["sky status ",n]})}),(0,a.jsx)(o.WH,{content:"Copy command",children:(0,a.jsx)(l.z,{variant:"ghost",size:"icon",onClick:()=>navigator.clipboard.writeText("sky status ".concat(n)),className:"h-8 w-8 rounded-full",children:(0,a.jsx)(c.Z,{className:"h-4 w-4"})})})]})})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("h3",{className:"text-sm font-medium mb-2 my-2",children:"Connect with VSCode/Cursor"}),(0,a.jsx)(i.Zb,{className:"p-3 bg-gray-50",children:(0,a.jsxs)("div",{className:"flex items-center justify-between",children:[(0,a.jsx)("pre",{className:"text-sm",children:(0,a.jsxs)("code",{children:["code --remote ssh-remote+",n,' "/home"']})}),(0,a.jsx)(o.WH,{content:"Copy command",children:(0,a.jsx)(l.z,{variant:"ghost",size:"icon",onClick:()=>navigator.clipboard.writeText("code --remote ssh-remote+".concat(n,' "/home"')),className:"h-8 w-8 rounded-full",children:(0,a.jsx)(c.Z,{className:"h-4 w-4"})})})]})})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("h3",{className:"text-sm font-medium",children:"Or use the GUI to connect"}),(0,a.jsx)("div",{className:"relative ".concat(u?"-mt-5":"-mt-10"),style:{paddingBottom:"70%"},children:(0,a.jsxs)("video",{className:"absolute top-0 left-0 w-full h-full rounded-lg",controls:!0,autoPlay:!0,muted:!0,preload:"metadata",children:[(0,a.jsx)("source",{src:"".concat(d.GW,"/videos/cursor-small.mp4"),type:"video/mp4"}),"Your browser does not support the video tag."]})})]})]})})]})})})}function m(e){let{isOpen:s,onClose:t,onConfirm:n,title:i,message:c,confirmText:o="Confirm",confirmVariant:d="destructive",confirmClassName:h=null}=e;return(0,a.jsx)(r.Vq,{open:s,onOpenChange:t,children:(0,a.jsxs)(r.cZ,{className:"sm:max-w-md",children:[(0,a.jsxs)(r.fK,{children:[(0,a.jsx)(r.$N,{children:i}),(0,a.jsx)(r.Be,{children:c})]}),(0,a.jsxs)(r.cN,{className:"flex justify-end gap-2 pt-4",children:[(0,a.jsx)(l.z,{variant:"outline",onClick:t,children:"Cancel"}),(0,a.jsx)(l.z,{variant:h?void 0:d,className:h,onClick:()=>{n(),t()},children:o})]})]})})}},2109:function(e,s,t){t.r(s),t.d(s,{ClusterJobs:function(){return H},ManagedJobs:function(){return T},ManagedJobsTable:function(){return U},Status2Actions:function(){return W},filterJobsByName:function(){return I},filterJobsByPool:function(){return z},filterJobsByUser:function(){return Z},filterJobsByWorkspace:function(){return P},statusGroups:function(){return F}});var a=t(85893),n=t(67294),r=t(11163),l=t(41664),i=t.n(l),c=t(55739),o=t(30803),d=t(37673),h=t(68764),u=t(36989),x=t(51214),m=t(68969),j=t(6378);class p{_generateFilterKey(e){let{allUsers:s=!0,nameMatch:t,userMatch:a,workspaceMatch:n,poolMatch:r,statuses:l}=e;return["allUsers:".concat(s),t?"name:".concat(t):"",a?"user:".concat(a):"",n?"workspace:".concat(n):"",r?"pool:".concat(r):"",l&&l.length>0?"statuses:".concat(l.sort().join(",")):""].filter(Boolean).join("|")||"default"}_getCacheStatus(e){let s=this.fullDataCache.get(e),t=Date.now();if(!s)return{isCached:!1,isFresh:!1,age:0,maxAge:12e4,hasData:!1};let a=t-s.timestamp;return{isCached:!0,isFresh:a<12e4,age:a,maxAge:12e4,hasData:s.jobs&&Array.isArray(s.jobs),data:s}}async getPaginatedJobs(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{page:s=1,limit:t=10,...a}=e,n=this._generateFilterKey(a);try{let e=this._getCacheStatus(n);if(e.isCached&&e.hasData){let r=e.data;if(!r.jobs||Array.isArray(r.jobs)&&0===r.jobs.length){if(!this.prefetching.has(n)){let e=this._loadFullDataset(a,n).catch(()=>{}).finally(()=>this.prefetching.delete(n));this.prefetching.set(n,e)}}else{let l=(s-1)*t,i=r.jobs.slice(l,l+t);if(!this.prefetching.has(n)&&(!e.isFresh||e.age>e.maxAge/2)){let e=this._loadFullDataset(a,n).catch(()=>{}).finally(()=>this.prefetching.delete(n));this.prefetching.set(n,e)}return{jobs:i,total:r.total,totalNoFilter:r.totalNoFilter||r.total,controllerStopped:r.controllerStopped,statusCounts:r.statusCounts||{},fromCache:!0,cacheStatus:e.isFresh?"local_cache_hit":"local_cache_stale_hit"}}}let r=await j.ZP.get(m.getManagedJobs,[{...a,page:s,limit:t}]),l=(null==r?void 0:r.jobs)||[],i="number"==typeof(null==r?void 0:r.total)?r.total:l.length,c=!!(null==r?void 0:r.controllerStopped);if(!this.prefetching.has(n)){let e=this._loadFullDataset(a,n).catch(e=>{console.warn("Background prefetch of full jobs failed:",e)}).finally(()=>{this.prefetching.delete(n)});this.prefetching.set(n,e)}return{jobs:l,total:i,totalNoFilter:(null==r?void 0:r.totalNoFilter)||i,controllerStopped:c,statusCounts:(null==r?void 0:r.statusCounts)||{},fromCache:!1,cacheStatus:"server_page_fetch"}}catch(e){throw console.error("Error in getPaginatedJobs:",e),e}}async _loadFullDataset(e,s){let t=await j.ZP.get(m.getManagedJobs,[e]);if(t&&t.__skipCache||t.controllerStopped||!t.jobs)return t;let a={jobs:t.jobs,total:t.jobs.length,totalNoFilter:t.totalNoFilter||t.jobs.length,controllerStopped:!1,statusCounts:t.statusCounts||{},timestamp:Date.now()};return this.fullDataCache.set(s,a),a}isDataLoading(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},s=this._generateFilterKey(e);return this.isLoading.has(s)||this.prefetching.has(s)}isDataCached(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},s=this._generateFilterKey(e),t=this._getCacheStatus(s);return t.isCached&&t.isFresh&&t.hasData}getCacheStatus(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},s=this._generateFilterKey(e);return this._getCacheStatus(s)}invalidateCache(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;if(e){let s=this._generateFilterKey(e);this.fullDataCache.delete(s),this.isLoading.delete(s),this.prefetching.delete(s)}else this.fullDataCache.clear(),this.isLoading.clear(),this.prefetching.clear();j.ZP.invalidateFunction(m.getManagedJobs)}getCacheStats(){let e={cachedFilters:Array.from(this.fullDataCache.keys()),loadingFilters:Array.from(this.isLoading.keys()),prefetchingFilters:Array.from(this.prefetching.keys()),cacheSize:this.fullDataCache.size,loadingCount:this.isLoading.size,prefetchingCount:this.prefetching.size};for(let[s,t]of(e.detailedStatus={},this.fullDataCache.entries())){let a=this._getCacheStatus(s);e.detailedStatus[s]={age:a.age,isFresh:a.isFresh,hasData:a.hasData,jobCount:t.jobs?t.jobs.length:0}}return e}constructor(){this.fullDataCache=new Map,this.isLoading=new Map,this.prefetching=new Map}}let f=new p;var g=t(23266),b=t(17324),v=t(13626),N=t(60998);/**
7
+ * @license lucide-react v0.407.0 - ISC
8
+ *
9
+ * This source code is licensed under the ISC license.
10
+ * See the LICENSE file in the root directory of this source tree.
11
+ */let y=(0,N.Z)("RefreshCcw",[["path",{d:"M21 12a9 9 0 0 0-9-9 9.75 9.75 0 0 0-6.74 2.74L3 8",key:"14sxne"}],["path",{d:"M3 3v5h5",key:"1xhq8a"}],["path",{d:"M3 12a9 9 0 0 0 9 9 9.75 9.75 0 0 0 6.74-2.74L21 16",key:"1hlbsb"}],["path",{d:"M16 16h5v5",key:"ccwih5"}]]),w=(0,N.Z)("FileSearch",[["path",{d:"M14 2v4a2 2 0 0 0 2 2h4",key:"tnqrlb"}],["path",{d:"M4.268 21a2 2 0 0 0 1.727 1H18a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v3",key:"ms7g94"}],["path",{d:"m9 18-1.5-1.5",key:"1j6qii"}],["circle",{cx:"5",cy:"14",r:"3",key:"ufru5t"}]]);var k=t(16826),C=t(92128),S=t(94545),_=t(99307),L=t(20546),E=t(23001),D=t(36856),R=t(55988),M=t(10546);let F={active:["PENDING","RUNNING","RECOVERING","SUBMITTED","STARTING","CANCELLING"],finished:["SUCCEEDED","FAILED","CANCELLED","FAILED_SETUP","FAILED_PRECHECKS","FAILED_NO_RESOURCE","FAILED_CONTROLLER"]},A=[{label:"Name",value:"name"},{label:"User",value:"user"},{label:"Workspace",value:"workspace"},{label:"Pool",value:"pool"},{label:"Labels",value:"labels"}];function I(e,s){if(!s||""===s.trim())return e;let t=s.toLowerCase().trim();return e.filter(e=>(e.name||"").toLowerCase().includes(t))}function P(e,s){return s&&"ALL_WORKSPACES"!==s?e.filter(e=>(e.workspace||"default").toLowerCase()===s.toLowerCase()):e}function Z(e,s){return s&&"ALL_USERS"!==s?e.filter(e=>(e.user_hash||e.user)===s):e}function z(e,s){if(!s||""===s.trim())return e;let t=s.toLowerCase().trim();return e.filter(e=>(e.pool||"").toLowerCase().includes(t))}let O=e=>{if(!e)return"-";let s=e instanceof Date?e:new Date(1e3*e);return(0,a.jsx)(u.Zg,{date:s})};function T(){let e=(0,r.useRouter)(),[s,t]=(0,n.useState)(!1),[l,c]=(0,n.useState)(!0),[o,d]=(0,n.useState)(!0),h=n.useRef(null),x=n.useRef(null),[p,g]=(0,n.useState)([]),[v,N]=(0,n.useState)([]),[y,w]=(0,n.useState)({name:[],user:[],workspace:[],pool:[],labels:[]}),[k,C]=(0,n.useState)(!1),[S,_]=(0,n.useState)(null),L=n.useCallback(async function(){let e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];t(!0),!e&&o&&c(!0);try{let[e]=await Promise.all([j.ZP.get(m.vs,[{}])]);g(e.pools||[])}catch(e){console.error("Error fetching data:",e)}finally{t(!1),!e&&o&&(c(!1),d(!1))}},[o]);(0,n.useEffect)(()=>{(async()=>{try{await D.ZP.preloadForPage("jobs")}catch(e){console.error("Error preloading jobs data:",e)}finally{C(!0),_(new Date),L()}})()},[L]);let E=s=>{(0,M.eG)(e,s)},R=n.useCallback(()=>{let s=new Map;s.set("",""),s.set("status","Status"),s.set("name","Name"),s.set("user","User"),s.set("workspace","Workspace"),s.set("pool","Pool"),s.set("labels","Labels"),N((0,M.Fu)(e,s))},[e,N]);return(0,n.useEffect)(()=>{e.isReady&&R()},[e.isReady,e.query.tab,R]),(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("div",{className:"flex flex-wrap items-center gap-2 mb-1",children:[(0,a.jsx)("div",{className:"text-base",children:(0,a.jsx)(i(),{href:"/jobs",className:"text-sky-blue hover:underline leading-none",children:"Managed Jobs"})}),(0,a.jsx)("div",{className:"w-full sm:w-auto",children:(0,a.jsx)(M.ML,{propertyList:A,valueList:y,setFilters:N,updateURLParams:E,placeholder:"Filter jobs"})})]}),(0,a.jsx)(M.x$,{filters:v,setFilters:N,updateURLParams:E}),(0,a.jsx)(U,{refreshInterval:u.yc,setLoading:t,refreshDataRef:h,filters:v,onRefresh:()=>{f.invalidateCache(),j.ZP.invalidate(m.vs,[{}]),j.ZP.invalidate(b.getWorkspaces),C(!1),D.ZP.preloadForPage("jobs",{force:!0}).then(()=>{C(!0),_(new Date),h.current&&h.current(),x.current&&x.current()})},poolsData:p,poolsLoading:l,setValueList:w,preloadingComplete:k,lastFetchedTime:S}),(0,a.jsx)("div",{className:"mb-4",children:(0,a.jsx)(B,{refreshInterval:u.yc,setLoading:t,refreshDataRef:x})})]})}function U(e){let{refreshInterval:s,setLoading:t,refreshDataRef:r,filters:l,onRefresh:p,poolsData:b,poolsLoading:N,setValueList:w,preloadingComplete:k,lastFetchedTime:D}=e,[A,I]=(0,n.useState)([]),[P,Z]=(0,n.useState)(0),[z,T]=(0,n.useState)(0),[U,H]=(0,n.useState)({key:null,direction:"ascending"}),[B,G]=(0,n.useState)(!1),[K,V]=(0,n.useState)(!0),[$,Y]=(0,n.useState)(1),[X,Q]=(0,n.useState)(10),[ee,es]=(0,n.useState)(null),et=(0,n.useRef)(null),[ea,en]=(0,n.useState)([]),[er,el]=(0,n.useState)({}),[ei,ec]=(0,n.useState)({}),[eo,ed]=(0,n.useState)(!1),[eh,eu]=(0,n.useState)(!1),[ex,em]=(0,n.useState)(!1),[ej,ep]=(0,n.useState)("all"),[ef,eg]=(0,n.useState)(!0),[eb,ev]=(0,n.useState)({isOpen:!1,title:"",message:"",onConfirm:null}),eN=(0,E.X)(),ey=(0,n.useRef)(0),ew=n.useMemo(()=>{if(!A||0===A.length)return!1;let e=new Set(A.map(e=>e.workspace||"default"));return e.size>1||1===e.size&&!e.has("default")},[A]),ek=n.useMemo(()=>b&&b.length>0,[b]),eC=async()=>{ev({isOpen:!0,title:"Restart Controller",message:"Are you sure you want to restart the controller?",onConfirm:async()=>{try{em(!0),G(!0),await (0,m.Ce)("restartcontroller"),await eS()}catch(e){console.error("Error restarting controller:",e)}finally{em(!1),G(!1)}}})},eS=n.useCallback(async function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},s=!1!==e.includeStatus,a=ey.current+1;ey.current=a,G(!0),t(!0);try{let e;let t=e=>{let s=(l||[]).find(s=>(s.property||"").toLowerCase()===e);return s&&s.value?String(s.value):void 0};ea.length>0?e=ea:ef?"active"===ej?e=F.active:"finished"===ej&&(e=F.finished):e=[];let n={allUsers:!0,nameMatch:t("name"),userMatch:t("user"),workspaceMatch:t("workspace"),poolMatch:t("pool"),statuses:e,page:$,limit:X},r=null;if(f.isDataCached(n),f.isDataLoading(n),s)try{r=await j.ZP.get(g.getClusters)}catch(e){console.error("Error fetching clusters:",e)}let{jobs:i=[],total:c=0,totalNoFilter:o=0,controllerStopped:d=!1,cacheStatus:h="unknown",statusCounts:u={}}=await f.getPaginatedJobs(n)||{},x=!1,m=!1;if(s&&r){let e=null==r?void 0:r.find(e=>(0,S.Ym)(e.cluster)),s=e?e.status:"NOT_FOUND";"STOPPED"==s&&d&&(x=!0),"LAUNCHING"==s&&(m=!0)}a===ey.current&&(I(i),Z(c||0),T(o||0),ed(!!x),eu(!!m),ec(u),V(!1))}catch(e){console.error("Error fetching data:",e),a===ey.current&&(I([]),ed(!1),V(!1))}finally{a===ey.current&&(G(!1),t(!1))}},[t,l,$,X,ea,ef,ej]);n.useEffect(()=>{r&&(r.current=eS)},[r,eS]);let e_=n.useRef(eS);n.useEffect(()=>{e_.current=eS},[eS]);let eL=n.useRef(!0);n.useEffect(()=>{eS({includeStatus:!0}),eL.current=!1},[]),n.useEffect(()=>{!eL.current&&k&&eS({includeStatus:!1})},[$,eS,k]),n.useEffect(()=>{!eL.current&&k&&eS({includeStatus:!0})},[l,X,eS,k]),n.useEffect(()=>{!eL.current&&k&&eS({includeStatus:!0})},[ej,ea,ef,eS,k]),(0,n.useEffect)(()=>{if(!k)return;let e=setInterval(()=>{e_.current&&"visible"===window.document.visibilityState&&e_.current({includeStatus:!0})},s);return()=>{clearInterval(e)}},[s,k]),(0,n.useEffect)(()=>{Y(1)},[ej]),(0,n.useEffect)(()=>{Y(1)},[l,X]),(0,n.useEffect)(()=>{en([]),eg(!0)},[ej]),(0,n.useEffect)(()=>{if(!w)return;let e=new Set,s=new Set,t=new Set,a=new Set,n=new Set;A.forEach(r=>{r.name&&e.add(r.name),r.user&&s.add(r.user),r.workspace&&t.add(r.workspace),r.pool&&a.add(r.pool),Object.entries(r.labels||{}).forEach(e=>{let[s,t]=e;n.add("".concat(s,":").concat(t))})}),b&&Array.isArray(b)&&b.forEach(e=>{if(!e.name)return;let s=e.jobCounts&&Object.keys(e.jobCounts).length>0,t=null!==e.uptime&&void 0!==e.uptime&&e.uptime>0&&e.uptime<86400;(s||t)&&a.add(e.name)}),w({name:Array.from(e).sort(),user:Array.from(s).sort(),workspace:Array.from(t).sort(),pool:Array.from(a).sort(),labels:Array.from(n).sort()})},[A,b,w]);let eE=e=>{let s="ascending";U.key===e&&"ascending"===U.direction&&(s="descending"),H({key:e,direction:s})},eD=e=>U.key===e?"ascending"===U.direction?" ↑":" ↓":"";n.useMemo(()=>{let e=A||[];return{active:e.filter(e=>F.active.includes(e.status)).length,finished:e.filter(e=>F.finished.includes(e.status)).length}},[A]);let eR=e=>ea.length>0?ea.includes(e):"all"===ej||F[ej].includes(e),eM=n.useMemo(()=>{let e=A,s=null==l?void 0:l.find(e=>"labels"===(e.property||"").toLowerCase());return s&&s.value&&(e=e.filter(e=>(0,M.mu)(e,s))),e},[A,l]),eF=n.useMemo(()=>U.key?[...eM].sort((e,s)=>e[U.key]<s[U.key]?"ascending"===U.direction?-1:1:e[U.key]>s[U.key]?"ascending"===U.direction?1:-1:0):eM,[eM,U]),eA=($-1)*X,eI=P>0?Math.ceil(P/X):0,eP=P>0?Math.min(eA+eF.length,P):0,eZ=e=>{if(ea.includes(e)){let s=ea.filter(s=>s!==e);0===s.length?(eg(!0),en([])):(en(s),eg(!1))}else en([...ea,e]),eg(!1);Y(1)};return(0,n.useEffect)(()=>{el(ei)},[ei]),(0,a.jsxs)("div",{className:"relative",children:[(0,a.jsx)("div",{className:"flex flex-col space-y-1 mb-1",children:(0,a.jsxs)("div",{className:"flex flex-wrap items-center justify-between text-sm mb-1",children:[(0,a.jsxs)("div",{className:"flex flex-wrap items-center",children:[(0,a.jsx)("span",{className:"mr-2 text-sm font-medium",children:"Statuses:"}),(0,a.jsxs)("div",{className:"flex flex-wrap gap-2 items-center",children:[!B&&0===z&&!K&&(0,a.jsx)("span",{className:"text-gray-500 mr-2",children:"No jobs found"}),Object.entries(er).map(e=>{let[s,t]=e;return(0,a.jsxs)("button",{onClick:()=>eZ(s),className:"px-3 py-0.5 rounded-full flex items-center space-x-2 ".concat(eR(s)||ea.includes(s)?(0,_.Cl)(s):"bg-gray-50 text-gray-600 hover:bg-gray-100"),children:[(0,a.jsx)("span",{children:s}),(0,a.jsx)("span",{className:"text-xs ".concat(eR(s)||ea.includes(s)?"bg-white/50":"bg-gray-200"," px-1.5 py-0.5 rounded"),children:t})]},s)}),z>0&&(0,a.jsxs)("div",{className:"flex items-center ml-2 gap-2",children:[(0,a.jsx)("span",{className:"text-gray-500",children:"("}),(0,a.jsx)("button",{onClick:()=>{n.startTransition(()=>{ep("all"),en([]),eg(!0),Y(1)})},className:"text-sm font-medium ".concat("all"===ej&&ef?"text-purple-700 underline":"text-gray-600 hover:text-purple-700 hover:underline"),children:"show all jobs"}),(0,a.jsx)("span",{className:"text-gray-500 mx-1",children:"|"}),(0,a.jsx)("button",{onClick:()=>{n.startTransition(()=>{ep("active"),en([]),eg(!0),Y(1)})},className:"text-sm font-medium ".concat("active"===ej&&ef?"text-green-700 underline":"text-gray-600 hover:text-green-700 hover:underline"),children:"show all active jobs"}),(0,a.jsx)("span",{className:"text-gray-500 mx-1",children:"|"}),(0,a.jsx)("button",{onClick:()=>{n.startTransition(()=>{ep("finished"),en([]),eg(!0),Y(1)})},className:"text-sm font-medium ".concat("finished"===ej&&ef?"text-blue-700 underline":"text-gray-600 hover:text-blue-700 hover:underline"),children:"show all finished jobs"}),(0,a.jsx)("span",{className:"text-gray-500",children:")"})]})]})]}),(0,a.jsxs)("div",{className:"flex items-center gap-2",children:[B&&(0,a.jsxs)("div",{className:"flex items-center",children:[(0,a.jsx)(c.Z,{size:15,className:"mt-0"}),(0,a.jsx)("span",{className:"ml-2 text-gray-500 text-sm",children:"Loading..."})]}),!B&&D&&(0,a.jsx)(u.$3,{timestamp:D}),(0,a.jsxs)("button",{onClick:()=>{p&&p()},disabled:B,className:"text-sky-blue hover:text-sky-blue-bright flex items-center text-sm",children:[(0,a.jsx)(v.Z,{className:"h-4 w-4 mr-1.5"}),(0,a.jsx)("span",{children:"Refresh"})]})]})]})}),eN&&eo&&0===eF.length&&!B&&!K&&(0,a.jsx)("div",{className:"mb-4 p-4 bg-gray-50 rounded-lg border",children:(0,a.jsxs)("div",{className:"flex flex-col items-center space-y-3",children:[(0,a.jsxs)("p",{className:"text-gray-700 text-center text-sm",children:["Job controller stopped.",(0,a.jsx)("br",{}),"Restart to check status."]}),(0,a.jsx)(o.z,{variant:"outline",size:"sm",onClick:eC,className:"text-sky-blue hover:text-sky-blue-bright",disabled:B||ex,children:ex?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(c.Z,{size:12,className:"mr-2"}),"Restarting..."]}):(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(y,{className:"h-4 w-4 mr-2"}),"Restart"]})})]})}),(0,a.jsx)(d.Zb,{children:(0,a.jsx)("div",{className:"overflow-x-auto rounded-lg",children:(0,a.jsxs)(h.iA,{className:"min-w-full",children:[(0,a.jsx)(h.xD,{children:(0,a.jsxs)(h.SC,{children:[(0,a.jsxs)(h.ss,{className:"sortable whitespace-nowrap",onClick:()=>eE("id"),children:["ID",eD("id")]}),(0,a.jsxs)(h.ss,{className:"sortable whitespace-nowrap",onClick:()=>eE("name"),children:["Name",eD("name")]}),(0,a.jsxs)(h.ss,{className:"sortable whitespace-nowrap",onClick:()=>eE("user"),children:["User",eD("user")]}),ew&&(0,a.jsxs)(h.ss,{className:"sortable whitespace-nowrap",onClick:()=>eE("workspace"),children:["Workspace",eD("workspace")]}),(0,a.jsxs)(h.ss,{className:"sortable whitespace-nowrap",onClick:()=>eE("submitted_at"),children:["Submitted",eD("submitted_at")]}),(0,a.jsxs)(h.ss,{className:"sortable whitespace-nowrap",onClick:()=>eE("job_duration"),children:["Duration",eD("job_duration")]}),(0,a.jsxs)(h.ss,{className:"sortable whitespace-nowrap",onClick:()=>eE("status"),children:["Status",eD("status")]}),(0,a.jsxs)(h.ss,{className:"sortable whitespace-nowrap",onClick:()=>eE("infra"),children:["Infra",eD("infra")]}),(0,a.jsxs)(h.ss,{className:"sortable whitespace-nowrap",onClick:()=>eE("cluster"),children:["Requested Resources",eD("cluster")]}),(0,a.jsxs)(h.ss,{className:"sortable whitespace-nowrap",onClick:()=>eE("recoveries"),children:["Recoveries",eD("recoveries")]}),ek&&(0,a.jsxs)(h.ss,{className:"sortable whitespace-nowrap",onClick:()=>eE("pool"),children:["Pool",eD("pool")]}),(0,a.jsx)(h.ss,{children:"Details"}),(0,a.jsx)(h.ss,{children:"Logs"})]})}),(0,a.jsx)(h.RM,{children:B&&K?(0,a.jsx)(h.SC,{children:(0,a.jsx)(h.pj,{colSpan:11+(ew?1:0)+(ek?1:0),className:"text-center py-6 text-gray-500",children:(0,a.jsxs)("div",{className:"flex justify-center items-center",children:[(0,a.jsx)(c.Z,{size:20,className:"mr-2"}),(0,a.jsx)("span",{children:"Loading..."})]})})}):eF.length>0?(0,a.jsx)(a.Fragment,{children:eF.map(e=>(0,a.jsxs)(n.Fragment,{children:[(0,a.jsxs)(h.SC,{children:[(0,a.jsx)(h.pj,{children:(0,a.jsx)(i(),{href:"/jobs/".concat(e.id),className:"text-blue-600",children:e.id})}),(0,a.jsx)(h.pj,{children:(0,a.jsx)(i(),{href:"/jobs/".concat(e.id),className:"text-blue-600",children:e.name})}),(0,a.jsx)(h.pj,{children:(0,a.jsx)(L.H,{username:e.user,userHash:e.user_hash})}),ew&&(0,a.jsx)(h.pj,{children:(0,a.jsx)(i(),{href:"/workspaces",className:"text-gray-700 hover:text-blue-600 hover:underline",children:e.workspace||"default"})}),(0,a.jsx)(h.pj,{children:O(e.submitted_at)}),(0,a.jsx)(h.pj,{children:(0,u.LU)(e.job_duration)}),(0,a.jsx)(h.pj,{children:(0,a.jsx)(R.j,{name:"jobs.table.status.badge",context:e,fallback:(0,a.jsx)(_.OE,{status:e.status,statusTooltip:e.statusTooltip})})}),(0,a.jsx)(h.pj,{children:e.infra&&"-"!==e.infra?(0,a.jsx)(u.Md,{content:e.full_infra||e.infra,className:"text-sm text-muted-foreground",children:(0,a.jsxs)("span",{children:[(0,a.jsx)(i(),{href:"/infra",className:"text-blue-600 hover:underline",children:e.cloud||e.infra.split("(")[0].trim()}),e.infra.includes("(")&&(0,a.jsx)("span",{children:" "+(()=>{let s=x.MO.NAME_TRUNCATE_LENGTH,t=e.infra.substring(e.infra.indexOf("(")),a=t.substring(1,t.length-1);if(a.length<=s)return t;let n="".concat(a.substring(0,Math.floor((s-3)/2)),"...").concat(a.substring(a.length-Math.ceil((s-3)/2)));return"(".concat(n,")")})()})]})}):(0,a.jsx)("span",{children:e.infra||"-"})}),(0,a.jsx)(h.pj,{children:(0,a.jsx)(u.Md,{content:e.requested_resources||e.resources_str_full||e.resources_str||"-",className:"text-sm text-muted-foreground",children:(0,a.jsx)("span",{children:e.requested_resources||e.resources_str||"-"})})}),(0,a.jsx)(h.pj,{children:e.recoveries}),ek&&(0,a.jsx)(h.pj,{children:(0,a.jsx)("div",{className:N?"blur-sm transition-all duration-300":"",children:N?"-":(0,u.os)(e.pool,e.pool_hash,b)})}),(0,a.jsx)(h.pj,{children:e.details?(0,a.jsx)(q,{text:e.details,rowId:e.id,expandedRowId:ee,setExpandedRowId:es}):"-"}),(0,a.jsx)(h.pj,{children:(0,a.jsx)(W,{jobParent:"/jobs",jobId:e.id,managed:!0,workspace:e.workspace})})]}),ee===e.id&&(0,a.jsx)(J,{text:e.details,colSpan:11+(ew?1:0)+(ek?1:0),innerRef:et})]},e.task_job_id))}):(0,a.jsx)(h.SC,{children:(0,a.jsx)(h.pj,{colSpan:11+(ew?1:0)+(ek?1:0),className:"text-center py-6",children:(0,a.jsxs)("div",{className:"flex flex-col items-center space-y-4",children:[eh&&(0,a.jsxs)("div",{className:"flex flex-col items-center space-y-2",children:[(0,a.jsx)("p",{className:"text-gray-700",children:"The managed job controller is launching. It will be ready shortly."}),(0,a.jsxs)("div",{className:"flex items-center",children:[(0,a.jsx)(c.Z,{size:12,className:"mr-2"}),(0,a.jsx)("span",{className:"text-gray-500",children:"Launching..."})]})]}),!eo&&!eh&&(0,a.jsx)("p",{className:"text-gray-500",children:"No active jobs"}),!eN&&eo&&(0,a.jsxs)("div",{className:"flex flex-col items-center space-y-3 px-4",children:[(0,a.jsx)("p",{className:"text-gray-700 text-center text-sm sm:text-base max-w-md",children:"The managed job controller has been stopped. Restart to check the latest job status."}),(0,a.jsx)(o.z,{variant:"outline",size:"sm",onClick:eC,className:"text-sky-blue hover:text-sky-blue-bright",disabled:B||ex,children:ex?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(c.Z,{size:12,className:"mr-2"}),"Restarting..."]}):(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(y,{className:"h-4 w-4 mr-2"}),"Restart Controller"]})})]})]})})})})]})})}),(0,a.jsx)("div",{className:"flex justify-end items-center py-2 px-4 text-sm text-gray-700",children:(0,a.jsxs)("div",{className:"flex items-center space-x-4",children:[(0,a.jsxs)("div",{className:"flex items-center",children:[(0,a.jsx)("span",{className:"mr-2",children:"Rows per page:"}),(0,a.jsxs)("div",{className:"relative inline-block",children:[(0,a.jsxs)("select",{value:X,onChange:e=>{Q(parseInt(e.target.value,10)),Y(1)},className:"py-1 pl-2 pr-6 appearance-none outline-none cursor-pointer border-none bg-transparent",style:{minWidth:"40px"},children:[(0,a.jsx)("option",{value:10,children:"10"}),(0,a.jsx)("option",{value:30,children:"30"}),(0,a.jsx)("option",{value:50,children:"50"}),(0,a.jsx)("option",{value:100,children:"100"}),(0,a.jsx)("option",{value:200,children:"200"})]}),(0,a.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-4 w-4 text-gray-500 absolute right-0 top-1/2 transform -translate-y-1/2 pointer-events-none",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:(0,a.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"})})]})]}),(0,a.jsx)("div",{children:P>0?"".concat(eA+1," – ").concat(eP," of ").concat(P):"0 – 0 of 0"}),(0,a.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,a.jsx)(o.z,{variant:"ghost",size:"icon",onClick:()=>{Y(e=>Math.max(e-1,1))},disabled:1===$||!eF||0===eF.length,className:"text-gray-500 h-8 w-8 p-0",children:(0,a.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:"chevron-left",children:(0,a.jsx)("path",{d:"M15 18l-6-6 6-6"})})}),(0,a.jsx)(o.z,{variant:"ghost",size:"icon",onClick:()=>{eI>0&&$<eI&&Y(e=>e+1)},disabled:0===eI||$>=eI||!eF||0===eF.length,className:"text-gray-500 h-8 w-8 p-0",children:(0,a.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:"chevron-right",children:(0,a.jsx)("path",{d:"M9 18l6-6-6-6"})})})]})]})}),(0,a.jsx)(C.cV,{isOpen:eb.isOpen,onClose:()=>ev({...eb,isOpen:!1}),onConfirm:eb.onConfirm,title:eb.title,message:eb.message,confirmClassName:"bg-blue-600 hover:bg-blue-700 text-white"})]})}function W(e){let{withLabel:s=!1,jobParent:t,jobId:n,managed:l,workspace:i="default"}=e,c=(0,r.useRouter)(),o=(e,s)=>{e.preventDefault(),e.stopPropagation(),c.push({pathname:"".concat(t,"/").concat(n),query:{tab:s}})},d=function(e){let s=arguments.length>1&&void 0!==arguments[1]&&arguments[1];if(e.preventDefault(),e.stopPropagation(),l)(0,m.jh)({jobId:parseInt(n),controller:s});else{let e=t.match(/\/clusters\/(.+)/);if(e){let s=e[1];(0,g.GH)({clusterName:s,jobIds:[n],workspace:i})}}};return(0,a.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,a.jsx)(u.WH,{content:"View Job Logs",className:"capitalize text-sm text-muted-foreground",children:(0,a.jsxs)("button",{onClick:e=>o(e,"logs"),className:"text-sky-blue hover:text-sky-blue-bright font-medium inline-flex items-center h-8",children:[(0,a.jsx)(w,{className:"w-4 h-4"}),s&&(0,a.jsx)("span",{className:"ml-1.5",children:"Logs"})]})},"logs"),(0,a.jsx)(u.WH,{content:"Download Job Logs",className:"capitalize text-sm text-muted-foreground",children:(0,a.jsxs)("button",{onClick:e=>d(e,!1),className:"text-sky-blue hover:text-sky-blue-bright font-medium inline-flex items-center h-8",children:[(0,a.jsx)(k.Z,{className:"w-4 h-4"}),s&&(0,a.jsx)("span",{className:"ml-1.5",children:"Download"})]})},"downloadlogs")]})}function H(e){let{clusterName:s,clusterJobData:t,loading:r,refreshClusterJobsOnly:l,userFilter:x=null,nameFilter:m=null,workspace:j="default"}=e,[p,f]=(0,n.useState)(null),[g,b]=(0,n.useState)({key:null,direction:"ascending"}),[N,y]=(0,n.useState)(1),[w,k]=(0,n.useState)(10),C=(0,n.useRef)(null),[S,E]=(0,n.useState)(null);(0,n.useEffect)(()=>{let e=e=>{p&&C.current&&!C.current.contains(e.target)&&f(null)};return document.addEventListener("mousedown",e),()=>{document.removeEventListener("mousedown",e)}},[p]);let D=n.useMemo(()=>{let e=t||[];return x&&"ALL_USERS"!==x&&(e=Z(e,x)),m&&(e=I(e,m)),e},[t,x,m]);(0,n.useEffect)(()=>{JSON.stringify(t)!==JSON.stringify(S)&&E(t)},[t,S]);let R=n.useMemo(()=>g.key?[...D].sort((e,s)=>e[g.key]<s[g.key]?"ascending"===g.direction?-1:1:e[g.key]>s[g.key]?"ascending"===g.direction?1:-1:0):D,[D,g]),M=e=>{let s="ascending";g.key===e&&"ascending"===g.direction&&(s="descending"),b({key:e,direction:s})},F=e=>g.key===e?"ascending"===g.direction?" ↑":" ↓":"",A=Math.ceil(R.length/w),P=(N-1)*w,z=P+w,T=R.slice(P,z);return(0,a.jsxs)("div",{className:"relative",children:[(0,a.jsxs)(d.Zb,{children:[(0,a.jsxs)("div",{className:"flex items-center justify-between p-4",children:[(0,a.jsx)("h3",{className:"text-lg font-semibold",children:"Cluster Jobs"}),(0,a.jsx)("div",{className:"flex items-center",children:l&&(0,a.jsxs)("button",{onClick:l,disabled:r,className:"text-sky-blue hover:text-sky-blue-bright font-medium inline-flex items-center text-sm ml-2",children:[(0,a.jsx)(v.Z,{className:"w-4 h-4 mr-1"}),"Refresh Jobs"]})})]}),(0,a.jsxs)(h.iA,{children:[(0,a.jsx)(h.xD,{children:(0,a.jsxs)(h.SC,{children:[(0,a.jsxs)(h.ss,{className:"sortable whitespace-nowrap",onClick:()=>M("id"),children:["ID",F("id")]}),(0,a.jsxs)(h.ss,{className:"sortable whitespace-nowrap",onClick:()=>M("job"),children:["Name",F("job")]}),(0,a.jsxs)(h.ss,{className:"sortable whitespace-nowrap",onClick:()=>M("user"),children:["User",F("user")]}),(0,a.jsxs)(h.ss,{className:"sortable whitespace-nowrap",onClick:()=>M("submitted_at"),children:["Submitted",F("submitted_at")]}),(0,a.jsxs)(h.ss,{className:"sortable whitespace-nowrap",onClick:()=>M("job_duration"),children:["Duration",F("job_duration")]}),(0,a.jsxs)(h.ss,{className:"sortable whitespace-nowrap",onClick:()=>M("status"),children:["Status",F("status")]}),(0,a.jsxs)(h.ss,{className:"sortable whitespace-nowrap",onClick:()=>M("resources"),children:["Resources",F("resources")]}),(0,a.jsx)(h.ss,{className:"whitespace-nowrap",children:"Logs"})]})}),(0,a.jsx)(h.RM,{children:r?(0,a.jsx)(h.SC,{children:(0,a.jsx)(h.pj,{colSpan:8,className:"text-center py-12 text-gray-500",children:(0,a.jsxs)("div",{className:"flex justify-center items-center",children:[(0,a.jsx)(c.Z,{size:24,className:"mr-2"}),(0,a.jsx)("span",{children:"Loading cluster jobs..."})]})})}):T.length>0?T.map(e=>(0,a.jsxs)(n.Fragment,{children:[(0,a.jsxs)(h.SC,{className:p===e.id?"selected-row":"",children:[(0,a.jsx)(h.pj,{children:(0,a.jsx)(i(),{href:"/clusters/".concat(s,"/").concat(e.id),className:"text-blue-600",children:e.id})}),(0,a.jsx)(h.pj,{children:(0,a.jsx)(i(),{href:"/clusters/".concat(s,"/").concat(e.id),className:"text-blue-600",children:(0,a.jsx)(q,{text:e.job||"Unnamed job",rowId:e.id,expandedRowId:p,setExpandedRowId:f})})}),(0,a.jsx)(h.pj,{children:(0,a.jsx)(L.H,{username:e.user,userHash:e.user_hash})}),(0,a.jsx)(h.pj,{children:O(e.submitted_at)}),(0,a.jsx)(h.pj,{children:(0,u.LU)(e.job_duration)}),(0,a.jsx)(h.pj,{children:(0,a.jsx)(_.OE,{status:e.status})}),(0,a.jsx)(h.pj,{children:e.resources}),(0,a.jsx)(h.pj,{className:"flex content-center items-center",children:(0,a.jsx)(W,{jobParent:"/clusters/".concat(s),jobId:e.id,managed:!1,workspace:j})})]}),p===e.id&&(0,a.jsx)(J,{text:e.job||"Unnamed job",colSpan:8,innerRef:C})]},e.id)):(0,a.jsx)(h.SC,{children:(0,a.jsx)(h.pj,{colSpan:8,className:"text-center py-6 text-gray-500",children:"No jobs found"})})})]})]}),R&&R.length>0&&(0,a.jsx)("div",{className:"flex justify-end items-center py-2 px-4 text-sm text-gray-700",children:(0,a.jsxs)("div",{className:"flex items-center space-x-4",children:[(0,a.jsxs)("div",{className:"flex items-center",children:[(0,a.jsx)("span",{className:"mr-2",children:"Rows per page:"}),(0,a.jsxs)("div",{className:"relative inline-block",children:[(0,a.jsxs)("select",{value:w,onChange:e=>{k(parseInt(e.target.value,10)),y(1)},className:"py-1 pl-2 pr-6 appearance-none outline-none cursor-pointer border-none bg-transparent",style:{minWidth:"40px"},children:[(0,a.jsx)("option",{value:5,children:"5"}),(0,a.jsx)("option",{value:10,children:"10"}),(0,a.jsx)("option",{value:20,children:"20"}),(0,a.jsx)("option",{value:50,children:"50"})]}),(0,a.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-4 w-4 text-gray-500 absolute right-0 top-1/2 transform -translate-y-1/2 pointer-events-none",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:(0,a.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"})})]})]}),(0,a.jsxs)("div",{children:[P+1," – ",Math.min(z,R.length)," of"," ",R.length]}),(0,a.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,a.jsx)(o.z,{variant:"ghost",size:"icon",onClick:()=>{y(e=>Math.max(e-1,1))},disabled:1===N,className:"text-gray-500 h-8 w-8 p-0",children:(0,a.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:"chevron-left",children:(0,a.jsx)("path",{d:"M15 18l-6-6 6-6"})})}),(0,a.jsx)(o.z,{variant:"ghost",size:"icon",onClick:()=>{y(e=>Math.min(e+1,A))},disabled:N===A||0===A,className:"text-gray-500 h-8 w-8 p-0",children:(0,a.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:"chevron-right",children:(0,a.jsx)("path",{d:"M9 18l6-6-6-6"})})})]})]})})]})}function J(e){let{text:s,colSpan:t,innerRef:n}=e;return(0,a.jsx)(h.SC,{className:"expanded-details",children:(0,a.jsx)(h.pj,{colSpan:t,children:(0,a.jsx)("div",{className:"p-4 bg-gray-50 rounded-md border border-gray-200",ref:n,children:(0,a.jsx)("div",{className:"flex justify-between items-start",children:(0,a.jsxs)("div",{className:"flex-1",children:[(0,a.jsx)("p",{className:"text-sm font-medium text-gray-900",children:"Full Details"}),(0,a.jsx)("p",{className:"mt-1 text-sm text-gray-700",style:{whiteSpace:"pre-wrap"},children:s})]})})})})})}function q(e){let{text:s,rowId:t,expandedRowId:r,setExpandedRowId:l}=e,i=s||"",c=i.length>50,o=r===t,d=c?"".concat(i.substring(0,50)):i,h=(0,n.useRef)(null);return(0,a.jsxs)("div",{className:"truncated-details relative max-w-full flex items-center",children:[(0,a.jsx)("span",{className:"truncate",children:d}),c&&(0,a.jsx)("button",{ref:h,type:"button",onClick:e=>{e.preventDefault(),e.stopPropagation(),l(o?null:t)},className:"text-blue-600 hover:text-blue-800 font-medium ml-1 flex-shrink-0","data-button-type":"show-more-less",children:o?"... show less":"... show more"})]})}function B(e){let{refreshInterval:s,setLoading:t,refreshDataRef:r}=e,[l,o]=(0,n.useState)([]),[x,p]=(0,n.useState)({key:null,direction:"ascending"}),[f,g]=(0,n.useState)(!1),[b,v]=(0,n.useState)(!0),[N,y]=(0,n.useState)(1),[w,k]=(0,n.useState)(10),C=n.useCallback(async()=>{g(!0),t(!0);try{let{pools:e=[]}=await j.ZP.get(m.vs,[{}])||{};o(e),v(!1)}catch(e){console.error("Error fetching pools data:",e),o([]),v(!1)}finally{g(!1),t(!1)}},[t]);n.useEffect(()=>{r&&(r.current=C)},[r,C]),(0,n.useEffect)(()=>{o([]);let e=!0;C();let t=setInterval(()=>{e&&"visible"===window.document.visibilityState&&C()},s);return()=>{e=!1,clearInterval(t)}},[s,C]);let S=e=>{let s="ascending";x.key===e&&"ascending"===x.direction&&(s="descending"),p({key:e,direction:s})},L=e=>x.key===e?"ascending"===x.direction?" ↑":" ↓":"",E=n.useMemo(()=>x.key?[...l].sort((e,s)=>e[x.key]<s[x.key]?"ascending"===x.direction?-1:1:e[x.key]>s[x.key]?"ascending"===x.direction?1:-1:0):l,[l,x]),D=Math.ceil(E.length/w),R=(N-1)*w,F=R+w,A=E.slice(R,F),I=e=>{if(!e||!e.replica_info||0===e.replica_info.length)return"0 (target: 0)";let s=e.replica_info.filter(e=>"READY"===e.status).length,t=e.target_num_replicas||0;return"".concat(s," (target: ").concat(t,")")},P=e=>{let{jobCounts:s}=e;return(0,a.jsx)(u.x9,{jobCounts:s,getStatusStyle:_.Cl})},Z=e=>{let{replicaInfo:s}=e;return(0,a.jsx)(u.Kl,{replicaInfo:s})};return(0,a.jsxs)(d.Zb,{children:[(0,a.jsx)("div",{className:"overflow-x-auto rounded-lg",children:(0,a.jsxs)(h.iA,{className:"min-w-full table-fixed",children:[(0,a.jsx)(h.xD,{children:(0,a.jsxs)(h.SC,{children:[(0,a.jsxs)(h.ss,{className:"sortable whitespace-nowrap w-32",onClick:()=>S("name"),children:["Pool",L("name")]}),(0,a.jsxs)(h.ss,{className:"sortable whitespace-nowrap w-40",onClick:()=>S("job_counts"),children:["Jobs",L("job_counts")]}),(0,a.jsx)(h.ss,{className:"whitespace-nowrap w-20",children:"Workers"}),(0,a.jsxs)(h.ss,{className:"sortable whitespace-nowrap w-36",onClick:()=>S("requested_resources_str"),children:["Worker Details",L("requested_resources_str")]}),(0,a.jsxs)(h.ss,{className:"sortable whitespace-nowrap w-40",onClick:()=>S("requested_resources_str"),children:["Worker Resources",L("requested_resources_str")]})]})}),(0,a.jsx)(h.RM,{children:f&&b?(0,a.jsx)(h.SC,{children:(0,a.jsx)(h.pj,{colSpan:5,className:"text-center py-6 text-gray-500",children:(0,a.jsxs)("div",{className:"flex justify-center items-center",children:[(0,a.jsx)(c.Z,{size:20,className:"mr-2"}),(0,a.jsx)("span",{children:"Loading..."})]})})}):A.length>0?A.map(e=>(0,a.jsxs)(h.SC,{children:[(0,a.jsx)(h.pj,{children:(0,a.jsx)(i(),{href:"/jobs/pools/".concat(e.name),className:"text-blue-600 hover:text-blue-800",children:e.name})}),(0,a.jsx)(h.pj,{children:(0,a.jsxs)("div",{className:"flex items-center gap-2 flex-wrap",children:[(0,a.jsx)(P,{jobCounts:e.jobCounts}),(0,a.jsx)(i(),{href:(0,M.P2)("/jobs","pool",":",e.name),className:"text-blue-600 hover:text-blue-800 text-xs",children:"See all jobs"})]})}),(0,a.jsx)(h.pj,{children:I(e)}),(0,a.jsx)(h.pj,{children:(0,a.jsx)(Z,{replicaInfo:e.replica_info})}),(0,a.jsx)(h.pj,{children:e.requested_resources_str||"-"})]},e.name)):(0,a.jsx)(h.SC,{children:(0,a.jsx)(h.pj,{colSpan:5,className:"text-center py-6 text-gray-500",children:"No pools found"})})})]})}),A.length>0&&D>1&&(0,a.jsxs)("div",{className:"flex items-center justify-between px-4 py-3 border-t border-gray-200",children:[(0,a.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,a.jsx)("span",{className:"text-sm text-gray-700",children:"Rows per page:"}),(0,a.jsxs)("select",{value:w,onChange:e=>{k(parseInt(e.target.value,10)),y(1)},className:"border border-gray-300 rounded px-2 py-1 text-sm",children:[(0,a.jsx)("option",{value:5,children:"5"}),(0,a.jsx)("option",{value:10,children:"10"}),(0,a.jsx)("option",{value:25,children:"25"}),(0,a.jsx)("option",{value:50,children:"50"})]})]}),(0,a.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,a.jsxs)("span",{className:"text-sm text-gray-700",children:[R+1,"-",Math.min(F,E.length)," of"," ",E.length]}),(0,a.jsx)("button",{onClick:()=>{y(e=>Math.max(e-1,1))},disabled:1===N,className:"px-2 py-1 text-sm border border-gray-300 rounded disabled:opacity-50 disabled:cursor-not-allowed hover:bg-gray-50",children:"Previous"}),(0,a.jsx)("button",{onClick:()=>{y(e=>Math.min(e+1,D))},disabled:N===D,className:"px-2 py-1 text-sm border border-gray-300 rounded disabled:opacity-50 disabled:cursor-not-allowed hover:bg-gray-50",children:"Next"})]})]})]})}},55988:function(e,s,t){t.d(s,{j:function(){return r}});var a=t(85893);t(67294);var n=t(23800);function r(e){let{name:s,context:t={},fallback:r=null,wrapperClassName:l=""}=e,i=(0,n.dL)(s);return 0===i.length?r:(0,a.jsx)("div",{className:l||void 0,children:i.map(e=>{let s=e.component;return(0,a.jsx)(s,{...t},e.id)})})}}}]);