skypilot-nightly 1.0.0.dev20250715__py3-none-any.whl → 1.0.0.dev20250716__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 +2 -2
- sky/adaptors/nebius.py +6 -0
- sky/catalog/data_fetchers/fetch_nebius.py +308 -0
- sky/clouds/hyperbolic.py +2 -0
- sky/clouds/nebius.py +6 -4
- sky/dashboard/out/404.html +1 -1
- sky/dashboard/out/_next/static/chunks/1141-d8c6404a7c6fffe6.js +11 -0
- sky/dashboard/out/_next/static/chunks/1746.27d40aedc22bd2d6.js +60 -0
- sky/dashboard/out/_next/static/chunks/2641.35edc9ccaeaad9e3.js +1 -0
- sky/dashboard/out/_next/static/chunks/{3785.b3cc2bc1d49d2c3c.js → 3785.95b94f18aaec7233.js} +1 -1
- sky/dashboard/out/_next/static/chunks/4869.c139c0124e677fc8.js +16 -0
- sky/dashboard/out/_next/static/chunks/6990-dcb411b566e64cde.js +1 -0
- sky/dashboard/out/_next/static/chunks/{9025.a7c44babfe56ce09.js → 9025.133e9ba5c780afeb.js} +1 -1
- sky/dashboard/out/_next/static/chunks/9847.46e613d000c55859.js +30 -0
- sky/dashboard/out/_next/static/chunks/pages/{_app-e0f63ea4704026ad.js → _app-771a40cde532309b.js} +1 -1
- sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]/[job]-9096ea50b8e2cf9e.js +6 -0
- sky/dashboard/out/_next/static/chunks/pages/jobs/[job]-14d404b7dd28502a.js +16 -0
- sky/dashboard/out/_next/static/chunks/pages/{users-cd43fb3c122eedde.js → users-19e98664bdd61643.js} +1 -1
- sky/dashboard/out/_next/static/chunks/pages/volumes-61ea7ba7e56f8d06.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/{workspaces-06bde99155fa6292.js → workspaces-a1e43d9ef51a9cea.js} +1 -1
- sky/dashboard/out/_next/static/chunks/{webpack-4a336bff3bcec29a.js → webpack-3fad5d4a0541a02d.js} +1 -1
- sky/dashboard/out/_next/static/css/219887b94512388c.css +3 -0
- sky/dashboard/out/_next/static/gVXjeFhvtWXyOsx9xYNvM/_buildManifest.js +1 -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.html +1 -1
- 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/execution.py +4 -0
- sky/provision/hyperbolic/__init__.py +1 -0
- sky/provision/hyperbolic/instance.py +10 -0
- sky/setup_files/dependencies.py +1 -1
- sky/utils/tempstore.py +20 -1
- {skypilot_nightly-1.0.0.dev20250715.dist-info → skypilot_nightly-1.0.0.dev20250716.dist-info}/METADATA +3 -3
- {skypilot_nightly-1.0.0.dev20250715.dist-info → skypilot_nightly-1.0.0.dev20250716.dist-info}/RECORD +57 -56
- sky/dashboard/out/_next/static/chunks/1141-726e5a3f00b67185.js +0 -11
- sky/dashboard/out/_next/static/chunks/1691.44e378727a41f3b5.js +0 -21
- sky/dashboard/out/_next/static/chunks/3256.7257acd01b481bed.js +0 -11
- sky/dashboard/out/_next/static/chunks/4697.f5421144224da9fc.js +0 -20
- sky/dashboard/out/_next/static/chunks/6990-d0dc765474fa0eca.js +0 -1
- sky/dashboard/out/_next/static/chunks/8982.a2e214068f30a857.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]/[job]-4608dc89f95eba89.js +0 -6
- sky/dashboard/out/_next/static/chunks/pages/jobs/[job]-980d6f6b64ca7833.js +0 -16
- sky/dashboard/out/_next/static/chunks/pages/volumes-4ebf6484f7216387.js +0 -1
- sky/dashboard/out/_next/static/css/eacc7d65a8686c76.css +0 -3
- sky/dashboard/out/_next/static/y4pSeZ-9XymSDfPlcWhVO/_buildManifest.js +0 -1
- /sky/dashboard/out/_next/static/chunks/{1043-5e5ef6198735ff7e.js → 1043-90a88c46f27b3df5.js} +0 -0
- /sky/dashboard/out/_next/static/chunks/{1871-4d1f786e83bd9ffe.js → 1871-76491ac174a95278.js} +0 -0
- /sky/dashboard/out/_next/static/chunks/{3698-52ad1ca228faa776.js → 3698-9fa11dafb5cad4a6.js} +0 -0
- /sky/dashboard/out/_next/static/chunks/{6601-d38d10f957dff832.js → 6601-d4a381403a8bae91.js} +0 -0
- /sky/dashboard/out/_next/static/chunks/{8969-13bb52ce3cffa4e3.js → 8969-743abf4bc86baf48.js} +0 -0
- /sky/dashboard/out/_next/static/chunks/{938-8e25c8ea0baa271a.js → 938-6a9ffdaa21eee969.js} +0 -0
- /sky/dashboard/out/_next/static/chunks/{9470-21d059a1dfa03f61.js → 9470-b6f6a35283863a6f.js} +0 -0
- /sky/dashboard/out/_next/static/chunks/pages/clusters/{[cluster]-0fbfb1dd0b08c90c.js → [cluster]-0c37ee1ac5f3474d.js} +0 -0
- /sky/dashboard/out/_next/static/{y4pSeZ-9XymSDfPlcWhVO → gVXjeFhvtWXyOsx9xYNvM}/_ssgManifest.js +0 -0
- {skypilot_nightly-1.0.0.dev20250715.dist-info → skypilot_nightly-1.0.0.dev20250716.dist-info}/WHEEL +0 -0
- {skypilot_nightly-1.0.0.dev20250715.dist-info → skypilot_nightly-1.0.0.dev20250716.dist-info}/entry_points.txt +0 -0
- {skypilot_nightly-1.0.0.dev20250715.dist-info → skypilot_nightly-1.0.0.dev20250716.dist-info}/licenses/LICENSE +0 -0
- {skypilot_nightly-1.0.0.dev20250715.dist-info → skypilot_nightly-1.0.0.dev20250716.dist-info}/top_level.txt +0 -0
sky/__init__.py
CHANGED
@@ -5,7 +5,7 @@ from typing import Optional
|
|
5
5
|
import urllib.request
|
6
6
|
|
7
7
|
# Replaced with the current commit when building the wheels.
|
8
|
-
_SKYPILOT_COMMIT_SHA = '
|
8
|
+
_SKYPILOT_COMMIT_SHA = '41c25f4073c1d5024d415c63f8e7d584fbb5517a'
|
9
9
|
|
10
10
|
|
11
11
|
def _get_git_commit():
|
@@ -35,7 +35,7 @@ def _get_git_commit():
|
|
35
35
|
|
36
36
|
|
37
37
|
__commit__ = _get_git_commit()
|
38
|
-
__version__ = '1.0.0.
|
38
|
+
__version__ = '1.0.0.dev20250716'
|
39
39
|
__root_dir__ = os.path.dirname(os.path.abspath(__file__))
|
40
40
|
|
41
41
|
|
sky/adaptors/nebius.py
CHANGED
@@ -89,6 +89,12 @@ def iam():
|
|
89
89
|
return iam_v1
|
90
90
|
|
91
91
|
|
92
|
+
def billing():
|
93
|
+
# pylint: disable=import-outside-toplevel
|
94
|
+
from nebius.api.nebius.billing import v1alpha1 as billing_v1alpha1
|
95
|
+
return billing_v1alpha1
|
96
|
+
|
97
|
+
|
92
98
|
def nebius_common():
|
93
99
|
# pylint: disable=import-outside-toplevel
|
94
100
|
from nebius.api.nebius.common import v1 as common_v1
|
@@ -0,0 +1,308 @@
|
|
1
|
+
"""A script that queries Nebius API to get instance types and pricing info.
|
2
|
+
|
3
|
+
This script takes about 1 minute to finish.
|
4
|
+
"""
|
5
|
+
import csv
|
6
|
+
from dataclasses import dataclass
|
7
|
+
import decimal
|
8
|
+
import json
|
9
|
+
import logging
|
10
|
+
import re
|
11
|
+
from typing import Any, Dict, List, Optional
|
12
|
+
|
13
|
+
from sky.adaptors import nebius
|
14
|
+
from sky.adaptors.nebius import billing
|
15
|
+
from sky.adaptors.nebius import compute
|
16
|
+
from sky.adaptors.nebius import iam
|
17
|
+
from sky.adaptors.nebius import nebius_common
|
18
|
+
|
19
|
+
logger = logging.getLogger(__name__)
|
20
|
+
|
21
|
+
TIMEOUT = 10
|
22
|
+
PARENT_ID_TEMPLATE = 'project-{}public-images'
|
23
|
+
ACCELERATOR_MANUFACTURER = 'NVIDIA'
|
24
|
+
|
25
|
+
|
26
|
+
@dataclass
|
27
|
+
class PresetInfo:
|
28
|
+
"""Represents information about a specific compute preset,
|
29
|
+
including its pricing.
|
30
|
+
|
31
|
+
Attributes:
|
32
|
+
region (str): The geographical region where the preset is available.
|
33
|
+
fullname (str): The full name of the preset, a combination of platform
|
34
|
+
and preset name.
|
35
|
+
name (str): The name of the preset.
|
36
|
+
platform_name (str): The name of the platform the preset belongs to.
|
37
|
+
gpu (int): The number of GPUs in the preset.
|
38
|
+
vcpu (int): The number of virtual CPUs in the preset.
|
39
|
+
memory_gib (int): The amount of memory in GiB in the preset.
|
40
|
+
accelerator_manufacturer (str | None): The manufacturer of the
|
41
|
+
accelerator (e.g., "NVIDIA"), or None if no accelerator.
|
42
|
+
accelerator_name (str | None): The name of the accelerator
|
43
|
+
(e.g., "H100"), or None if no accelerator.
|
44
|
+
price_hourly (decimal.Decimal): The hourly price of the preset.
|
45
|
+
"""
|
46
|
+
|
47
|
+
region: str
|
48
|
+
fullname: str
|
49
|
+
name: str
|
50
|
+
platform_name: str
|
51
|
+
gpu: int
|
52
|
+
vcpu: int
|
53
|
+
memory_gib: int
|
54
|
+
accelerator_manufacturer: Optional[str]
|
55
|
+
accelerator_name: Optional[str]
|
56
|
+
price_hourly: decimal.Decimal
|
57
|
+
|
58
|
+
|
59
|
+
def _format_decimal(value: decimal.Decimal) -> str:
|
60
|
+
"""Formats a decimal value to a string with at least two decimal places,
|
61
|
+
removing trailing zeros and ensuring a two-digit decimal part.
|
62
|
+
|
63
|
+
Args:
|
64
|
+
value (decimal.Decimal): The decimal value to format.
|
65
|
+
|
66
|
+
Returns:
|
67
|
+
str: The formatted string representation of the decimal.
|
68
|
+
"""
|
69
|
+
formatted_value = f'{value:f}'.rstrip('0').rstrip('.')
|
70
|
+
integer_part, decimal_part = formatted_value.split(
|
71
|
+
'.') if '.' in formatted_value else (formatted_value, '')
|
72
|
+
if len(decimal_part) < 2:
|
73
|
+
decimal_part += '0' * (2 - len(decimal_part))
|
74
|
+
|
75
|
+
return f'{integer_part}.{decimal_part}'
|
76
|
+
|
77
|
+
|
78
|
+
def _estimate_platforms(platforms: List[Any], parent_id: str,
|
79
|
+
region: str) -> List[PresetInfo]:
|
80
|
+
"""Collects specifications for all presets on the given platforms to form a
|
81
|
+
batch price request. It then sends the request and processes the responses
|
82
|
+
to create a list of PresetInfo objects.
|
83
|
+
|
84
|
+
Args:
|
85
|
+
platforms (List[Platform]): A List of compute platforms to estimate
|
86
|
+
prices for.
|
87
|
+
parent_id (str): The parent ID used for resource metadata
|
88
|
+
in the estimate request.
|
89
|
+
region (str): The region associated with the platforms.
|
90
|
+
|
91
|
+
Returns:
|
92
|
+
List[PresetInfo]: A list of PresetInfo objects containing details and
|
93
|
+
estimated prices for each preset.
|
94
|
+
"""
|
95
|
+
|
96
|
+
calculator_service = billing().CalculatorServiceClient(nebius.sdk())
|
97
|
+
futures = []
|
98
|
+
|
99
|
+
for platform in platforms:
|
100
|
+
platform_name = platform.metadata.name
|
101
|
+
|
102
|
+
for preset in platform.spec.presets:
|
103
|
+
# Form the specification for the price request
|
104
|
+
estimate_spec = billing().ResourceSpec(
|
105
|
+
compute_instance_spec=compute().CreateInstanceRequest(
|
106
|
+
metadata=nebius_common().ResourceMetadata(
|
107
|
+
parent_id=parent_id,),
|
108
|
+
spec=compute().InstanceSpec(
|
109
|
+
resources=compute().ResourcesSpec(
|
110
|
+
platform=platform_name,
|
111
|
+
preset=preset.name,
|
112
|
+
)),
|
113
|
+
))
|
114
|
+
|
115
|
+
price_request = billing().EstimateBatchRequest(
|
116
|
+
resource_specs=[estimate_spec])
|
117
|
+
# Start future for each preset
|
118
|
+
futures.append((
|
119
|
+
platform,
|
120
|
+
preset,
|
121
|
+
calculator_service.estimate_batch(price_request,
|
122
|
+
timeout=TIMEOUT),
|
123
|
+
))
|
124
|
+
|
125
|
+
# wait all futures to complete and collect results
|
126
|
+
result = []
|
127
|
+
for platform, preset, future in futures:
|
128
|
+
platform_name = platform.metadata.name
|
129
|
+
result.append(
|
130
|
+
PresetInfo(
|
131
|
+
region=region,
|
132
|
+
fullname=f'{platform_name}_{preset.name}',
|
133
|
+
name=preset.name,
|
134
|
+
platform_name=platform_name,
|
135
|
+
gpu=preset.resources.gpu_count or 0,
|
136
|
+
vcpu=preset.resources.vcpu_count,
|
137
|
+
memory_gib=preset.resources.memory_gibibytes,
|
138
|
+
accelerator_manufacturer=ACCELERATOR_MANUFACTURER
|
139
|
+
if platform_name.startswith('gpu-') else '',
|
140
|
+
accelerator_name=platform_name.split('-')[1].upper()
|
141
|
+
if platform_name.startswith('gpu-') else '',
|
142
|
+
price_hourly=decimal.Decimal(
|
143
|
+
future.wait().hourly_cost.general.total.cost),
|
144
|
+
))
|
145
|
+
|
146
|
+
return result
|
147
|
+
|
148
|
+
|
149
|
+
def _write_preset_prices(presets: List[PresetInfo], output_file: str) -> None:
|
150
|
+
"""Writes the provided preset information to a CSV file.
|
151
|
+
|
152
|
+
Args:
|
153
|
+
presets (List[PresetInfo]): A list of PresetInfo objects to write.
|
154
|
+
output_file (str): The path to the output CSV file.
|
155
|
+
"""
|
156
|
+
# Set up the CSV writer to output to stdout
|
157
|
+
with open(output_file, 'w', encoding='utf-8') as out:
|
158
|
+
header = [
|
159
|
+
'InstanceType',
|
160
|
+
'AcceleratorName',
|
161
|
+
'AcceleratorCount',
|
162
|
+
'vCPUs',
|
163
|
+
'MemoryGiB',
|
164
|
+
'Price',
|
165
|
+
'Region',
|
166
|
+
'GpuInfo',
|
167
|
+
'SpotPrice',
|
168
|
+
]
|
169
|
+
writer = csv.DictWriter(out, fieldnames=header)
|
170
|
+
writer.writeheader()
|
171
|
+
|
172
|
+
for preset in sorted(presets,
|
173
|
+
key=lambda x:
|
174
|
+
(bool(x.gpu), x.region, x.platform_name, x.vcpu)):
|
175
|
+
gpu_info = ''
|
176
|
+
if preset.gpu > 0:
|
177
|
+
gpu_info_dict = {
|
178
|
+
'Gpus': [{
|
179
|
+
'Name': preset.accelerator_name,
|
180
|
+
'Manufacturer': preset.accelerator_manufacturer,
|
181
|
+
'Count': preset.gpu,
|
182
|
+
'MemoryInfo': {
|
183
|
+
'SizeInMiB': preset.memory_gib * 1024 // preset.gpu
|
184
|
+
},
|
185
|
+
}],
|
186
|
+
'TotalGpuMemoryInMiB': preset.memory_gib * 1024,
|
187
|
+
}
|
188
|
+
gpu_info = json.dumps(gpu_info_dict).replace('"', '\'')
|
189
|
+
|
190
|
+
writer.writerow({
|
191
|
+
'InstanceType': preset.fullname,
|
192
|
+
'AcceleratorName': preset.accelerator_name,
|
193
|
+
'AcceleratorCount': preset.gpu,
|
194
|
+
'vCPUs': preset.vcpu,
|
195
|
+
'MemoryGiB': preset.memory_gib,
|
196
|
+
'Price': _format_decimal(preset.price_hourly),
|
197
|
+
'Region': preset.region,
|
198
|
+
'GpuInfo': gpu_info,
|
199
|
+
'SpotPrice': '',
|
200
|
+
})
|
201
|
+
|
202
|
+
|
203
|
+
def _fetch_platforms_for_project(project_id: str) -> List[Any]:
|
204
|
+
"""Fetches all available compute platforms for a given project.
|
205
|
+
|
206
|
+
Args:
|
207
|
+
project_id (str): The ID of the project to fetch platforms from.
|
208
|
+
|
209
|
+
Returns:
|
210
|
+
List[ComputePlatform]: A list of ComputePlatform objects available
|
211
|
+
in the project.
|
212
|
+
"""
|
213
|
+
platform_service = compute().PlatformServiceClient(nebius.sdk())
|
214
|
+
|
215
|
+
platform_request = compute().ListPlatformsRequest(page_size=999,
|
216
|
+
parent_id=project_id)
|
217
|
+
platform_response = platform_service.list(platform_request,
|
218
|
+
timeout=TIMEOUT).wait()
|
219
|
+
|
220
|
+
return platform_response.items
|
221
|
+
|
222
|
+
|
223
|
+
def _get_regions_map() -> Dict[str, str]:
|
224
|
+
"""Maps region codes to their full names by iterating through tenants and
|
225
|
+
projects.
|
226
|
+
|
227
|
+
Returns:
|
228
|
+
dict[str, str]: A dictionary where keys are region codes (e.g., "e00")
|
229
|
+
and values are full region names (e.g., "eu-north1").
|
230
|
+
"""
|
231
|
+
result = {}
|
232
|
+
response = iam().TenantServiceClient(nebius.sdk()).list(
|
233
|
+
iam().ListTenantsRequest(), timeout=TIMEOUT).wait()
|
234
|
+
|
235
|
+
for tenant in response.items:
|
236
|
+
projects = (iam().ProjectServiceClient(nebius.sdk()).list(
|
237
|
+
iam().ListProjectsRequest(parent_id=tenant.metadata.id),
|
238
|
+
timeout=TIMEOUT).wait())
|
239
|
+
|
240
|
+
for project in projects.items:
|
241
|
+
match = re.match(r'^project-([a-z0-9]{3})', project.metadata.id)
|
242
|
+
if match is None:
|
243
|
+
logger.error('Could not parse project id %s',
|
244
|
+
project.metadata.id)
|
245
|
+
continue
|
246
|
+
result[match.group(1)] = project.status.region
|
247
|
+
|
248
|
+
return result
|
249
|
+
|
250
|
+
|
251
|
+
def _get_all_platform_prices() -> List[PresetInfo]:
|
252
|
+
"""Orchestrates fetching specifications and prices for all platforms across
|
253
|
+
all regions.
|
254
|
+
|
255
|
+
This function first retrieves a map of region codes to full names, then
|
256
|
+
iterates through each region, fetches available platforms for
|
257
|
+
the corresponding project ID, and finally estimates prices for all presets
|
258
|
+
on those platforms.
|
259
|
+
|
260
|
+
Returns:
|
261
|
+
List[PresetInfo]: A consolidated list of PresetInfo objects for all
|
262
|
+
platforms and presets across all regions.
|
263
|
+
"""
|
264
|
+
|
265
|
+
# Get regions codes to names
|
266
|
+
regions_map = _get_regions_map()
|
267
|
+
|
268
|
+
presets = []
|
269
|
+
|
270
|
+
for region_code in sorted(regions_map.keys()):
|
271
|
+
project_id = PARENT_ID_TEMPLATE.format(region_code)
|
272
|
+
region = regions_map[region_code]
|
273
|
+
logger.info('Processing region: %s (project: %s)...', region,
|
274
|
+
project_id)
|
275
|
+
|
276
|
+
platforms = _fetch_platforms_for_project(project_id)
|
277
|
+
if not platforms:
|
278
|
+
logger.warning('No platforms found in region %s', region)
|
279
|
+
continue
|
280
|
+
|
281
|
+
presets.extend(
|
282
|
+
_estimate_platforms(platforms=platforms,
|
283
|
+
parent_id=project_id,
|
284
|
+
region=region))
|
285
|
+
|
286
|
+
return presets
|
287
|
+
|
288
|
+
|
289
|
+
def main() -> None:
|
290
|
+
"""Main function to fetch and write Nebius platform prices to a CSV file.
|
291
|
+
|
292
|
+
It initializes the SDK, fetches all platform prices, and then writes them
|
293
|
+
to the specified CSV file.
|
294
|
+
"""
|
295
|
+
|
296
|
+
output_file = 'nebius/vms.csv'
|
297
|
+
|
298
|
+
# Fetch presets and estimate
|
299
|
+
presets = _get_all_platform_prices()
|
300
|
+
|
301
|
+
# Write CSV
|
302
|
+
_write_preset_prices(presets, output_file)
|
303
|
+
|
304
|
+
logger.info('Done!')
|
305
|
+
|
306
|
+
|
307
|
+
if __name__ == '__main__':
|
308
|
+
main()
|
sky/clouds/hyperbolic.py
CHANGED
@@ -55,6 +55,8 @@ class Hyperbolic(clouds.Cloud):
|
|
55
55
|
('Auto-stop not supported.'),
|
56
56
|
clouds.CloudImplementationFeatures.AUTODOWN:
|
57
57
|
('Auto-down not supported.'),
|
58
|
+
clouds.CloudImplementationFeatures.CUSTOM_MULTI_NETWORK:
|
59
|
+
('Customized multiple network interfaces not supported.'),
|
58
60
|
}
|
59
61
|
|
60
62
|
PROVISIONER_VERSION = clouds.ProvisionerVersion.SKYPILOT
|
sky/clouds/nebius.py
CHANGED
@@ -219,10 +219,12 @@ class Nebius(clouds.Cloud):
|
|
219
219
|
acc_dict)
|
220
220
|
platform, _ = resources.instance_type.split('_')
|
221
221
|
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
image_family = '
|
222
|
+
# Selecting image_family by platform
|
223
|
+
# https://docs.nebius.com/compute/storage/boot-disk-images
|
224
|
+
if platform.startswith('cpu'):
|
225
|
+
image_family = 'ubuntu24.04-driverless'
|
226
|
+
elif platform.startswith('gpu'):
|
227
|
+
image_family = 'ubuntu24.04-cuda12'
|
226
228
|
else:
|
227
229
|
raise RuntimeError('Unsupported instance type for Nebius cloud:'
|
228
230
|
f' {resources.instance_type}')
|
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/219887b94512388c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/219887b94512388c.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-3fad5d4a0541a02d.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-771a40cde532309b.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_error-c72a1f77a3c0be1b.js" defer=""></script><script src="/dashboard/_next/static/gVXjeFhvtWXyOsx9xYNvM/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/gVXjeFhvtWXyOsx9xYNvM/_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":"gVXjeFhvtWXyOsx9xYNvM","assetPrefix":"/dashboard","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
|
@@ -0,0 +1,11 @@
|
|
1
|
+
"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[1141],{9333:function(e,s,r){r.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,r(998).Z)("Save",[["path",{d:"M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z",key:"1c8476"}],["path",{d:"M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7",key:"1ydtos"}],["path",{d:"M7 3v4a1 1 0 0 0 1 1h7",key:"t51u73"}]])},8418:function(e,s,r){r.d(s,{Z:function(){return a}});/**
|
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 a=(0,r(998).Z)("Trash",[["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6",key:"4alrt4"}],["path",{d:"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2",key:"v07s0e"}]])},1812:function(e,s,r){r.d(s,{X:function(){return n}});var a=r(5893),l=r(7294);let t=e=>{if(!(null==e?void 0:e.message))return"An unexpected error occurred.";let s=e.message;return s.includes("failed:")&&(s=s.split("failed:")[1].trim()),s},n=e=>{let{error:s,title:r="Error",onDismiss:n}=e,[c,i]=(0,l.useState)(!1);if((0,l.useEffect)(()=>{s&&i(!1)},[s]),!s||c)return null;let o="string"==typeof s?s:t(s);return(0,a.jsx)("div",{className:"bg-red-50 border border-red-200 rounded-md p-3 mb-4",children:(0,a.jsxs)("div",{className:"flex items-center justify-between",children:[(0,a.jsxs)("div",{className:"flex",children:[(0,a.jsx)("div",{className:"flex-shrink-0",children:(0,a.jsx)("svg",{className:"h-5 w-5 text-red-400",viewBox:"0 0 20 20",fill:"currentColor",children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z",clipRule:"evenodd"})})}),(0,a.jsx)("div",{className:"ml-3",children:(0,a.jsxs)("div",{className:"text-sm text-red-800",children:[(0,a.jsxs)("strong",{children:[r,":"]})," ",o]})})]}),(0,a.jsx)("button",{onClick:()=>{i(!0),n&&n()},className:"flex-shrink-0 ml-4 text-red-400 hover:text-red-600 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 focus:ring-offset-red-50 rounded","aria-label":"Dismiss error",children:(0,a.jsx)("svg",{className:"h-4 w-4",viewBox:"0 0 20 20",fill:"currentColor",children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z",clipRule:"evenodd"})})})]})})}},9123:function(e,s,r){r.d(s,{g:function(){return n}});var a=r(5893),l=r(7294),t=r(2350);let n=l.forwardRef((e,s)=>{let{className:r,...l}=e;return(0,a.jsx)("textarea",{className:(0,t.cn)("flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",r),ref:s,...l})});n.displayName="Textarea"},1141:function(e,s,r){r.r(s),r.d(s,{WorkspaceEditor:function(){return R}});var a=r(5893),l=r(7294),t=r(1163),n=r(7324),c=r(3266),i=r(8969);r(9470);var o=r(1664),d=r.n(o),u=r(9008),x=r.n(u),m=r(7673),h=r(803),f=r(9123),g=r(5739),p=r(282),b=r(6021),j=r(3626),y=r(8418),N=r(9333),v=r(326);let w=e=>{let{className:s="",variant:r="default",children:l,...t}=e;return(0,a.jsx)("div",{role:"alert",className:"".concat("relative w-full rounded-lg border p-4 flex items-start space-x-2"," ").concat({default:"bg-blue-50 border-blue-200 text-blue-800",destructive:"bg-red-50 border-red-200 text-red-800"}[r]," ").concat(s),...t,children:l})},k=e=>{let{className:s="",children:r,...l}=e;return(0,a.jsx)("div",{className:"text-sm leading-relaxed ".concat(s),...l,children:r})};var C=r(3850),L=r(1812),S=r(938),E=r(1272),Z=r(3225),D=r(3081);let M=e=>{let{message:s}=e;return s?(0,a.jsxs)(w,{className:"border-green-200 bg-green-50",children:[(0,a.jsx)(p.Z,{className:"h-4 w-4 text-green-600"}),(0,a.jsx)(k,{className:"text-green-800",children:s})]}):null},A=e=>{let{workspaceName:s,config:r,enabledClouds:l=[]}=e;if(!r)return null;let t="default"===s,n=0===Object.keys(r).length;if(t&&n)return(0,a.jsx)("div",{className:"text-sm text-gray-500 mb-3 italic p-3 bg-sky-50 rounded border border-sky-200",children:"Workspace 'default' can use all accessible infrastructure."});let c=[],i=[],o=[],d=new Set(l.map(e=>e.toLowerCase()));Object.entries(r).forEach(e=>{let[s,r]=e;if("private"===s||"allowed_users"===s)return;let l=Z.Z2[s.toLowerCase()]||s.toUpperCase(),t=d.has(null==l?void 0:l.toLowerCase());if((null==r?void 0:r.disabled)===!0)i.push(l);else if(r&&Object.keys(r).length>0){let e="";"gcp"===s.toLowerCase()&&r.project_id?e=" (Project ID: ".concat(r.project_id,")"):"aws"===s.toLowerCase()&&r.region&&(e=" (Region: ".concat(r.region,")")),t?c.push((0,a.jsxs)("span",{className:"block",children:[l,e," is enabled."]},"".concat(s,"-enabled"))):o.push((0,a.jsxs)("span",{className:"block text-amber-700",children:[l,e," is configured but not currently available."]},"".concat(s,"-configured-not-enabled")))}else t?c.push((0,a.jsxs)("span",{className:"block",children:[l," is enabled (using default settings)."]},"".concat(s,"-default-enabled"))):o.push((0,a.jsxs)("span",{className:"block text-amber-700",children:[l," is configured but not currently available."]},"".concat(s,"-default-not-enabled")))});let u=[];if(i.length>0){let e=i.join(" and ");u.push((0,a.jsxs)("span",{className:"block",children:[e," ",1===i.length?"is":"are"," explicitly disabled."]},"disabled-clouds"))}return(u.push(...c),u.push(...o),u.length>0)?(0,a.jsx)("div",{className:"text-sm text-gray-700 mb-3 p-3 bg-sky-50 rounded border border-sky-200",children:u}):!t&&n?(0,a.jsx)("div",{className:"text-sm text-gray-500 mb-3 italic p-3 bg-sky-50 rounded border border-sky-200",children:"This workspace has no specific cloud resource configurations and can use all accessible infrastructure."}):null},W=e=>{let{isPrivate:s}=e;return s?(0,a.jsx)("span",{className:"inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-gray-100 text-gray-700 border border-gray-300",children:"Private"}):(0,a.jsx)("span",{className:"inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-green-100 text-green-700 border border-green-300",children:"Public"})},P=e=>{let{workspaceConfig:s,allUsers:r}=e;if(!s.private)return null;let l=s.allowed_users||[],t=(r||[]).filter(e=>"admin"===e.role).map(e=>e.username),n=[...new Set([...l,...t])];return 0===n.length?(0,a.jsxs)("div",{className:"mt-4",children:[(0,a.jsx)("h4",{className:"mb-2 text-xs text-gray-500 tracking-wider",children:"Allowed Users (0)"}),(0,a.jsx)("div",{className:"text-amber-600 text-xs italic p-2 bg-amber-50 rounded border border-amber-200",children:"No users configured (workspace may be inaccessible)"})]}):(0,a.jsxs)("div",{className:"mt-4",children:[(0,a.jsxs)("h4",{className:"mb-2 text-xs text-gray-500 tracking-wider",children:["Allowed Users (",n.length,")"]}),(0,a.jsx)("div",{className:"space-y-1 max-h-48 overflow-y-auto border border-gray-200 rounded",children:n.map(e=>{let s=t.includes(e);return(0,a.jsxs)("div",{className:"flex items-center justify-between text-xs p-2 bg-gray-50 hover:bg-gray-100 border-b border-gray-100 last:border-b-0",children:[(0,a.jsx)("span",{className:"font-medium text-gray-700",children:e}),s?(0,a.jsxs)("span",{className:"inline-flex items-center text-blue-600",children:[(0,a.jsx)(C.r7,{className:"w-3 h-3 mr-1"}),"Admin"]}):(0,a.jsxs)("span",{className:"inline-flex items-center text-gray-600",children:[(0,a.jsx)(b.Z,{className:"w-3 h-3 mr-1"}),"User"]})]},e)})})]})};function R(e){let{workspaceName:s,isNewWorkspace:r=!1}=e,o=(0,t.useRouter)(),[u,p]=(0,l.useState)({}),[b,w]=(0,l.useState)({}),[k,Z]=(0,l.useState)(""),[R,_]=(0,l.useState)(!0),[z,O]=(0,l.useState)(!1),[T,U]=(0,l.useState)(!1),[Y,J]=(0,l.useState)(null),[I,V]=(0,l.useState)(null),[F,H]=(0,l.useState)(null),[X,B]=(0,l.useState)([]),[G,q]=(0,l.useState)({showDialog:!1,deleting:!1,error:null}),[K,Q]=(0,l.useState)({totalClusterCount:0,runningClusterCount:0,managedJobsCount:0,clouds:[]}),[$,ee]=(0,l.useState)(!1),es=(0,l.useCallback)(async()=>{_(!0),J(null);try{let e;let[r,a]=await Promise.all([(0,n.fX)(),(0,D.R)()]),l=r[s]||{};p(l),w(l),B(a||[]),e=0===Object.keys(l).length?"".concat(s,":\n # Empty workspace configuration - uses all accessible infrastructure\n"):E.ZP.dump({[s]:l},{indent:2,lineWidth:-1,noRefs:!0,skipInvalid:!0,flowLevel:-1}),Z(e)}catch(e){console.error("Error fetching workspace config:",e),J(e)}finally{_(!1)}},[s]),er=(0,l.useCallback)(async()=>{if(!r){ee(!0);try{let[e,r,a]=await Promise.all([(0,c.getClusters)(),(0,i.getManagedJobs)(),(0,n.yz)(s,!0)]),l=e.filter(e=>(e.workspace||"default")===s),t=l.filter(e=>"RUNNING"===e.status||"LAUNCHING"===e.status),o={};e.forEach(e=>{o[e.cluster]=e.workspace||"default"});let d=r.jobs||[],u=new Set(S.statusGroups.active),x=0;d.forEach(e=>{let r=e.cluster_name||e.resources&&e.resources.cluster_name;r&&o[r]===s&&u.has(e.status)&&x++}),Q({totalClusterCount:l.length,runningClusterCount:t.length,managedJobsCount:x,clouds:Array.isArray(a)?a:[]})}catch(e){console.error("Failed to fetch workspace stats:",e)}finally{ee(!1)}}},[s,r]);(0,l.useEffect)(()=>{r?(_(!1),Z("".concat(s,":\n # New workspace configuration\n # Leave empty to use all accessible infrastructure\n"))):(es(),er())},[s,r,es,er]),(0,l.useEffect)(()=>{U(JSON.stringify(u)!==JSON.stringify(b))},[u,b]);let ea=e=>{Z(e),H(null);try{let r=E.ZP.load(e)||{},a=Object.keys(r);if(0===a.length)p({});else if(1===a.length){let e=a[0];if(e!==s){H('Workspace name cannot be changed. Expected "'.concat(s,'" but found "').concat(e,'".'));return}let l=r[s]||{};p(l)}else H("Configuration must contain only one workspace. Found: ".concat(a.join(", ")))}catch(e){H("Invalid YAML: ".concat(e.message))}},el=async()=>{O(!0),J(null),V(null);try{if(F)throw Error("Please fix YAML errors before saving");let e=E.ZP.load(k)||{},a=Object.keys(e);if(a.length>0&&a[0]!==s)throw Error('Workspace name cannot be changed. Expected "'.concat(s,'".'));r?(await (0,n.MB)(s,u),V("Workspace created successfully!"),setTimeout(()=>{o.push("/workspaces/".concat(s))},1500)):(await (0,n.eA)(s,u),V("Workspace updated successfully!"),w(u),er())}catch(e){console.error("Error saving workspace:",e),J(e)}finally{O(!1)}},et=async()=>{q(e=>({...e,deleting:!0,error:null}));try{await (0,n.zl)(s),V("Workspace deleted successfully!"),setTimeout(()=>{o.push("/workspaces")},1500)}catch(e){console.error("Error deleting workspace:",e),q(s=>({...s,deleting:!1,error:e}))}},en=()=>{q({showDialog:!1,deleting:!1,error:null})},ec=async()=>{await Promise.all([es(),er()])};if(!o.isReady)return(0,a.jsx)("div",{children:"Loading..."});let ei=r?"Create New Workspace | SkyPilot Dashboard":"Workspace: ".concat(s," | SkyPilot Dashboard");return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(x(),{children:(0,a.jsx)("title",{children:ei})}),(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("div",{className:"flex items-center justify-between mb-4 h-5",children:[(0,a.jsxs)("div",{className:"text-base flex items-center",children:[(0,a.jsx)(d(),{href:"/workspaces",className:"text-sky-blue hover:underline",children:"Workspaces"}),(0,a.jsx)("span",{className:"mx-2 text-gray-500",children:"›"}),(0,a.jsx)(d(),{href:r?"/workspace/new":"/workspaces/".concat(s),className:"text-sky-blue hover:underline",children:r?"New Workspace":s}),T&&(0,a.jsx)("span",{className:"ml-3 px-2 py-1 bg-yellow-100 text-yellow-800 text-xs rounded",children:"Unsaved changes"})]}),(0,a.jsxs)("div",{className:"text-sm flex items-center",children:[(R||z||$)&&(0,a.jsxs)("div",{className:"flex items-center mr-4",children:[(0,a.jsx)(g.Z,{size:15,className:"mt-0"}),(0,a.jsx)("span",{className:"ml-2 text-gray-500",children:z?"Saving...":"Loading..."})]}),(0,a.jsxs)("div",{className:"flex items-center space-x-4",children:[!r&&(0,a.jsxs)("button",{onClick:ec,disabled:R||z||$,className:"text-sky-blue hover:text-sky-blue-bright font-medium inline-flex items-center",children:[(0,a.jsx)(j.Z,{className:"w-4 h-4 mr-1.5"}),"Refresh"]}),!r&&"default"!==s&&(0,a.jsxs)("button",{onClick:()=>q({...G,showDialog:!0}),disabled:G.deleting||z,className:"text-red-600 hover:text-red-700 font-medium inline-flex items-center",children:[(0,a.jsx)(y.Z,{className:"w-4 h-4 mr-1.5"}),"Delete"]})]})]})]}),R?(0,a.jsxs)("div",{className:"flex justify-center items-center py-12",children:[(0,a.jsx)(g.Z,{size:24,className:"mr-2"}),(0,a.jsx)("span",{className:"text-gray-500",children:"Loading workspace configuration..."})]}):(0,a.jsxs)("div",{className:"space-y-6",children:[(0,a.jsx)(L.X,{error:Y,title:"Error",onDismiss:()=>J(null)}),(0,a.jsx)(M,{message:I}),(0,a.jsxs)("div",{className:"grid grid-cols-1 lg:grid-cols-3 gap-6",children:[!r&&(0,a.jsx)("div",{className:"lg:col-span-1",children:(0,a.jsxs)(m.Zb,{className:"h-full",children:[(0,a.jsx)(m.Ol,{children:(0,a.jsx)(m.ll,{className:"text-base font-normal",children:(0,a.jsxs)("div",{className:"flex items-center justify-between",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("span",{className:"font-semibold",children:"Workspace:"})," ",s]}),(0,a.jsx)(W,{isPrivate:!0===b.private})]})})}),(0,a.jsxs)(m.aY,{className:"text-sm pb-2 flex-1",children:[(0,a.jsxs)("div",{className:"py-2 flex items-center justify-between",children:[(0,a.jsxs)("div",{className:"flex items-center text-gray-600",children:[(0,a.jsx)(C.QT,{className:"w-4 h-4 mr-2 text-gray-500"}),(0,a.jsx)("span",{children:"Clusters (Running / Total)"})]}),(0,a.jsx)("span",{className:"font-normal text-gray-800",children:$?"...":"".concat(K.runningClusterCount," / ").concat(K.totalClusterCount)})]}),(0,a.jsxs)("div",{className:"py-2 flex items-center justify-between border-t border-gray-100",children:[(0,a.jsxs)("div",{className:"flex items-center text-gray-600",children:[(0,a.jsx)(C.Vp,{className:"w-4 h-4 mr-2 text-gray-500"}),(0,a.jsx)("span",{children:"Managed Jobs"})]}),(0,a.jsx)("span",{className:"font-normal text-gray-800",children:$?"...":K.managedJobsCount})]})]}),(0,a.jsxs)("div",{className:"px-6 pb-6 text-sm pt-3",children:[(0,a.jsx)("h4",{className:"mb-2 text-xs text-gray-500 tracking-wider",children:"Enabled Infra"}),(0,a.jsx)("div",{className:"flex flex-wrap gap-x-4 gap-y-1",children:$?(0,a.jsx)("span",{className:"text-gray-500",children:"Loading..."}):K.clouds.length>0?K.clouds.map(e=>(0,a.jsxs)("div",{className:"flex items-center text-gray-700",children:[(0,a.jsx)(C.Ye,{className:"w-3.5 h-3.5 mr-1.5 text-green-500"}),(0,a.jsx)("span",{children:e})]},e)):(0,a.jsx)("span",{className:"text-gray-500 italic",children:"No enabled infrastructure"})}),(0,a.jsx)("div",{className:"mt-4",children:(0,a.jsx)(A,{workspaceName:s,config:b,enabledClouds:K.clouds})}),(0,a.jsx)(P,{workspaceConfig:b,allUsers:X})]})]})}),(0,a.jsx)("div",{className:r?"lg:col-span-3":"lg:col-span-2",children:(0,a.jsxs)(m.Zb,{className:"h-full flex flex-col",children:[(0,a.jsx)(m.Ol,{children:(0,a.jsx)(m.ll,{className:"text-base font-normal",children:r?"New Workspace YAML":"Edit Workspace YAML"})}),(0,a.jsx)(m.aY,{className:"flex-1 flex flex-col",children:(0,a.jsxs)("div",{className:"space-y-4 flex-1 flex flex-col",children:[F&&(0,a.jsx)(L.X,{error:F,onDismiss:()=>H(null)}),(0,a.jsxs)("div",{className:"flex-1 flex flex-col",children:[(0,a.jsxs)("p",{className:"text-sm text-gray-600 mb-3",children:["Configure infra-specific settings for this workspace. Leave empty to use all accessible infrastructure. Refer to"," ",(0,a.jsx)("a",{href:"https://docs.skypilot.co/en/latest/admin/workspaces.html#configuration",target:"_blank",rel:"noopener noreferrer",className:"text-blue-600",children:"SkyPilot Docs"})," ","for more details."]}),(0,a.jsxs)("div",{className:"mb-4",children:[(0,a.jsx)("h4",{className:"text-sm font-medium text-gray-700 mb-2",children:"Example configuration:"}),(0,a.jsx)("div",{className:"p-3 bg-gray-50 border rounded-lg",children:(0,a.jsx)("pre",{className:"text-xs font-mono text-gray-600 whitespace-pre-wrap",children:"".concat(s||"my-workspace",":\n private: true\n allowed_users:\n - user1@mydomain.com\n - user2@mydomain.com\n gcp:\n project_id: xxx\n disabled: false\n kubernetes:\n allowed_contexts:\n - context-1")})})]}),(0,a.jsx)(f.g,{value:k,onChange:e=>ea(e.target.value),className:"font-mono text-sm flex-1 resize-none",style:{minHeight:"350px"},spellCheck:!1,placeholder:"# Enter workspace configuration in YAML format"}),(0,a.jsx)("div",{className:"flex justify-end space-x-3 pt-3 border-gray-200",children:(0,a.jsxs)(h.z,{onClick:el,disabled:z||F||R,className:"inline-flex items-center bg-sky-600 hover:bg-sky-700 text-white",children:[(0,a.jsx)(N.Z,{className:"w-4 h-4 mr-1.5"}),z?"Applying...":"Apply"]})})]})]})})]})})]})]}),(0,a.jsx)(v.Vq,{open:G.showDialog,onOpenChange:en,children:(0,a.jsxs)(v.cZ,{className:"sm:max-w-md",children:[(0,a.jsxs)(v.fK,{className:"",children:[(0,a.jsx)(v.$N,{children:"Delete Workspace"}),(0,a.jsxs)(v.Be,{children:['Are you sure you want to delete workspace "',s,'"? This action cannot be undone.']})]}),G.error&&(0,a.jsx)(L.X,{error:G.error,title:"Deletion Failed",onDismiss:()=>q(e=>({...e,error:null}))}),(0,a.jsxs)(v.cN,{className:"",children:[(0,a.jsx)(h.z,{variant:"outline",onClick:en,disabled:G.deleting,children:"Cancel"}),(0,a.jsx)(h.z,{variant:"destructive",onClick:et,disabled:G.deleting,children:G.deleting?"Deleting...":"Delete"})]})]})})]})]})}}}]);
|
@@ -0,0 +1,60 @@
|
|
1
|
+
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[1746,430,5491],{8671:function(e,t,n){"use strict";n.d(t,{Z:function(){return r}});/**
|
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 r=(0,n(998).Z)("Copy",[["rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2",key:"17jyea"}],["path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2",key:"zix9uf"}]])},6826:function(e,t,n){"use strict";n.d(t,{Z:function(){return r}});/**
|
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 r=(0,n(998).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"}]])},3685:function(e,t,n){"use strict";n.d(t,{Z:function(){return r}});/**
|
12
|
+
* @license lucide-react v0.407.0 - ISC
|
13
|
+
*
|
14
|
+
* This source code is licensed under the ISC license.
|
15
|
+
* See the LICENSE file in the root directory of this source tree.
|
16
|
+
*/let r=(0,n(998).Z)("EyeOff",[["path",{d:"M9.88 9.88a3 3 0 1 0 4.24 4.24",key:"1jxqfv"}],["path",{d:"M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68",key:"9wicm4"}],["path",{d:"M6.61 6.61A13.526 13.526 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61",key:"1jreej"}],["line",{x1:"2",x2:"22",y1:"2",y2:"22",key:"a6p6uj"}]])},6741:function(e,t,n){"use strict";n.d(t,{Z:function(){return r}});/**
|
17
|
+
* @license lucide-react v0.407.0 - ISC
|
18
|
+
*
|
19
|
+
* This source code is licensed under the ISC license.
|
20
|
+
* See the LICENSE file in the root directory of this source tree.
|
21
|
+
*/let r=(0,n(998).Z)("Eye",[["path",{d:"M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z",key:"rwhkz3"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]])},3936:function(e,t,n){"use strict";n.d(t,{Z:function(){return r}});/**
|
22
|
+
* @license lucide-react v0.407.0 - ISC
|
23
|
+
*
|
24
|
+
* This source code is licensed under the ISC license.
|
25
|
+
* See the LICENSE file in the root directory of this source tree.
|
26
|
+
*/let r=(0,n(998).Z)("KeyRound",[["path",{d:"M2.586 17.414A2 2 0 0 0 2 18.828V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.172a2 2 0 0 0 1.414-.586l.814-.814a6.5 6.5 0 1 0-4-4z",key:"1s6t7t"}],["circle",{cx:"16.5",cy:"7.5",r:".5",fill:"currentColor",key:"w0ekpg"}]])},5274:function(e,t,n){"use strict";n.d(t,{Z:function(){return r}});/**
|
27
|
+
* @license lucide-react v0.407.0 - ISC
|
28
|
+
*
|
29
|
+
* This source code is licensed under the ISC license.
|
30
|
+
* See the LICENSE file in the root directory of this source tree.
|
31
|
+
*/let r=(0,n(998).Z)("Pen",[["path",{d:"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z",key:"1a8usu"}]])},1260:function(e,t,n){"use strict";n.d(t,{Z:function(){return r}});/**
|
32
|
+
* @license lucide-react v0.407.0 - ISC
|
33
|
+
*
|
34
|
+
* This source code is licensed under the ISC license.
|
35
|
+
* See the LICENSE file in the root directory of this source tree.
|
36
|
+
*/let r=(0,n(998).Z)("Plus",[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"M12 5v14",key:"s699le"}]])},3626:function(e,t,n){"use strict";n.d(t,{Z:function(){return r}});/**
|
37
|
+
* @license lucide-react v0.407.0 - ISC
|
38
|
+
*
|
39
|
+
* This source code is licensed under the ISC license.
|
40
|
+
* See the LICENSE file in the root directory of this source tree.
|
41
|
+
*/let r=(0,n(998).Z)("RotateCw",[["path",{d:"M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8",key:"1p45f6"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}]])},7603:function(e,t,n){"use strict";n.d(t,{Z:function(){return r}});/**
|
42
|
+
* @license lucide-react v0.407.0 - ISC
|
43
|
+
*
|
44
|
+
* This source code is licensed under the ISC license.
|
45
|
+
* See the LICENSE file in the root directory of this source tree.
|
46
|
+
*/let r=(0,n(998).Z)("Trash2",[["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6",key:"4alrt4"}],["path",{d:"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2",key:"v07s0e"}],["line",{x1:"10",x2:"10",y1:"11",y2:"17",key:"1uufr5"}],["line",{x1:"14",x2:"14",y1:"11",y2:"17",key:"xtxkd"}]])},1109:function(e,t,n){"use strict";n.d(t,{Z:function(){return r}});/**
|
47
|
+
* @license lucide-react v0.407.0 - ISC
|
48
|
+
*
|
49
|
+
* This source code is licensed under the ISC license.
|
50
|
+
* See the LICENSE file in the root directory of this source tree.
|
51
|
+
*/let r=(0,n(998).Z)("Upload",[["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["polyline",{points:"17 8 12 3 7 8",key:"t8dd8p"}],["line",{x1:"12",x2:"12",y1:"3",y2:"15",key:"widbto"}]])},3767:function(e,t,n){"use strict";n.d(t,{Z:function(){return r}});/**
|
52
|
+
* @license lucide-react v0.407.0 - ISC
|
53
|
+
*
|
54
|
+
* This source code is licensed under the ISC license.
|
55
|
+
* See the LICENSE file in the root directory of this source tree.
|
56
|
+
*/let r=(0,n(998).Z)("X",[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]])},1163:function(e,t,n){e.exports=n(6036)},6327:function(e,t,n){"use strict";n.d(t,{x8:function(){return ea},VY:function(){return eo},dk:function(){return eu},aV:function(){return er},h_:function(){return en},fC:function(){return ee},Dx:function(){return ei},xz:function(){return et}});var r=n(7294),o=n(6206),i=n(8771),u=n(5360),a=n(1276),l=n(7342),s=n(6063),c=n(5420),d=n(2651),f=n(9981),p=e=>{let t,n;let{present:o,children:u}=e,a=function(e){var t,n;let[o,i]=r.useState(),u=r.useRef(null),a=r.useRef(e),l=r.useRef("none"),[s,c]=(t=e?"mounted":"unmounted",n={mounted:{UNMOUNT:"unmounted",ANIMATION_OUT:"unmountSuspended"},unmountSuspended:{MOUNT:"mounted",ANIMATION_END:"unmounted"},unmounted:{MOUNT:"mounted"}},r.useReducer((e,t)=>n[e][t]??e,t));return r.useEffect(()=>{let e=y(u.current);l.current="mounted"===s?e:"none"},[s]),(0,f.b)(()=>{let t=u.current,n=a.current;if(n!==e){let r=l.current,o=y(t);e?c("MOUNT"):"none"===o||t?.display==="none"?c("UNMOUNT"):n&&r!==o?c("ANIMATION_OUT"):c("UNMOUNT"),a.current=e}},[e,c]),(0,f.b)(()=>{if(o){let e;let t=o.ownerDocument.defaultView??window,n=n=>{let r=y(u.current).includes(n.animationName);if(n.target===o&&r&&(c("ANIMATION_END"),!a.current)){let n=o.style.animationFillMode;o.style.animationFillMode="forwards",e=t.setTimeout(()=>{"forwards"===o.style.animationFillMode&&(o.style.animationFillMode=n)})}},r=e=>{e.target===o&&(l.current=y(u.current))};return o.addEventListener("animationstart",r),o.addEventListener("animationcancel",n),o.addEventListener("animationend",n),()=>{t.clearTimeout(e),o.removeEventListener("animationstart",r),o.removeEventListener("animationcancel",n),o.removeEventListener("animationend",n)}}c("ANIMATION_END")},[o,c]),{isPresent:["mounted","unmountSuspended"].includes(s),ref:r.useCallback(e=>{u.current=e?getComputedStyle(e):null,i(e)},[])}}(o),l="function"==typeof u?u({present:a.isPresent}):r.Children.only(u),s=(0,i.e)(a.ref,(t=Object.getOwnPropertyDescriptor(l.props,"ref")?.get)&&"isReactWarning"in t&&t.isReactWarning?l.ref:(t=Object.getOwnPropertyDescriptor(l,"ref")?.get)&&"isReactWarning"in t&&t.isReactWarning?l.props.ref:l.props.ref||l.ref);return"function"==typeof u||a.isPresent?r.cloneElement(l,{ref:s}):null};function y(e){return e?.animationName||"none"}p.displayName="Presence";var m=n(5320),v=n(7552),g=n(6223),h=n(3541),x=n(8426),k=n(5893),M="Dialog",[N,D]=(0,u.b)(M),[j,w]=N(M),O=e=>{let{__scopeDialog:t,children:n,open:o,defaultOpen:i,onOpenChange:u,modal:s=!0}=e,c=r.useRef(null),d=r.useRef(null),[f,p]=(0,l.T)({prop:o,defaultProp:i??!1,onChange:u,caller:M});return(0,k.jsx)(j,{scope:t,triggerRef:c,contentRef:d,contentId:(0,a.M)(),titleId:(0,a.M)(),descriptionId:(0,a.M)(),open:f,onOpenChange:p,onOpenToggle:r.useCallback(()=>p(e=>!e),[p]),modal:s,children:n})};O.displayName=M;var b="DialogTrigger",R=r.forwardRef((e,t)=>{let{__scopeDialog:n,...r}=e,u=w(b,n),a=(0,i.e)(t,u.triggerRef);return(0,k.jsx)(m.WV.button,{type:"button","aria-haspopup":"dialog","aria-expanded":u.open,"aria-controls":u.contentId,"data-state":K(u.open),...r,ref:a,onClick:(0,o.M)(e.onClick,u.onOpenToggle)})});R.displayName=b;var I="DialogPortal",[C,E]=N(I,{forceMount:void 0}),Z=e=>{let{__scopeDialog:t,forceMount:n,children:o,container:i}=e,u=w(I,t);return(0,k.jsx)(C,{scope:t,forceMount:n,children:r.Children.map(o,e=>(0,k.jsx)(p,{present:n||u.open,children:(0,k.jsx)(d.h,{asChild:!0,container:i,children:e})}))})};Z.displayName=I;var A="DialogOverlay",T=r.forwardRef((e,t)=>{let n=E(A,e.__scopeDialog),{forceMount:r=n.forceMount,...o}=e,i=w(A,e.__scopeDialog);return i.modal?(0,k.jsx)(p,{present:r||i.open,children:(0,k.jsx)(F,{...o,ref:t})}):null});T.displayName=A;var _=(0,x.Z8)("DialogOverlay.RemoveScroll"),F=r.forwardRef((e,t)=>{let{__scopeDialog:n,...r}=e,o=w(A,n);return(0,k.jsx)(g.Z,{as:_,allowPinchZoom:!0,shards:[o.contentRef],children:(0,k.jsx)(m.WV.div,{"data-state":K(o.open),...r,ref:t,style:{pointerEvents:"auto",...r.style}})})}),P="DialogContent",V=r.forwardRef((e,t)=>{let n=E(P,e.__scopeDialog),{forceMount:r=n.forceMount,...o}=e,i=w(P,e.__scopeDialog);return(0,k.jsx)(p,{present:r||i.open,children:i.modal?(0,k.jsx)(W,{...o,ref:t}):(0,k.jsx)(U,{...o,ref:t})})});V.displayName=P;var W=r.forwardRef((e,t)=>{let n=w(P,e.__scopeDialog),u=r.useRef(null),a=(0,i.e)(t,n.contentRef,u);return r.useEffect(()=>{let e=u.current;if(e)return(0,h.Ry)(e)},[]),(0,k.jsx)(L,{...e,ref:a,trapFocus:n.open,disableOutsidePointerEvents:!0,onCloseAutoFocus:(0,o.M)(e.onCloseAutoFocus,e=>{e.preventDefault(),n.triggerRef.current?.focus()}),onPointerDownOutside:(0,o.M)(e.onPointerDownOutside,e=>{let t=e.detail.originalEvent,n=0===t.button&&!0===t.ctrlKey;(2===t.button||n)&&e.preventDefault()}),onFocusOutside:(0,o.M)(e.onFocusOutside,e=>e.preventDefault())})}),U=r.forwardRef((e,t)=>{let n=w(P,e.__scopeDialog),o=r.useRef(!1),i=r.useRef(!1);return(0,k.jsx)(L,{...e,ref:t,trapFocus:!1,disableOutsidePointerEvents:!1,onCloseAutoFocus:t=>{e.onCloseAutoFocus?.(t),t.defaultPrevented||(o.current||n.triggerRef.current?.focus(),t.preventDefault()),o.current=!1,i.current=!1},onInteractOutside:t=>{e.onInteractOutside?.(t),t.defaultPrevented||(o.current=!0,"pointerdown"!==t.detail.originalEvent.type||(i.current=!0));let r=t.target;n.triggerRef.current?.contains(r)&&t.preventDefault(),"focusin"===t.detail.originalEvent.type&&i.current&&t.preventDefault()}})}),L=r.forwardRef((e,t)=>{let{__scopeDialog:n,trapFocus:o,onOpenAutoFocus:u,onCloseAutoFocus:a,...l}=e,d=w(P,n),f=r.useRef(null),p=(0,i.e)(t,f);return(0,v.EW)(),(0,k.jsxs)(k.Fragment,{children:[(0,k.jsx)(c.M,{asChild:!0,loop:!0,trapped:o,onMountAutoFocus:u,onUnmountAutoFocus:a,children:(0,k.jsx)(s.XB,{role:"dialog",id:d.contentId,"aria-describedby":d.descriptionId,"aria-labelledby":d.titleId,"data-state":K(d.open),...l,ref:p,onDismiss:()=>d.onOpenChange(!1)})}),(0,k.jsxs)(k.Fragment,{children:[(0,k.jsx)(J,{titleId:d.titleId}),(0,k.jsx)(Q,{contentRef:f,descriptionId:d.descriptionId})]})]})}),S="DialogTitle",z=r.forwardRef((e,t)=>{let{__scopeDialog:n,...r}=e,o=w(S,n);return(0,k.jsx)(m.WV.h2,{id:o.titleId,...r,ref:t})});z.displayName=S;var $="DialogDescription",q=r.forwardRef((e,t)=>{let{__scopeDialog:n,...r}=e,o=w($,n);return(0,k.jsx)(m.WV.p,{id:o.descriptionId,...r,ref:t})});q.displayName=$;var H="DialogClose",B=r.forwardRef((e,t)=>{let{__scopeDialog:n,...r}=e,i=w(H,n);return(0,k.jsx)(m.WV.button,{type:"button",...r,ref:t,onClick:(0,o.M)(e.onClick,()=>i.onOpenChange(!1))})});function K(e){return e?"open":"closed"}B.displayName=H;var X="DialogTitleWarning",[Y,G]=(0,u.k)(X,{contentName:P,titleName:S,docsSlug:"dialog"}),J=({titleId:e})=>{let t=G(X),n=`\`${t.contentName}\` requires a \`${t.titleName}\` for the component to be accessible for screen reader users.
|
57
|
+
|
58
|
+
If you want to hide the \`${t.titleName}\`, you can wrap it with our VisuallyHidden component.
|
59
|
+
|
60
|
+
For more information, see https://radix-ui.com/primitives/docs/components/${t.docsSlug}`;return r.useEffect(()=>{e&&!document.getElementById(e)&&console.error(n)},[n,e]),null},Q=({contentRef:e,descriptionId:t})=>{let n=G("DialogDescriptionWarning"),o=`Warning: Missing \`Description\` or \`aria-describedby={undefined}\` for {${n.contentName}}.`;return r.useEffect(()=>{let n=e.current?.getAttribute("aria-describedby");t&&n&&!document.getElementById(t)&&console.warn(o)},[o,e,t]),null},ee=O,et=R,en=Z,er=T,eo=V,ei=z,eu=q,ea=B},2003:function(e,t,n){"use strict";n.d(t,{j:function(){return u}});var r=n(512);let o=e=>"boolean"==typeof e?`${e}`:0===e?"0":e,i=r.W,u=(e,t)=>n=>{var r;if((null==t?void 0:t.variants)==null)return i(e,null==n?void 0:n.class,null==n?void 0:n.className);let{variants:u,defaultVariants:a}=t,l=Object.keys(u).map(e=>{let t=null==n?void 0:n[e],r=null==a?void 0:a[e];if(null===t)return null;let i=o(t)||o(r);return u[e][i]}),s=n&&Object.entries(n).reduce((e,t)=>{let[n,r]=t;return void 0===r||(e[n]=r),e},{});return i(e,l,null==t?void 0:null===(r=t.compoundVariants)||void 0===r?void 0:r.reduce((e,t)=>{let{class:n,className:r,...o}=t;return Object.entries(o).every(e=>{let[t,n]=e;return Array.isArray(n)?n.includes({...a,...s}[t]):({...a,...s})[t]===n})?[...e,n,r]:e},[]),null==n?void 0:n.class,null==n?void 0:n.className)}}}]);
|