@rebasepro/studio 0.0.1-canary.eae7889 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/dist/{ApiExplorer-gMJt5JrS.js → ApiExplorer-DHVmWYfK.js} +13 -13
  2. package/dist/ApiExplorer-DHVmWYfK.js.map +1 -0
  3. package/dist/AuthSimulationSelector-CM488Eei.js +106 -0
  4. package/dist/AuthSimulationSelector-CM488Eei.js.map +1 -0
  5. package/dist/{JSEditor-D8nVp3Lp.js → JSEditor-CSHA0t_O.js} +2 -2
  6. package/dist/{JSEditor-D8nVp3Lp.js.map → JSEditor-CSHA0t_O.js.map} +1 -1
  7. package/dist/{RLSEditor-DBH09u9v.js → RLSEditor-BzDjqo6w.js} +46 -5
  8. package/dist/RLSEditor-BzDjqo6w.js.map +1 -0
  9. package/dist/{SQLEditor-CkVx9vgr.js → SQLEditor-Cr9Kg_Qg.js} +63 -75
  10. package/dist/SQLEditor-Cr9Kg_Qg.js.map +1 -0
  11. package/dist/{SchemaVisualizer-BgD5Zb77.js → SchemaVisualizer-BGpmzyXT.js} +5 -5
  12. package/dist/SchemaVisualizer-BGpmzyXT.js.map +1 -0
  13. package/dist/StorageView-BYoslzBR.js +870 -0
  14. package/dist/StorageView-BYoslzBR.js.map +1 -0
  15. package/dist/core/src/components/BootstrapAdminBanner.d.ts +4 -0
  16. package/dist/core/src/components/LoginView/LoginView.d.ts +22 -0
  17. package/dist/core/src/components/common/useDataTableController.d.ts +3 -3
  18. package/dist/core/src/components/index.d.ts +1 -0
  19. package/dist/core/src/hooks/data/useRelationSelector.d.ts +2 -2
  20. package/dist/core/src/hooks/index.d.ts +1 -0
  21. package/dist/core/src/hooks/useCollapsedGroups.d.ts +16 -1
  22. package/dist/core/src/hooks/useResolvedComponent.d.ts +47 -0
  23. package/dist/index.es.js +79 -71
  24. package/dist/index.es.js.map +1 -1
  25. package/dist/index.umd.js +821 -834
  26. package/dist/index.umd.js.map +1 -1
  27. package/dist/types/src/controllers/auth.d.ts +8 -2
  28. package/dist/types/src/controllers/client.d.ts +13 -0
  29. package/dist/types/src/controllers/collection_registry.d.ts +2 -1
  30. package/dist/types/src/controllers/data_driver.d.ts +36 -1
  31. package/dist/types/src/controllers/navigation.d.ts +18 -6
  32. package/dist/types/src/controllers/registry.d.ts +9 -1
  33. package/dist/types/src/controllers/side_entity_controller.d.ts +7 -0
  34. package/dist/types/src/rebase_context.d.ts +17 -0
  35. package/dist/types/src/types/backend_hooks.d.ts +187 -0
  36. package/dist/types/src/types/collections.d.ts +31 -11
  37. package/dist/types/src/types/component_ref.d.ts +47 -0
  38. package/dist/types/src/types/cron.d.ts +1 -1
  39. package/dist/types/src/types/entity_views.d.ts +6 -7
  40. package/dist/types/src/types/formex.d.ts +40 -0
  41. package/dist/types/src/types/index.d.ts +3 -0
  42. package/dist/types/src/types/plugins.d.ts +6 -3
  43. package/dist/types/src/types/properties.d.ts +72 -88
  44. package/dist/types/src/types/slots.d.ts +20 -10
  45. package/dist/types/src/types/translations.d.ts +6 -0
  46. package/dist/ui/src/components/FileUpload.d.ts +1 -1
  47. package/dist/ui/src/components/SearchBar.d.ts +5 -1
  48. package/dist/ui/src/styles.d.ts +2 -2
  49. package/package.json +10 -10
  50. package/src/components/ApiExplorer/ApiExplorer.tsx +7 -5
  51. package/src/components/ApiExplorer/TryItPanel.tsx +29 -53
  52. package/src/components/AuthSimulationSelector.tsx +13 -17
  53. package/src/components/RLSEditor/RLSEditor.tsx +82 -3
  54. package/src/components/SQLEditor/SQLEditor.tsx +16 -18
  55. package/src/components/SQLEditor/SchemaBrowser.tsx +6 -8
  56. package/src/components/SchemaVisualizer/SchemaVisualizer.tsx +20 -22
  57. package/src/components/StorageView/StorageView.tsx +719 -304
  58. package/src/components/StudioHomePage.tsx +4 -1
  59. package/dist/ApiExplorer-gMJt5JrS.js.map +0 -1
  60. package/dist/AuthSimulationSelector-BF4rkRGp.js +0 -118
  61. package/dist/AuthSimulationSelector-BF4rkRGp.js.map +0 -1
  62. package/dist/RLSEditor-DBH09u9v.js.map +0 -1
  63. package/dist/SQLEditor-CkVx9vgr.js.map +0 -1
  64. package/dist/SchemaVisualizer-BgD5Zb77.js.map +0 -1
  65. package/dist/StorageView-CTqGFhY9.js +0 -907
  66. package/dist/StorageView-CTqGFhY9.js.map +0 -1
@@ -1,907 +0,0 @@
1
- import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
- import { c } from "react-compiler-runtime";
3
- import React, { useState, useEffect, useCallback } from "react";
4
- import { ResizablePanels, Tooltip, IconButton, iconSize, Typography, Button, cls, Chip, defaultBorderMixin, CircularProgress, DialogContent, Dialog, FileUpload, DialogActions } from "@rebasepro/ui";
5
- import { ArrowLeftIcon, LayoutGridIcon, ListIcon, RefreshCwIcon, UploadCloudIcon, PlusIcon, FolderIcon, DownloadIcon, Trash2Icon, XIcon, HomeIcon, FileTextIcon, ImageIcon, VideoIcon, Music2Icon } from "lucide-react";
6
- import { useStorageSource, useSnackbarController, ErrorView } from "@rebasepro/core";
7
- function formatFileSize(bytes) {
8
- if (bytes < 1024) return `${bytes} B`;
9
- if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
10
- if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
11
- return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`;
12
- }
13
- function getFileIcon(contentType) {
14
- if (!contentType) return FileTextIcon;
15
- if (contentType.startsWith("image/")) return ImageIcon;
16
- if (contentType.startsWith("video/")) return VideoIcon;
17
- if (contentType.startsWith("audio/")) return Music2Icon;
18
- return FileTextIcon;
19
- }
20
- function getExtension(name) {
21
- const parts = name.split(".");
22
- return parts.length > 1 ? parts[parts.length - 1].toUpperCase() : "";
23
- }
24
- function breadcrumbSegments(path) {
25
- if (!path || path === "/") return [{
26
- label: "Root",
27
- path: ""
28
- }];
29
- const parts = path.split("/").filter(Boolean);
30
- const segments = [{
31
- label: "Root",
32
- path: ""
33
- }];
34
- let accumulated = "";
35
- for (const part of parts) {
36
- accumulated = accumulated ? `${accumulated}/${part}` : part;
37
- segments.push({
38
- label: part,
39
- path: accumulated
40
- });
41
- }
42
- return segments;
43
- }
44
- function UploadDialog({
45
- open,
46
- currentPath,
47
- onClose,
48
- onUpload
49
- }) {
50
- const [uploading, setUploading] = useState(false);
51
- const [selectedFiles, setSelectedFiles] = useState([]);
52
- const [error, setError] = useState(null);
53
- const handleFilesAdded = useCallback((files) => {
54
- setSelectedFiles((prev) => [...prev, ...files]);
55
- }, []);
56
- const handleRemoveFile = useCallback((index) => {
57
- setSelectedFiles((prev_0) => prev_0.filter((_, i) => i !== index));
58
- }, []);
59
- const handleUpload = useCallback(async () => {
60
- if (selectedFiles.length === 0) return;
61
- setUploading(true);
62
- setError(null);
63
- try {
64
- await onUpload(selectedFiles);
65
- setSelectedFiles([]);
66
- onClose();
67
- } catch (err) {
68
- setError(err instanceof Error ? err.message : "Upload failed");
69
- } finally {
70
- setUploading(false);
71
- }
72
- }, [selectedFiles, onUpload, onClose]);
73
- const handleClose = useCallback(() => {
74
- if (!uploading) {
75
- setSelectedFiles([]);
76
- setError(null);
77
- onClose();
78
- }
79
- }, [uploading, onClose]);
80
- return /* @__PURE__ */ jsxs(Dialog, { open, onOpenChange: (o) => !o && handleClose(), maxWidth: "md", children: [
81
- /* @__PURE__ */ jsxs(DialogContent, { className: "p-0", children: [
82
- /* @__PURE__ */ jsxs("div", { className: "p-4 border-b border-surface-accent-200 dark:border-surface-accent-700", children: [
83
- /* @__PURE__ */ jsx(Typography, { variant: "h6", children: "Upload Files" }),
84
- /* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-text-secondary dark:text-text-secondary-dark mt-1 block", children: [
85
- "to ",
86
- /* @__PURE__ */ jsxs("span", { className: "font-mono text-primary", children: [
87
- "/",
88
- currentPath || "root"
89
- ] })
90
- ] })
91
- ] }),
92
- /* @__PURE__ */ jsxs("div", { className: "p-4", children: [
93
- /* @__PURE__ */ jsx(FileUpload, { accept: {}, onFilesAdded: handleFilesAdded, size: "large", uploadDescription: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center justify-center pointer-events-none mt-2", children: [
94
- /* @__PURE__ */ jsx(UploadCloudIcon, { className: "text-surface-accent-400 mb-2 w-8 h-8" }),
95
- /* @__PURE__ */ jsx(Typography, { variant: "h6", className: "font-bold", children: "Drop files here or click to browse" }),
96
- /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-surface-accent-500 font-medium", children: "Any file type supported" })
97
- ] }) }),
98
- error && /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-red-500 mt-2 block whitespace-pre-line", children: error }),
99
- selectedFiles.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mt-4 space-y-2", children: [
100
- /* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-surface-accent-500", children: [
101
- "Selected files (",
102
- selectedFiles.length,
103
- ")"
104
- ] }),
105
- /* @__PURE__ */ jsx("div", { className: "max-h-40 overflow-auto space-y-1", children: selectedFiles.map((file, index_0) => /* @__PURE__ */ jsxs("div", { className: cls("flex items-center justify-between p-2 rounded", "bg-surface-accent-50 dark:bg-surface-accent-800"), children: [
106
- /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0 mr-2", children: [
107
- /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "truncate", children: file.name }),
108
- /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-surface-accent-500", children: formatFileSize(file.size) })
109
- ] }),
110
- /* @__PURE__ */ jsx(Button, { variant: "text", size: "small", onClick: (e) => {
111
- e.stopPropagation();
112
- handleRemoveFile(index_0);
113
- }, disabled: uploading, children: "Remove" })
114
- ] }, `${file.name}-${index_0}`)) })
115
- ] })
116
- ] })
117
- ] }),
118
- /* @__PURE__ */ jsxs(DialogActions, { children: [
119
- /* @__PURE__ */ jsx(Button, { variant: "text", onClick: handleClose, disabled: uploading, children: "Cancel" }),
120
- /* @__PURE__ */ jsx(Button, { variant: "filled", onClick: handleUpload, disabled: selectedFiles.length === 0 || uploading, children: uploading ? /* @__PURE__ */ jsxs(Fragment, { children: [
121
- /* @__PURE__ */ jsx(CircularProgress, { size: "smallest" }),
122
- "Uploading..."
123
- ] }) : `Upload ${selectedFiles.length > 0 ? `(${selectedFiles.length})` : ""}` })
124
- ] })
125
- ] });
126
- }
127
- function FilePreviewPanel(t0) {
128
- const $ = c(79);
129
- const {
130
- file,
131
- onClose,
132
- onDelete,
133
- downloadUrl
134
- } = t0;
135
- file.contentType?.startsWith("image/");
136
- file.contentType?.startsWith("video/");
137
- file.contentType?.startsWith("audio/");
138
- let t1;
139
- if ($[0] !== file.contentType) {
140
- t1 = getFileIcon(file.contentType);
141
- $[0] = file.contentType;
142
- $[1] = t1;
143
- } else {
144
- t1 = $[1];
145
- }
146
- const FileIconComponent = t1;
147
- const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
148
- let t2;
149
- let t3;
150
- if ($[2] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
151
- t2 = cls("flex flex-col h-full border-l", defaultBorderMixin, "bg-white dark:bg-surface-950");
152
- t3 = cls("flex items-center justify-between p-3 border-b shrink-0", defaultBorderMixin);
153
- $[2] = t2;
154
- $[3] = t3;
155
- } else {
156
- t2 = $[2];
157
- t3 = $[3];
158
- }
159
- let t4;
160
- if ($[4] !== file.name) {
161
- t4 = /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "font-medium truncate flex-1 mr-2", children: file.name });
162
- $[4] = file.name;
163
- $[5] = t4;
164
- } else {
165
- t4 = $[5];
166
- }
167
- let t5;
168
- if ($[6] !== downloadUrl) {
169
- t5 = downloadUrl && /* @__PURE__ */ jsx(Tooltip, { title: "Download", children: /* @__PURE__ */ jsx(IconButton, { size: "small", onClick: () => window.open(downloadUrl, "_blank"), children: /* @__PURE__ */ jsx(DownloadIcon, { size: iconSize.smallest }) }) });
170
- $[6] = downloadUrl;
171
- $[7] = t5;
172
- } else {
173
- t5 = $[7];
174
- }
175
- let t6;
176
- if ($[8] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
177
- t6 = () => setDeleteDialogOpen(true);
178
- $[8] = t6;
179
- } else {
180
- t6 = $[8];
181
- }
182
- let t7;
183
- if ($[9] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
184
- t7 = /* @__PURE__ */ jsx(Tooltip, { title: "Delete", children: /* @__PURE__ */ jsx(IconButton, { size: "small", onClick: t6, className: "text-red-500 hover:bg-red-50 dark:hover:bg-red-900/20", children: /* @__PURE__ */ jsx(Trash2Icon, { size: iconSize.smallest }) }) });
185
- $[9] = t7;
186
- } else {
187
- t7 = $[9];
188
- }
189
- let t8;
190
- if ($[10] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
191
- t8 = /* @__PURE__ */ jsx(XIcon, { size: iconSize.smallest });
192
- $[10] = t8;
193
- } else {
194
- t8 = $[10];
195
- }
196
- let t9;
197
- if ($[11] !== onClose) {
198
- t9 = /* @__PURE__ */ jsx(IconButton, { size: "small", onClick: onClose, children: t8 });
199
- $[11] = onClose;
200
- $[12] = t9;
201
- } else {
202
- t9 = $[12];
203
- }
204
- let t10;
205
- if ($[13] !== t5 || $[14] !== t9) {
206
- t10 = /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-0.5", children: [
207
- t5,
208
- t7,
209
- t9
210
- ] });
211
- $[13] = t5;
212
- $[14] = t9;
213
- $[15] = t10;
214
- } else {
215
- t10 = $[15];
216
- }
217
- let t11;
218
- if ($[16] !== t10 || $[17] !== t4) {
219
- t11 = /* @__PURE__ */ jsxs("div", { className: t3, children: [
220
- t4,
221
- t10
222
- ] });
223
- $[16] = t10;
224
- $[17] = t4;
225
- $[18] = t11;
226
- } else {
227
- t11 = $[18];
228
- }
229
- let t12;
230
- const ext = getExtension(file.name)?.toLowerCase() || "";
231
- const isImage_0 = file.contentType?.startsWith("image/") || ["jpg", "jpeg", "png", "gif", "webp", "svg"].includes(ext);
232
- const isVideo_0 = file.contentType?.startsWith("video/") || ["mp4", "webm", "ogg", "mov"].includes(ext);
233
- const isAudio_0 = file.contentType?.startsWith("audio/") || ["mp3", "wav", "ogg", "m4a"].includes(ext);
234
- const downloadUrl_0 = file.downloadUrl;
235
- if (isImage_0 && downloadUrl_0) {
236
- let t132;
237
- if ($[19] !== downloadUrl_0 || $[20] !== file.name) {
238
- t132 = /* @__PURE__ */ jsx("img", { src: downloadUrl_0, alt: file.name, className: "max-w-full max-h-[400px] object-contain rounded-md shadow-sm" });
239
- $[19] = downloadUrl_0;
240
- $[20] = file.name;
241
- $[21] = t132;
242
- } else {
243
- t132 = $[21];
244
- }
245
- t12 = t132;
246
- } else {
247
- if (isVideo_0 && downloadUrl_0) {
248
- let t132;
249
- if ($[22] !== downloadUrl_0) {
250
- t132 = /* @__PURE__ */ jsx("video", { src: downloadUrl_0, className: "max-w-full max-h-[400px] rounded-md", controls: true });
251
- $[22] = downloadUrl_0;
252
- $[23] = t132;
253
- } else {
254
- t132 = $[23];
255
- }
256
- t12 = t132;
257
- } else {
258
- if (isAudio_0 && downloadUrl_0) {
259
- let t132;
260
- if ($[24] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
261
- t132 = /* @__PURE__ */ jsx(Music2Icon, { className: "text-surface-accent-400 w-10 h-10" });
262
- $[24] = t132;
263
- } else {
264
- t132 = $[24];
265
- }
266
- let t142;
267
- if ($[25] !== downloadUrl_0) {
268
- t142 = /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-4", children: [
269
- t132,
270
- /* @__PURE__ */ jsx("audio", { src: downloadUrl_0, controls: true, className: "w-full max-w-xs" })
271
- ] });
272
- $[25] = downloadUrl_0;
273
- $[26] = t142;
274
- } else {
275
- t142 = $[26];
276
- }
277
- t12 = t142;
278
- } else {
279
- let t132;
280
- if ($[27] !== FileIconComponent) {
281
- t132 = /* @__PURE__ */ jsx(FileIconComponent, { className: "w-10 h-10" });
282
- $[27] = FileIconComponent;
283
- $[28] = t132;
284
- } else {
285
- t132 = $[28];
286
- }
287
- let t142;
288
- if ($[29] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
289
- t142 = /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-text-disabled dark:text-text-disabled-dark", children: "No preview available" });
290
- $[29] = t142;
291
- } else {
292
- t142 = $[29];
293
- }
294
- let t152;
295
- if ($[30] !== t132) {
296
- t152 = /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-3 text-surface-accent-400", children: [
297
- t132,
298
- t142
299
- ] });
300
- $[30] = t132;
301
- $[31] = t152;
302
- } else {
303
- t152 = $[31];
304
- }
305
- t12 = t152;
306
- }
307
- }
308
- }
309
- let t13;
310
- if ($[32] !== t12) {
311
- t13 = /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-auto", children: /* @__PURE__ */ jsx("div", { className: "flex flex-col items-center justify-center min-h-[200px] p-4 bg-surface-50 dark:bg-surface-900 border-b border-surface-accent-200 dark:border-surface-accent-700", children: t12 }) });
312
- $[32] = t12;
313
- $[33] = t13;
314
- } else {
315
- t13 = $[33];
316
- }
317
- let t14;
318
- if ($[34] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
319
- t14 = /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-text-disabled dark:text-text-disabled-dark text-[10px] uppercase tracking-wider font-bold mb-1 block", children: "File Info" }) });
320
- $[34] = t14;
321
- } else {
322
- t14 = $[34];
323
- }
324
- let t15;
325
- if ($[35] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
326
- t15 = /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-surface-accent-500 text-[11px]", children: "Name" });
327
- $[35] = t15;
328
- } else {
329
- t15 = $[35];
330
- }
331
- let t16;
332
- if ($[36] !== file.name) {
333
- t16 = /* @__PURE__ */ jsxs("div", { children: [
334
- t15,
335
- /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-[13px] break-all", children: file.name })
336
- ] });
337
- $[36] = file.name;
338
- $[37] = t16;
339
- } else {
340
- t16 = $[37];
341
- }
342
- let t17;
343
- if ($[38] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
344
- t17 = /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-surface-accent-500 text-[11px]", children: "Type" });
345
- $[38] = t17;
346
- } else {
347
- t17 = $[38];
348
- }
349
- const t18 = file.contentType || "Unknown";
350
- let t19;
351
- if ($[39] !== t18) {
352
- t19 = /* @__PURE__ */ jsxs("div", { children: [
353
- t17,
354
- /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-[13px]", children: t18 })
355
- ] });
356
- $[39] = t18;
357
- $[40] = t19;
358
- } else {
359
- t19 = $[40];
360
- }
361
- let t20;
362
- if ($[41] !== file.size) {
363
- t20 = file.size !== void 0 && /* @__PURE__ */ jsxs("div", { children: [
364
- /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-surface-accent-500 text-[11px]", children: "Size" }),
365
- /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-[13px]", children: formatFileSize(file.size) })
366
- ] });
367
- $[41] = file.size;
368
- $[42] = t20;
369
- } else {
370
- t20 = $[42];
371
- }
372
- let t21;
373
- if ($[43] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
374
- t21 = /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-surface-accent-500 text-[11px]", children: "Extension" });
375
- $[43] = t21;
376
- } else {
377
- t21 = $[43];
378
- }
379
- let t22;
380
- if ($[44] !== file.name) {
381
- t22 = getExtension(file.name) || "—";
382
- $[44] = file.name;
383
- $[45] = t22;
384
- } else {
385
- t22 = $[45];
386
- }
387
- let t23;
388
- if ($[46] !== t22) {
389
- t23 = /* @__PURE__ */ jsxs("div", { children: [
390
- t21,
391
- /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-[13px] font-mono", children: t22 })
392
- ] });
393
- $[46] = t22;
394
- $[47] = t23;
395
- } else {
396
- t23 = $[47];
397
- }
398
- let t24;
399
- if ($[48] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
400
- t24 = /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-surface-accent-500 text-[11px]", children: "Path" });
401
- $[48] = t24;
402
- } else {
403
- t24 = $[48];
404
- }
405
- let t25;
406
- if ($[49] !== file.fullPath) {
407
- t25 = /* @__PURE__ */ jsxs("div", { className: "col-span-2", children: [
408
- t24,
409
- /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-[13px] font-mono break-all", children: file.fullPath })
410
- ] });
411
- $[49] = file.fullPath;
412
- $[50] = t25;
413
- } else {
414
- t25 = $[50];
415
- }
416
- let t26;
417
- if ($[51] !== t16 || $[52] !== t19 || $[53] !== t20 || $[54] !== t23 || $[55] !== t25) {
418
- t26 = /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-3", children: [
419
- t16,
420
- t19,
421
- t20,
422
- t23,
423
- t25
424
- ] });
425
- $[51] = t16;
426
- $[52] = t19;
427
- $[53] = t20;
428
- $[54] = t23;
429
- $[55] = t25;
430
- $[56] = t26;
431
- } else {
432
- t26 = $[56];
433
- }
434
- let t27;
435
- if ($[57] !== downloadUrl) {
436
- t27 = downloadUrl && /* @__PURE__ */ jsxs("div", { className: "pt-2", children: [
437
- /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-surface-accent-500 text-[11px] block mb-1", children: "URL" }),
438
- /* @__PURE__ */ jsxs("div", { className: "p-2 rounded bg-surface-100 dark:bg-surface-950 cursor-pointer hover:bg-surface-200 dark:hover:bg-surface-700 transition-colors", onClick: () => {
439
- navigator.clipboard.writeText(downloadUrl);
440
- }, children: [
441
- /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "font-mono text-[11px] break-all text-primary", children: downloadUrl }),
442
- /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-text-disabled dark:text-text-disabled-dark text-[10px] block mt-1", children: "Click to copy" })
443
- ] })
444
- ] });
445
- $[57] = downloadUrl;
446
- $[58] = t27;
447
- } else {
448
- t27 = $[58];
449
- }
450
- let t28;
451
- if ($[59] !== t26 || $[60] !== t27) {
452
- t28 = /* @__PURE__ */ jsxs("div", { className: "p-4 space-y-3", children: [
453
- t14,
454
- t26,
455
- t27
456
- ] });
457
- $[59] = t26;
458
- $[60] = t27;
459
- $[61] = t28;
460
- } else {
461
- t28 = $[61];
462
- }
463
- let t29;
464
- if ($[62] !== t11 || $[63] !== t13 || $[64] !== t28) {
465
- t29 = /* @__PURE__ */ jsxs("div", { className: t2, children: [
466
- t11,
467
- t13,
468
- t28
469
- ] });
470
- $[62] = t11;
471
- $[63] = t13;
472
- $[64] = t28;
473
- $[65] = t29;
474
- } else {
475
- t29 = $[65];
476
- }
477
- let t30;
478
- if ($[66] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
479
- t30 = /* @__PURE__ */ jsx(Typography, { variant: "subtitle1", className: "mb-2", children: "Delete File?" });
480
- $[66] = t30;
481
- } else {
482
- t30 = $[66];
483
- }
484
- let t31;
485
- if ($[67] !== file.name) {
486
- t31 = /* @__PURE__ */ jsxs(DialogContent, { children: [
487
- t30,
488
- /* @__PURE__ */ jsxs(Typography, { className: "text-surface-accent-600 dark:text-surface-accent-400", children: [
489
- 'Are you sure you want to delete "',
490
- file.name,
491
- '"? This action cannot be undone.'
492
- ] })
493
- ] });
494
- $[67] = file.name;
495
- $[68] = t31;
496
- } else {
497
- t31 = $[68];
498
- }
499
- let t32;
500
- if ($[69] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
501
- t32 = /* @__PURE__ */ jsx(Button, { variant: "text", onClick: () => setDeleteDialogOpen(false), children: "Cancel" });
502
- $[69] = t32;
503
- } else {
504
- t32 = $[69];
505
- }
506
- let t33;
507
- if ($[70] !== onDelete) {
508
- t33 = /* @__PURE__ */ jsxs(DialogActions, { children: [
509
- t32,
510
- /* @__PURE__ */ jsx(Button, { variant: "filled", color: "error", onClick: () => {
511
- setDeleteDialogOpen(false);
512
- onDelete();
513
- }, children: "Delete" })
514
- ] });
515
- $[70] = onDelete;
516
- $[71] = t33;
517
- } else {
518
- t33 = $[71];
519
- }
520
- let t34;
521
- if ($[72] !== deleteDialogOpen || $[73] !== t31 || $[74] !== t33) {
522
- t34 = /* @__PURE__ */ jsxs(Dialog, { open: deleteDialogOpen, onOpenChange: setDeleteDialogOpen, children: [
523
- t31,
524
- t33
525
- ] });
526
- $[72] = deleteDialogOpen;
527
- $[73] = t31;
528
- $[74] = t33;
529
- $[75] = t34;
530
- } else {
531
- t34 = $[75];
532
- }
533
- let t35;
534
- if ($[76] !== t29 || $[77] !== t34) {
535
- t35 = /* @__PURE__ */ jsxs(Fragment, { children: [
536
- t29,
537
- t34
538
- ] });
539
- $[76] = t29;
540
- $[77] = t34;
541
- $[78] = t35;
542
- } else {
543
- t35 = $[78];
544
- }
545
- return t35;
546
- }
547
- function StorageSidebar(t0) {
548
- const $ = c(19);
549
- const {
550
- folders,
551
- currentPath,
552
- onNavigate,
553
- loading
554
- } = t0;
555
- breadcrumbSegments(currentPath);
556
- let t1;
557
- let t2;
558
- if ($[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
559
- t1 = cls("flex flex-col h-full w-full bg-white dark:bg-surface-950 border-r", defaultBorderMixin);
560
- t2 = /* @__PURE__ */ jsx("div", { className: cls("p-3 border-b flex justify-between items-center bg-surface-50 dark:bg-surface-900 shrink-0", defaultBorderMixin), children: /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "font-bold uppercase tracking-wider text-text-disabled dark:text-text-disabled-dark", children: "Folders" }) });
561
- $[0] = t1;
562
- $[1] = t2;
563
- } else {
564
- t1 = $[0];
565
- t2 = $[1];
566
- }
567
- const t3 = currentPath === "" || !currentPath ? "bg-primary/10 text-primary dark:bg-primary/20 dark:text-primary-light" : "hover:bg-surface-100 dark:hover:bg-surface-950 text-text-secondary dark:text-text-secondary-dark";
568
- let t4;
569
- if ($[2] !== t3) {
570
- t4 = cls("flex items-center p-1.5 cursor-pointer rounded transition-colors", t3);
571
- $[2] = t3;
572
- $[3] = t4;
573
- } else {
574
- t4 = $[3];
575
- }
576
- let t5;
577
- if ($[4] !== onNavigate) {
578
- t5 = () => onNavigate("");
579
- $[4] = onNavigate;
580
- $[5] = t5;
581
- } else {
582
- t5 = $[5];
583
- }
584
- let t6;
585
- let t7;
586
- if ($[6] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
587
- t6 = /* @__PURE__ */ jsx(HomeIcon, { size: iconSize.smallest, className: "mr-1.5 shrink-0" });
588
- t7 = /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-xs truncate", children: "Root" });
589
- $[6] = t6;
590
- $[7] = t7;
591
- } else {
592
- t6 = $[6];
593
- t7 = $[7];
594
- }
595
- let t8;
596
- if ($[8] !== t4 || $[9] !== t5) {
597
- t8 = /* @__PURE__ */ jsxs("div", { className: t4, onClick: t5, children: [
598
- t6,
599
- t7
600
- ] });
601
- $[8] = t4;
602
- $[9] = t5;
603
- $[10] = t8;
604
- } else {
605
- t8 = $[10];
606
- }
607
- let t9;
608
- if ($[11] !== currentPath || $[12] !== folders || $[13] !== loading || $[14] !== onNavigate) {
609
- t9 = loading && folders.length === 0 ? /* @__PURE__ */ jsx("div", { className: "flex justify-center p-4", children: /* @__PURE__ */ jsx(CircularProgress, { size: "small" }) }) : /* @__PURE__ */ jsx("div", { className: "mt-1 space-y-0.5", children: folders.map((folder) => {
610
- const isSelected = currentPath === folder.fullPath;
611
- return /* @__PURE__ */ jsxs("div", { className: cls("flex items-center p-1.5 cursor-pointer rounded transition-colors group", isSelected ? "bg-primary/10 text-primary dark:bg-primary/20 dark:text-primary-light" : "hover:bg-surface-100 dark:hover:bg-surface-950 text-text-secondary dark:text-text-secondary-dark"), onClick: () => onNavigate(folder.fullPath), children: [
612
- /* @__PURE__ */ jsx(FolderIcon, { size: iconSize.smallest, className: "mr-1.5 shrink-0 text-amber-500 dark:text-amber-400" }),
613
- /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-xs truncate flex-1 min-w-0", children: folder.name })
614
- ] }, folder.fullPath);
615
- }) });
616
- $[11] = currentPath;
617
- $[12] = folders;
618
- $[13] = loading;
619
- $[14] = onNavigate;
620
- $[15] = t9;
621
- } else {
622
- t9 = $[15];
623
- }
624
- let t10;
625
- if ($[16] !== t8 || $[17] !== t9) {
626
- t10 = /* @__PURE__ */ jsxs("div", { className: t1, children: [
627
- t2,
628
- /* @__PURE__ */ jsxs("div", { className: "flex-grow overflow-y-auto no-scrollbar p-1", children: [
629
- t8,
630
- t9
631
- ] })
632
- ] });
633
- $[16] = t8;
634
- $[17] = t9;
635
- $[18] = t10;
636
- } else {
637
- t10 = $[18];
638
- }
639
- return t10;
640
- }
641
- const StorageView = () => {
642
- const storageSource = useStorageSource();
643
- const snackbarController = useSnackbarController();
644
- const [currentPath, setCurrentPath] = useState("");
645
- const [loading, setLoading] = useState(true);
646
- const [error, setError] = useState(null);
647
- const [folders, setFolders] = useState([]);
648
- const [files, setFiles] = useState([]);
649
- const [selectedFile, setSelectedFile] = useState(null);
650
- const [selectedDownloadUrl, setSelectedDownloadUrl] = useState(null);
651
- const [uploadDialogOpen, setUploadDialogOpen] = useState(false);
652
- const [viewMode, setViewMode] = useState("grid");
653
- const [sidebarSize, setSidebarSize] = useState(() => {
654
- try {
655
- const saved = localStorage.getItem("rebase_storage_sidebar_size");
656
- return saved !== null ? parseFloat(saved) : 18;
657
- } catch {
658
- return 18;
659
- }
660
- });
661
- useEffect(() => {
662
- try {
663
- localStorage.setItem("rebase_storage_sidebar_size", sidebarSize.toString());
664
- } catch {
665
- }
666
- }, [sidebarSize]);
667
- const fetchContents = useCallback(async (path) => {
668
- setLoading(true);
669
- setError(null);
670
- try {
671
- const result = await storageSource.listObjects(path);
672
- const folderItems = (result.prefixes ?? []).map((ref) => ({
673
- name: ref.name,
674
- fullPath: ref.fullPath,
675
- isFolder: true
676
- }));
677
- const fileItems = await Promise.all((result.items ?? []).map(async (ref_0) => {
678
- try {
679
- const downloadConfig = await storageSource.getSignedUrl(ref_0.fullPath);
680
- return {
681
- name: ref_0.name,
682
- fullPath: ref_0.fullPath,
683
- isFolder: false,
684
- size: downloadConfig.metadata?.size,
685
- contentType: downloadConfig.metadata?.contentType,
686
- downloadUrl: downloadConfig.url ?? void 0
687
- };
688
- } catch {
689
- return {
690
- name: ref_0.name,
691
- fullPath: ref_0.fullPath,
692
- isFolder: false
693
- };
694
- }
695
- }));
696
- setFolders(folderItems);
697
- setFiles(fileItems);
698
- } catch (e) {
699
- console.error("Storage list error:", e);
700
- setError(e instanceof Error ? e.message : String(e));
701
- } finally {
702
- setLoading(false);
703
- }
704
- }, [storageSource]);
705
- useEffect(() => {
706
- fetchContents(currentPath);
707
- }, [currentPath, fetchContents]);
708
- const handleNavigate = useCallback((path_0) => {
709
- setCurrentPath(path_0);
710
- setSelectedFile(null);
711
- setSelectedDownloadUrl(null);
712
- }, []);
713
- const handleNavigateUp = useCallback(() => {
714
- const parts = currentPath.split("/").filter(Boolean);
715
- parts.pop();
716
- handleNavigate(parts.join("/"));
717
- }, [currentPath, handleNavigate]);
718
- const handleSelectFile = useCallback(async (file) => {
719
- setSelectedFile(file);
720
- if (file.downloadUrl) {
721
- setSelectedDownloadUrl(file.downloadUrl);
722
- } else {
723
- try {
724
- const config = await storageSource.getSignedUrl(file.fullPath);
725
- setSelectedDownloadUrl(config.url);
726
- } catch {
727
- setSelectedDownloadUrl(null);
728
- }
729
- }
730
- }, [storageSource]);
731
- const handleUpload = useCallback(async (uploadFiles) => {
732
- for (const file_0 of uploadFiles) {
733
- const key = currentPath ? `${currentPath}/${file_0.name}` : file_0.name;
734
- await storageSource.putObject({
735
- file: file_0,
736
- key
737
- });
738
- }
739
- snackbarController.open({
740
- type: "success",
741
- message: `${uploadFiles.length} file${uploadFiles.length > 1 ? "s" : ""} uploaded successfully`
742
- });
743
- fetchContents(currentPath);
744
- }, [storageSource, currentPath, snackbarController, fetchContents]);
745
- const handleDeleteFile = useCallback(async (file_1) => {
746
- try {
747
- await storageSource.deleteObject(file_1.fullPath);
748
- snackbarController.open({
749
- type: "success",
750
- message: `"${file_1.name}" deleted`
751
- });
752
- setSelectedFile(null);
753
- setSelectedDownloadUrl(null);
754
- fetchContents(currentPath);
755
- } catch (e_0) {
756
- snackbarController.open({
757
- type: "error",
758
- message: e_0 instanceof Error ? e_0.message : String(e_0)
759
- });
760
- }
761
- }, [storageSource, currentPath, snackbarController, fetchContents]);
762
- const handleRefresh = useCallback(() => {
763
- fetchContents(currentPath);
764
- }, [currentPath, fetchContents]);
765
- const segments = breadcrumbSegments(currentPath);
766
- const renderContents = () => {
767
- if (loading) {
768
- return /* @__PURE__ */ jsx("div", { className: "flex-grow flex items-center justify-center", children: /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
769
- /* @__PURE__ */ jsx(CircularProgress, { size: "medium" }),
770
- /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "mt-4 text-text-secondary dark:text-text-secondary-dark font-mono tracking-tight animate-pulse", children: "Loading..." })
771
- ] }) });
772
- }
773
- if (error) {
774
- return /* @__PURE__ */ jsx("div", { className: "flex-grow flex items-center justify-center p-6 overflow-auto", children: /* @__PURE__ */ jsx(ErrorView, { title: "Error loading storage", error, onRetry: handleRefresh }) });
775
- }
776
- const allItems = [...folders, ...files];
777
- if (allItems.length === 0) {
778
- return /* @__PURE__ */ jsx("div", { className: "flex-grow flex items-center justify-center text-text-disabled dark:text-text-disabled-dark", children: /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
779
- /* @__PURE__ */ jsx("svg", { className: "w-12 h-12 mx-auto mb-4 opacity-50", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1, d: "M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z" }) }),
780
- /* @__PURE__ */ jsx(Typography, { variant: "body2", children: "This folder is empty" }),
781
- /* @__PURE__ */ jsxs(Button, { className: "mt-3", onClick: () => setUploadDialogOpen(true), children: [
782
- /* @__PURE__ */ jsx(PlusIcon, { size: iconSize.smallest }),
783
- "Upload files"
784
- ] })
785
- ] }) });
786
- }
787
- if (viewMode === "list") {
788
- return /* @__PURE__ */ jsx("div", { className: "flex-grow overflow-auto", children: /* @__PURE__ */ jsxs("table", { className: "w-full", children: [
789
- /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { className: cls("border-b text-left text-[10px] uppercase tracking-wider text-text-disabled dark:text-text-disabled-dark", defaultBorderMixin), children: [
790
- /* @__PURE__ */ jsx("th", { className: "px-4 py-2 font-bold", children: "Name" }),
791
- /* @__PURE__ */ jsx("th", { className: "px-4 py-2 font-bold w-24", children: "Type" }),
792
- /* @__PURE__ */ jsx("th", { className: "px-4 py-2 font-bold w-24 text-right", children: "Size" })
793
- ] }) }),
794
- /* @__PURE__ */ jsxs("tbody", { children: [
795
- folders.map((folder) => /* @__PURE__ */ jsxs("tr", { className: "hover:bg-surface-100 dark:hover:bg-surface-950 cursor-pointer transition-colors border-b border-surface-100 dark:border-surface-950/50", onClick: () => handleNavigate(folder.fullPath), children: [
796
- /* @__PURE__ */ jsx("td", { className: "px-4 py-2.5", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
797
- /* @__PURE__ */ jsx(FolderIcon, { size: iconSize.smallest, className: "text-amber-500 dark:text-amber-400 shrink-0" }),
798
- /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-[13px] font-medium truncate", children: folder.name })
799
- ] }) }),
800
- /* @__PURE__ */ jsx("td", { className: "px-4 py-2.5", children: /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-text-secondary dark:text-text-secondary-dark", children: "Folder" }) }),
801
- /* @__PURE__ */ jsx("td", { className: "px-4 py-2.5 text-right", children: /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-text-disabled dark:text-text-disabled-dark", children: "—" }) })
802
- ] }, folder.fullPath)),
803
- files.map((file_2) => {
804
- const FileIconComp = getFileIcon(file_2.contentType);
805
- const isSelected = selectedFile?.fullPath === file_2.fullPath;
806
- return /* @__PURE__ */ jsxs("tr", { className: cls("cursor-pointer transition-colors border-b border-surface-100 dark:border-surface-950/50", isSelected ? "bg-primary/5 dark:bg-primary/10" : "hover:bg-surface-100 dark:hover:bg-surface-950"), onClick: () => handleSelectFile(file_2), children: [
807
- /* @__PURE__ */ jsx("td", { className: "px-4 py-2.5", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
808
- /* @__PURE__ */ jsx(FileIconComp, { size: iconSize.smallest, className: "text-surface-accent-400 shrink-0" }),
809
- /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-[13px] truncate", children: file_2.name })
810
- ] }) }),
811
- /* @__PURE__ */ jsx("td", { className: "px-4 py-2.5", children: /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-text-secondary dark:text-text-secondary-dark", children: getExtension(file_2.name) || file_2.contentType?.split("/")[1]?.toUpperCase() || "—" }) }),
812
- /* @__PURE__ */ jsx("td", { className: "px-4 py-2.5 text-right", children: /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-text-secondary dark:text-text-secondary-dark font-mono text-[11px]", children: file_2.size !== void 0 ? formatFileSize(file_2.size) : "—" }) })
813
- ] }, file_2.fullPath);
814
- })
815
- ] })
816
- ] }) });
817
- }
818
- return /* @__PURE__ */ jsxs("div", { className: "flex-grow overflow-auto p-4", children: [
819
- folders.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
820
- /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-[10px] uppercase tracking-wider font-bold text-text-disabled dark:text-text-disabled-dark mb-2 block", children: "Folders" }),
821
- /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 gap-3", children: folders.map((folder_0) => /* @__PURE__ */ jsxs("div", { className: cls("rounded-lg p-3 cursor-pointer transition-all duration-150 border", defaultBorderMixin, "hover:bg-surface-100 dark:hover:bg-surface-950 hover:shadow-sm", "flex items-center gap-2"), onClick: () => handleNavigate(folder_0.fullPath), children: [
822
- /* @__PURE__ */ jsx(FolderIcon, { size: iconSize.smallest, className: "text-amber-500 dark:text-amber-400 shrink-0" }),
823
- /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-[13px] font-medium truncate", children: folder_0.name })
824
- ] }, folder_0.fullPath)) })
825
- ] }),
826
- files.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
827
- /* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-[10px] uppercase tracking-wider font-bold text-text-disabled dark:text-text-disabled-dark mb-2 block", children: [
828
- "Files (",
829
- files.length,
830
- ")"
831
- ] }),
832
- /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 gap-3", children: files.map((file_3) => {
833
- const FileIconComp_0 = getFileIcon(file_3.contentType);
834
- const ext = getExtension(file_3.name)?.toLowerCase() || "";
835
- const isImage = file_3.contentType?.startsWith("image/") || ["jpg", "jpeg", "png", "gif", "webp", "svg"].includes(ext);
836
- const isSelected_0 = selectedFile?.fullPath === file_3.fullPath;
837
- return /* @__PURE__ */ jsxs("div", { className: cls("rounded-lg overflow-hidden cursor-pointer transition-all duration-150 border group", defaultBorderMixin, "hover:shadow-md hover:-translate-y-0.5", isSelected_0 && "ring-2 ring-primary"), onClick: () => handleSelectFile(file_3), children: [
838
- /* @__PURE__ */ jsxs("div", { className: "aspect-square relative overflow-hidden bg-surface-100 dark:bg-surface-950 flex items-center justify-center", children: [
839
- isImage && file_3.downloadUrl ? /* @__PURE__ */ jsx("img", { src: file_3.downloadUrl, alt: file_3.name, className: "w-full h-full object-cover transition-transform duration-200 group-hover:scale-105", loading: "lazy" }) : /* @__PURE__ */ jsx(FileIconComp_0, { className: "text-surface-accent-400 dark:text-surface-accent-500 w-8 h-8" }),
840
- getExtension(file_3.name) && /* @__PURE__ */ jsx("div", { className: "absolute bottom-1.5 right-1.5 px-1.5 py-0.5 rounded text-[9px] font-bold uppercase bg-black/50 text-white backdrop-blur-sm", children: getExtension(file_3.name) }),
841
- /* @__PURE__ */ jsx("div", { className: cls("absolute inset-0 bg-black/0 group-hover:bg-black/10", "transition-colors duration-200") })
842
- ] }),
843
- /* @__PURE__ */ jsxs("div", { className: "p-2.5", children: [
844
- /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-[12px] font-medium truncate text-surface-900 dark:text-white", children: file_3.name }),
845
- /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", className: "truncate block mt-0.5 text-[11px]", children: file_3.size !== void 0 ? formatFileSize(file_3.size) : "—" })
846
- ] })
847
- ] }, file_3.fullPath);
848
- }) })
849
- ] })
850
- ] });
851
- };
852
- return /* @__PURE__ */ jsxs("div", { className: "flex h-full w-full bg-white dark:bg-surface-950 overflow-hidden text-text-primary dark:text-text-primary-dark", children: [
853
- /* @__PURE__ */ jsx(ResizablePanels, { orientation: "horizontal", panelSizePercent: sidebarSize, onPanelSizeChange: setSidebarSize, minPanelSizePx: 180, firstPanel: /* @__PURE__ */ jsx(StorageSidebar, { folders, currentPath, onNavigate: handleNavigate, loading }), secondPanel: /* @__PURE__ */ jsxs("div", { className: "flex h-full w-full", children: [
854
- /* @__PURE__ */ jsxs("div", { className: "flex-grow flex flex-col min-w-0 h-full", children: [
855
- /* @__PURE__ */ jsxs("div", { className: cls("flex items-center justify-between pr-2 border-b bg-white dark:bg-surface-950 shrink-0", defaultBorderMixin), children: [
856
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 flex-grow overflow-hidden px-3 py-2", children: [
857
- currentPath && /* @__PURE__ */ jsx(Tooltip, { title: "Go up", children: /* @__PURE__ */ jsx(IconButton, { size: "small", onClick: handleNavigateUp, children: /* @__PURE__ */ jsx(ArrowLeftIcon, { size: iconSize.smallest }) }) }),
858
- /* @__PURE__ */ jsx("div", { className: "flex items-center gap-0.5 overflow-x-auto no-scrollbar", children: segments.map((seg, i) => /* @__PURE__ */ jsxs(React.Fragment, { children: [
859
- i > 0 && /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-text-disabled dark:text-text-disabled-dark mx-0.5", children: "/" }),
860
- /* @__PURE__ */ jsx(Button, { variant: "text", size: "small", className: cls("px-1.5 py-0.5 min-h-0 min-w-0 h-6 text-xs whitespace-nowrap normal-case font-normal", i === segments.length - 1 ? "text-text-primary dark:text-text-primary-dark font-medium" : "text-text-secondary dark:text-text-secondary-dark"), onClick: () => handleNavigate(seg.path), children: seg.label })
861
- ] }, seg.path)) }),
862
- /* @__PURE__ */ jsx("div", { className: "flex-1" }),
863
- !loading && /* @__PURE__ */ jsxs(Chip, { size: "small", className: "shrink-0 text-[10px]", children: [
864
- files.length,
865
- " file",
866
- files.length !== 1 ? "s" : "",
867
- folders.length > 0 ? `, ${folders.length} folder${folders.length !== 1 ? "s" : ""}` : ""
868
- ] })
869
- ] }),
870
- /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center justify-end gap-1.5 pr-1", children: [
871
- /* @__PURE__ */ jsx(Tooltip, { title: "Grid view", children: /* @__PURE__ */ jsx(IconButton, { size: "small", onClick: () => setViewMode("grid"), className: cls(viewMode === "grid" && "bg-surface-100 dark:bg-surface-950"), children: /* @__PURE__ */ jsx(LayoutGridIcon, { size: iconSize.smallest }) }) }),
872
- /* @__PURE__ */ jsx(Tooltip, { title: "List view", children: /* @__PURE__ */ jsx(IconButton, { size: "small", onClick: () => setViewMode("list"), className: cls(viewMode === "list" && "bg-surface-100 dark:bg-surface-950"), children: /* @__PURE__ */ jsx(ListIcon, { size: iconSize.smallest }) }) }),
873
- /* @__PURE__ */ jsx("div", { className: "h-4 w-px bg-surface-200 dark:bg-surface-950 mx-0.5" }),
874
- /* @__PURE__ */ jsx(Tooltip, { title: "Refresh", children: /* @__PURE__ */ jsx(IconButton, { size: "small", onClick: handleRefresh, disabled: loading, children: /* @__PURE__ */ jsx(RefreshCwIcon, { size: iconSize.smallest }) }) }),
875
- /* @__PURE__ */ jsxs(Button, { size: "small", color: "primary", onClick: () => setUploadDialogOpen(true), children: [
876
- /* @__PURE__ */ jsx(UploadCloudIcon, { size: iconSize.smallest, className: "mr-1" }),
877
- "Upload"
878
- ] })
879
- ] })
880
- ] }),
881
- /* @__PURE__ */ jsx("div", { className: "flex-grow flex flex-col overflow-hidden min-h-0", children: renderContents() }),
882
- /* @__PURE__ */ jsxs("div", { className: cls("px-4 py-1.5 border-t bg-surface-50 dark:bg-surface-900 flex items-center justify-between shrink-0", defaultBorderMixin), children: [
883
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4 text-[11px]", children: [
884
- /* @__PURE__ */ jsx("span", { className: "text-text-disabled dark:text-text-disabled-dark font-bold uppercase tracking-tighter", children: "Path" }),
885
- /* @__PURE__ */ jsxs("span", { className: "font-mono text-text-secondary dark:text-text-secondary-dark", children: [
886
- "/",
887
- currentPath || ""
888
- ] })
889
- ] }),
890
- selectedFile && /* @__PURE__ */ jsxs("div", { className: "text-[11px] text-text-secondary dark:text-text-secondary-dark", children: [
891
- "Selected: ",
892
- /* @__PURE__ */ jsx("span", { className: "font-mono", children: selectedFile.name })
893
- ] })
894
- ] })
895
- ] }),
896
- selectedFile && /* @__PURE__ */ jsx("div", { className: "w-80 lg:w-96 shrink-0", children: /* @__PURE__ */ jsx(FilePreviewPanel, { file: selectedFile, downloadUrl: selectedDownloadUrl, onClose: () => {
897
- setSelectedFile(null);
898
- setSelectedDownloadUrl(null);
899
- }, onDelete: () => handleDeleteFile(selectedFile) }) })
900
- ] }) }),
901
- /* @__PURE__ */ jsx(UploadDialog, { open: uploadDialogOpen, currentPath, onClose: () => setUploadDialogOpen(false), onUpload: handleUpload })
902
- ] });
903
- };
904
- export {
905
- StorageView
906
- };
907
- //# sourceMappingURL=StorageView-CTqGFhY9.js.map