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.
- sky/__init__.py +6 -2
- sky/adaptors/aws.py +1 -61
- sky/adaptors/slurm.py +565 -0
- sky/backends/backend_utils.py +95 -12
- sky/backends/cloud_vm_ray_backend.py +224 -65
- sky/backends/task_codegen.py +380 -4
- sky/catalog/__init__.py +0 -3
- sky/catalog/data_fetchers/fetch_gcp.py +9 -1
- sky/catalog/data_fetchers/fetch_nebius.py +1 -1
- sky/catalog/data_fetchers/fetch_vast.py +4 -2
- sky/catalog/kubernetes_catalog.py +12 -4
- sky/catalog/seeweb_catalog.py +30 -15
- sky/catalog/shadeform_catalog.py +5 -2
- sky/catalog/slurm_catalog.py +236 -0
- sky/catalog/vast_catalog.py +30 -6
- sky/check.py +25 -11
- sky/client/cli/command.py +391 -32
- sky/client/interactive_utils.py +190 -0
- sky/client/sdk.py +64 -2
- sky/client/sdk_async.py +9 -0
- sky/clouds/__init__.py +2 -0
- sky/clouds/aws.py +60 -2
- sky/clouds/azure.py +2 -0
- sky/clouds/cloud.py +7 -0
- sky/clouds/kubernetes.py +2 -0
- sky/clouds/runpod.py +38 -7
- sky/clouds/slurm.py +610 -0
- sky/clouds/ssh.py +3 -2
- sky/clouds/vast.py +39 -16
- sky/core.py +197 -37
- sky/dashboard/out/404.html +1 -1
- sky/dashboard/out/_next/static/3nu-b8raeKRNABZ2d4GAG/_buildManifest.js +1 -0
- sky/dashboard/out/_next/static/chunks/1871-0565f8975a7dcd10.js +6 -0
- sky/dashboard/out/_next/static/chunks/2109-55a1546d793574a7.js +11 -0
- sky/dashboard/out/_next/static/chunks/2521-099b07cd9e4745bf.js +26 -0
- sky/dashboard/out/_next/static/chunks/2755.a636e04a928a700e.js +31 -0
- sky/dashboard/out/_next/static/chunks/3495.05eab4862217c1a5.js +6 -0
- sky/dashboard/out/_next/static/chunks/3785.cfc5dcc9434fd98c.js +1 -0
- sky/dashboard/out/_next/static/chunks/3850-fd5696f3bbbaddae.js +1 -0
- sky/dashboard/out/_next/static/chunks/3981.645d01bf9c8cad0c.js +21 -0
- sky/dashboard/out/_next/static/chunks/4083-0115d67c1fb57d6c.js +21 -0
- sky/dashboard/out/_next/static/chunks/{8640.5b9475a2d18c5416.js → 429.a58e9ba9742309ed.js} +2 -2
- sky/dashboard/out/_next/static/chunks/4555.8e221537181b5dc1.js +6 -0
- sky/dashboard/out/_next/static/chunks/4725.937865b81fdaaebb.js +6 -0
- sky/dashboard/out/_next/static/chunks/6082-edabd8f6092300ce.js +25 -0
- sky/dashboard/out/_next/static/chunks/6989-49cb7dca83a7a62d.js +1 -0
- sky/dashboard/out/_next/static/chunks/6990-630bd2a2257275f8.js +1 -0
- sky/dashboard/out/_next/static/chunks/7248-a99800d4db8edabd.js +1 -0
- sky/dashboard/out/_next/static/chunks/754-cfc5d4ad1b843d29.js +18 -0
- sky/dashboard/out/_next/static/chunks/8050-dd8aa107b17dce00.js +16 -0
- sky/dashboard/out/_next/static/chunks/8056-d4ae1e0cb81e7368.js +1 -0
- sky/dashboard/out/_next/static/chunks/8555.011023e296c127b3.js +6 -0
- sky/dashboard/out/_next/static/chunks/8821-93c25df904a8362b.js +1 -0
- sky/dashboard/out/_next/static/chunks/8969-0662594b69432ade.js +1 -0
- sky/dashboard/out/_next/static/chunks/9025.f15c91c97d124a5f.js +6 -0
- sky/dashboard/out/_next/static/chunks/9353-7ad6bd01858556f1.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/_app-5a86569acad99764.js +34 -0
- sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]/[job]-8297476714acb4ac.js +6 -0
- sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]-337c3ba1085f1210.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/{clusters-ee39056f9851a3ff.js → clusters-57632ff3684a8b5c.js} +1 -1
- sky/dashboard/out/_next/static/chunks/pages/{config-dfb9bf07b13045f4.js → config-718cdc365de82689.js} +1 -1
- sky/dashboard/out/_next/static/chunks/pages/infra/[context]-5fd3a453c079c2ea.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/infra-9f85c02c9c6cae9e.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/jobs/[job]-90f16972cbecf354.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/jobs/pools/[pool]-2dd42fc37aad427a.js +16 -0
- sky/dashboard/out/_next/static/chunks/pages/jobs-ed806aeace26b972.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/plugins/[...slug]-449a9f5a3bb20fb3.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/users-bec34706b36f3524.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/{volumes-b84b948ff357c43e.js → volumes-a83ba9b38dff7ea9.js} +1 -1
- sky/dashboard/out/_next/static/chunks/pages/workspaces/{[name]-84a40f8c7c627fe4.js → [name]-c781e9c3e52ef9fc.js} +1 -1
- sky/dashboard/out/_next/static/chunks/pages/workspaces-91e0942f47310aae.js +1 -0
- sky/dashboard/out/_next/static/chunks/webpack-cfe59cf684ee13b9.js +1 -0
- sky/dashboard/out/_next/static/css/b0dbca28f027cc19.css +3 -0
- sky/dashboard/out/clusters/[cluster]/[job].html +1 -1
- sky/dashboard/out/clusters/[cluster].html +1 -1
- sky/dashboard/out/clusters.html +1 -1
- sky/dashboard/out/config.html +1 -1
- sky/dashboard/out/index.html +1 -1
- sky/dashboard/out/infra/[context].html +1 -1
- sky/dashboard/out/infra.html +1 -1
- sky/dashboard/out/jobs/[job].html +1 -1
- sky/dashboard/out/jobs/pools/[pool].html +1 -1
- sky/dashboard/out/jobs.html +1 -1
- sky/dashboard/out/plugins/[...slug].html +1 -0
- sky/dashboard/out/users.html +1 -1
- sky/dashboard/out/volumes.html +1 -1
- sky/dashboard/out/workspace/new.html +1 -1
- sky/dashboard/out/workspaces/[name].html +1 -1
- sky/dashboard/out/workspaces.html +1 -1
- sky/data/data_utils.py +26 -12
- sky/data/mounting_utils.py +44 -5
- sky/global_user_state.py +111 -19
- sky/jobs/client/sdk.py +8 -3
- sky/jobs/controller.py +191 -31
- sky/jobs/recovery_strategy.py +109 -11
- sky/jobs/server/core.py +81 -4
- sky/jobs/server/server.py +14 -0
- sky/jobs/state.py +417 -19
- sky/jobs/utils.py +73 -80
- sky/models.py +11 -0
- sky/optimizer.py +8 -6
- sky/provision/__init__.py +12 -9
- sky/provision/common.py +20 -0
- sky/provision/docker_utils.py +15 -2
- sky/provision/kubernetes/utils.py +163 -20
- sky/provision/kubernetes/volume.py +52 -17
- sky/provision/provisioner.py +17 -7
- sky/provision/runpod/instance.py +3 -1
- sky/provision/runpod/utils.py +13 -1
- sky/provision/runpod/volume.py +25 -9
- sky/provision/slurm/__init__.py +12 -0
- sky/provision/slurm/config.py +13 -0
- sky/provision/slurm/instance.py +618 -0
- sky/provision/slurm/utils.py +689 -0
- sky/provision/vast/instance.py +4 -1
- sky/provision/vast/utils.py +11 -6
- sky/resources.py +135 -13
- sky/schemas/api/responses.py +4 -0
- sky/schemas/db/global_user_state/010_save_ssh_key.py +1 -1
- sky/schemas/db/spot_jobs/008_add_full_resources.py +34 -0
- sky/schemas/db/spot_jobs/009_job_events.py +32 -0
- sky/schemas/db/spot_jobs/010_job_events_timestamp_with_timezone.py +43 -0
- sky/schemas/db/spot_jobs/011_add_links.py +34 -0
- sky/schemas/generated/jobsv1_pb2.py +9 -5
- sky/schemas/generated/jobsv1_pb2.pyi +12 -0
- sky/schemas/generated/jobsv1_pb2_grpc.py +44 -0
- sky/schemas/generated/managed_jobsv1_pb2.py +32 -28
- sky/schemas/generated/managed_jobsv1_pb2.pyi +11 -2
- sky/serve/serve_utils.py +232 -40
- sky/serve/server/impl.py +1 -1
- sky/server/common.py +17 -0
- sky/server/constants.py +1 -1
- sky/server/metrics.py +6 -3
- sky/server/plugins.py +238 -0
- sky/server/requests/executor.py +5 -2
- sky/server/requests/payloads.py +30 -1
- sky/server/requests/request_names.py +4 -0
- sky/server/requests/requests.py +33 -11
- sky/server/requests/serializers/encoders.py +22 -0
- sky/server/requests/serializers/return_value_serializers.py +70 -0
- sky/server/server.py +506 -109
- sky/server/server_utils.py +30 -0
- sky/server/uvicorn.py +5 -0
- sky/setup_files/MANIFEST.in +1 -0
- sky/setup_files/dependencies.py +22 -9
- sky/sky_logging.py +2 -1
- sky/skylet/attempt_skylet.py +13 -3
- sky/skylet/constants.py +55 -13
- sky/skylet/events.py +10 -4
- sky/skylet/executor/__init__.py +1 -0
- sky/skylet/executor/slurm.py +187 -0
- sky/skylet/job_lib.py +91 -5
- sky/skylet/log_lib.py +22 -6
- sky/skylet/log_lib.pyi +8 -6
- sky/skylet/services.py +18 -3
- sky/skylet/skylet.py +5 -1
- sky/skylet/subprocess_daemon.py +2 -1
- sky/ssh_node_pools/constants.py +12 -0
- sky/ssh_node_pools/core.py +40 -3
- sky/ssh_node_pools/deploy/__init__.py +4 -0
- sky/{utils/kubernetes/deploy_ssh_node_pools.py → ssh_node_pools/deploy/deploy.py} +279 -504
- sky/ssh_node_pools/deploy/tunnel/ssh-tunnel.sh +379 -0
- sky/ssh_node_pools/deploy/tunnel_utils.py +199 -0
- sky/ssh_node_pools/deploy/utils.py +173 -0
- sky/ssh_node_pools/server.py +11 -13
- sky/{utils/kubernetes/ssh_utils.py → ssh_node_pools/utils.py} +9 -6
- sky/templates/kubernetes-ray.yml.j2 +12 -6
- sky/templates/slurm-ray.yml.j2 +115 -0
- sky/templates/vast-ray.yml.j2 +1 -0
- sky/templates/websocket_proxy.py +18 -41
- sky/users/model.conf +1 -1
- sky/users/permission.py +85 -52
- sky/users/rbac.py +31 -3
- sky/utils/annotations.py +108 -8
- sky/utils/auth_utils.py +42 -0
- sky/utils/cli_utils/status_utils.py +19 -5
- sky/utils/cluster_utils.py +10 -3
- sky/utils/command_runner.py +389 -35
- sky/utils/command_runner.pyi +43 -4
- sky/utils/common_utils.py +47 -31
- sky/utils/context.py +32 -0
- sky/utils/db/db_utils.py +36 -6
- sky/utils/db/migration_utils.py +41 -21
- sky/utils/infra_utils.py +5 -1
- sky/utils/instance_links.py +139 -0
- sky/utils/interactive_utils.py +49 -0
- sky/utils/kubernetes/generate_kubeconfig.sh +42 -33
- sky/utils/kubernetes/kubernetes_deploy_utils.py +2 -94
- sky/utils/kubernetes/rsync_helper.sh +5 -1
- sky/utils/kubernetes/ssh-tunnel.sh +7 -376
- sky/utils/plugin_extensions/__init__.py +14 -0
- sky/utils/plugin_extensions/external_failure_source.py +176 -0
- sky/utils/resources_utils.py +10 -8
- sky/utils/rich_utils.py +9 -11
- sky/utils/schemas.py +93 -19
- sky/utils/status_lib.py +7 -0
- sky/utils/subprocess_utils.py +17 -0
- sky/volumes/client/sdk.py +6 -3
- sky/volumes/server/core.py +65 -27
- sky_templates/ray/start_cluster +8 -4
- {skypilot_nightly-1.0.0.dev20251203.dist-info → skypilot_nightly-1.0.0.dev20260112.dist-info}/METADATA +67 -59
- {skypilot_nightly-1.0.0.dev20251203.dist-info → skypilot_nightly-1.0.0.dev20260112.dist-info}/RECORD +208 -180
- sky/dashboard/out/_next/static/96_E2yl3QAiIJGOYCkSpB/_buildManifest.js +0 -1
- sky/dashboard/out/_next/static/chunks/1141-e6aa9ab418717c59.js +0 -11
- sky/dashboard/out/_next/static/chunks/1871-7e202677c42f43fe.js +0 -6
- sky/dashboard/out/_next/static/chunks/2260-7703229c33c5ebd5.js +0 -1
- sky/dashboard/out/_next/static/chunks/2350.fab69e61bac57b23.js +0 -1
- sky/dashboard/out/_next/static/chunks/2369.fc20f0c2c8ed9fe7.js +0 -15
- sky/dashboard/out/_next/static/chunks/2755.edd818326d489a1d.js +0 -26
- sky/dashboard/out/_next/static/chunks/3294.20a8540fe697d5ee.js +0 -1
- sky/dashboard/out/_next/static/chunks/3785.7e245f318f9d1121.js +0 -1
- sky/dashboard/out/_next/static/chunks/3800-7b45f9fbb6308557.js +0 -1
- sky/dashboard/out/_next/static/chunks/3850-ff4a9a69d978632b.js +0 -1
- sky/dashboard/out/_next/static/chunks/4725.172ede95d1b21022.js +0 -1
- sky/dashboard/out/_next/static/chunks/4937.a2baa2df5572a276.js +0 -15
- sky/dashboard/out/_next/static/chunks/6212-7bd06f60ba693125.js +0 -13
- sky/dashboard/out/_next/static/chunks/6856-8f27d1c10c98def8.js +0 -1
- sky/dashboard/out/_next/static/chunks/6989-01359c57e018caa4.js +0 -1
- sky/dashboard/out/_next/static/chunks/6990-9146207c4567fdfd.js +0 -1
- sky/dashboard/out/_next/static/chunks/7359-c8d04e06886000b3.js +0 -30
- sky/dashboard/out/_next/static/chunks/7411-b15471acd2cba716.js +0 -41
- sky/dashboard/out/_next/static/chunks/7615-019513abc55b3b47.js +0 -1
- sky/dashboard/out/_next/static/chunks/8969-452f9d5cbdd2dc73.js +0 -1
- sky/dashboard/out/_next/static/chunks/9025.fa408f3242e9028d.js +0 -6
- sky/dashboard/out/_next/static/chunks/9353-cff34f7e773b2e2b.js +0 -1
- sky/dashboard/out/_next/static/chunks/9360.a536cf6b1fa42355.js +0 -31
- sky/dashboard/out/_next/static/chunks/9847.3aaca6bb33455140.js +0 -30
- sky/dashboard/out/_next/static/chunks/pages/_app-bde01e4a2beec258.js +0 -34
- sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]/[job]-792db96d918c98c9.js +0 -16
- sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]-abfcac9c137aa543.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/infra/[context]-c0b5935149902e6f.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/infra-aed0ea19df7cf961.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/jobs/[job]-d66997e2bfc837cf.js +0 -16
- sky/dashboard/out/_next/static/chunks/pages/jobs/pools/[pool]-9faf940b253e3e06.js +0 -21
- sky/dashboard/out/_next/static/chunks/pages/jobs-2072b48b617989c9.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/users-f42674164aa73423.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/workspaces-531b2f8c4bf89f82.js +0 -1
- sky/dashboard/out/_next/static/chunks/webpack-64e05f17bf2cf8ce.js +0 -1
- sky/dashboard/out/_next/static/css/0748ce22df867032.css +0 -3
- /sky/dashboard/out/_next/static/{96_E2yl3QAiIJGOYCkSpB → 3nu-b8raeKRNABZ2d4GAG}/_ssgManifest.js +0 -0
- /sky/{utils/kubernetes → ssh_node_pools/deploy/tunnel}/cleanup-tunnel.sh +0 -0
- {skypilot_nightly-1.0.0.dev20251203.dist-info → skypilot_nightly-1.0.0.dev20260112.dist-info}/WHEEL +0 -0
- {skypilot_nightly-1.0.0.dev20251203.dist-info → skypilot_nightly-1.0.0.dev20260112.dist-info}/entry_points.txt +0 -0
- {skypilot_nightly-1.0.0.dev20251203.dist-info → skypilot_nightly-1.0.0.dev20260112.dist-info}/licenses/LICENSE +0 -0
- {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(
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
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
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
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) =
|
|
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
|
-
|
|
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(
|
|
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
|
|
sky/dashboard/out/404.html
CHANGED
|
@@ -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/
|
|
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)})})}}}]);
|