@parallelworks/ui 0.19.0 → 0.19.1

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 (217) hide show
  1. package/dist/{chunks/memoryStore-CC91S5LP.js → ai/adapter/memoryStore.js} +2 -2
  2. package/dist/ai/adapter/mock/index.js +2 -80
  3. package/dist/ai/adapter/mock/mockAdapter.js +81 -0
  4. package/dist/ai/adapter/openai/createOpenAIStream.js +33 -0
  5. package/dist/ai/adapter/openai/errors.js +37 -0
  6. package/dist/ai/adapter/openai/index.js +5 -333
  7. package/dist/ai/adapter/openai/openaiAdapter.js +54 -0
  8. package/dist/ai/adapter/openai/responses.js +108 -0
  9. package/dist/ai/adapter/openai/sse.js +112 -0
  10. package/dist/{chunks/types-Yy0NrerF.js → ai/adapter/types.js} +1 -1
  11. package/dist/ai/agent/classifier.js +12 -0
  12. package/dist/ai/agent/diff.js +223 -0
  13. package/dist/ai/agent/diffHighlight.js +101 -0
  14. package/dist/ai/agent/permissions.js +29 -0
  15. package/dist/ai/agent/toolfmt.js +383 -0
  16. package/dist/ai/agent/transcript.js +127 -0
  17. package/dist/ai/components/AllocationSelector.js +56 -0
  18. package/dist/ai/components/AttachmentManager.js +144 -0
  19. package/dist/ai/components/AttachmentUpload.js +179 -0
  20. package/dist/ai/components/BlockedGroupBanner.js +29 -0
  21. package/dist/ai/components/BranchNavigator.js +57 -0
  22. package/dist/ai/components/ChatEmptyState.js +171 -0
  23. package/dist/ai/components/ChatInput.js +265 -0
  24. package/dist/ai/components/ChatLayout.js +15 -0
  25. package/dist/ai/components/ChatMessage.js +338 -0
  26. package/dist/ai/components/ChatMessageList.js +301 -0
  27. package/dist/ai/components/ChatSidebar.js +345 -0
  28. package/dist/ai/components/ChatThread.js +198 -0
  29. package/dist/ai/components/ComposerChrome.js +50 -0
  30. package/dist/ai/components/ComposerFrame.js +33 -0
  31. package/dist/ai/components/DragOverlay.js +20 -0
  32. package/dist/ai/components/ModelSelector.js +343 -0
  33. package/dist/ai/components/ShareDialog.js +260 -0
  34. package/dist/ai/components/SlashMenu.js +91 -0
  35. package/dist/ai/components/agent/ActivityLine.js +151 -0
  36. package/dist/ai/components/agent/AgentMessageParts.js +721 -0
  37. package/dist/ai/components/agent/PermissionPicker.js +38 -0
  38. package/dist/ai/components/attachmentKeys.js +10 -0
  39. package/dist/ai/core/ChatProvider.js +848 -0
  40. package/dist/ai/core/KeyboardShortcutsProvider.js +9 -0
  41. package/dist/ai/core/chatReducer.js +223 -0
  42. package/dist/ai/core/config.js +45 -0
  43. package/dist/ai/core/events.js +4 -0
  44. package/dist/ai/core/exportConversation.js +42 -0
  45. package/dist/ai/core/greeting.js +38 -0
  46. package/dist/ai/core/parts.js +84 -0
  47. package/dist/ai/core/useDragDrop.js +36 -0
  48. package/dist/ai/core/useKeyboardShortcuts.js +77 -0
  49. package/dist/ai/core/useSSEStream.js +98 -0
  50. package/dist/ai/index.js +43 -6644
  51. package/dist/ai/strings.js +175 -0
  52. package/dist/ai/ui/Avatar.js +35 -0
  53. package/dist/ai/ui/Dropdown.js +110 -0
  54. package/dist/ai/ui/Markdown.js +79 -0
  55. package/dist/ai/ui/Notice.js +77 -0
  56. package/dist/ai/ui/codeBreaks.js +36 -0
  57. package/dist/ai/ui/prose.js +13 -0
  58. package/dist/ai/ui/sidebar.js +148 -0
  59. package/dist/ai/utils.js +23 -0
  60. package/dist/components/AddMenu.js +46 -0
  61. package/dist/components/Avatar.js +46 -0
  62. package/dist/{chunks/BareModal-BtRiQezg.js → components/BareModal.js} +1 -1
  63. package/dist/components/Breadcrumbs.js +83 -0
  64. package/dist/components/Button.js +83 -0
  65. package/dist/components/Callout.js +23 -0
  66. package/dist/components/Card.js +31 -0
  67. package/dist/components/CollapsiblePanel.js +77 -0
  68. package/dist/{chunks/ConfirmModal-aOR4O1QE.js → components/ConfirmModal.js} +4 -9
  69. package/dist/components/CopyToClipboard.js +81 -0
  70. package/dist/{chunks/Markdown-CM-FenNE.js → components/CreateModal.js} +9 -116
  71. package/dist/components/DescriptionList.js +42 -0
  72. package/dist/components/Dropdown.js +349 -0
  73. package/dist/components/EmptyState.js +27 -0
  74. package/dist/components/Filter.js +32 -0
  75. package/dist/components/FilterPill.js +13 -0
  76. package/dist/components/IconButton.js +34 -0
  77. package/dist/{chunks/Indicator-hBSIxOPK.js → components/Indicator.js} +1 -1
  78. package/dist/components/Input.js +88 -0
  79. package/dist/components/LetterBadge.js +13 -0
  80. package/dist/components/Listbox.js +123 -0
  81. package/dist/{chunks/Loader-BXoXTZGc.js → components/Loader.js} +1 -1
  82. package/dist/components/Markdown.js +15 -0
  83. package/dist/components/MultiSelect.js +171 -0
  84. package/dist/components/Overview.js +39 -0
  85. package/dist/components/PageHeader.js +194 -0
  86. package/dist/components/Pagination.js +35 -0
  87. package/dist/{chunks/Provider-CDYurraE.js → components/Provider.js} +1 -1
  88. package/dist/{chunks/RequiredMark-DfLdYbYZ.js → components/RequiredMark.js} +1 -1
  89. package/dist/components/SectionHeader.js +11 -0
  90. package/dist/components/SettingModeOption.js +30 -0
  91. package/dist/components/SettingRow.js +35 -0
  92. package/dist/components/SettingsCard.js +31 -0
  93. package/dist/components/SettingsGroup.js +17 -0
  94. package/dist/components/Sort.js +42 -0
  95. package/dist/components/StatusBadge.js +63 -0
  96. package/dist/components/SwitchToggle.js +59 -0
  97. package/dist/{chunks/SwitchToggleSmall-FcsaYSTs.js → components/SwitchToggleSmall.js} +1 -1
  98. package/dist/{chunks/Table-DU2MW8xz.js → components/Table.js} +3 -3
  99. package/dist/components/Toggle.js +20 -0
  100. package/dist/{chunks/Tooltip-K5HJr4_p.js → components/Tooltip.js} +2 -27
  101. package/dist/{chunks/StatusBadge-C1Blx_cW.js → components/dropdownUtils.js} +2 -63
  102. package/dist/{chunks/focus-D_iZJTW1.js → components/focus.js} +1 -1
  103. package/dist/components/ghostButton.js +7 -0
  104. package/dist/components/inputClasses.js +4 -0
  105. package/dist/components/keys.js +27 -0
  106. package/dist/components/relativeTime.js +32 -0
  107. package/dist/{chunks/useCssIsDark-DHr05dG2.js → components/useCssIsDark.js} +1 -1
  108. package/dist/{chunks/duration-BOv8Phl8.js → duration.js} +1 -1
  109. package/dist/editor/Editor.js +13 -0
  110. package/dist/editor/EditorField.js +53 -0
  111. package/dist/editor/FormCodePanel.js +173 -0
  112. package/dist/{chunks/Monaco-DJ8MW-Dq.js → editor/Monaco.js} +4 -2
  113. package/dist/editor/index.js +6 -1
  114. package/dist/editor/themes.js +91 -0
  115. package/dist/editor/workers.js +29 -0
  116. package/dist/editor/yaml.js +15 -0
  117. package/dist/file-explorer/FileExplorer.js +1402 -0
  118. package/dist/file-explorer/FileExplorerContext.js +370 -0
  119. package/dist/{chunks/CodePreviewEditor-YqQBz1YL.js → file-explorer/FilePreview/CodePreviewEditor.js} +3 -2
  120. package/dist/file-explorer/FilePreview/Inline.js +45 -0
  121. package/dist/file-explorer/FilePreview/StreamedBadge.js +16 -0
  122. package/dist/file-explorer/FilePreview/Viewer.js +526 -0
  123. package/dist/file-explorer/FilePreview/index.js +266 -0
  124. package/dist/file-explorer/FilePreview/parse.js +63 -0
  125. package/dist/file-explorer/FilePreview/previewCache.js +98 -0
  126. package/dist/file-explorer/FilePreview/previewType.js +151 -0
  127. package/dist/file-explorer/FilePreview/readCappedBytes.js +196 -0
  128. package/dist/file-explorer/FilePreview/useObjectBlobUrl.js +95 -0
  129. package/dist/file-explorer/FilePreview/useObjectText.js +109 -0
  130. package/dist/file-explorer/FilePreview/usePresignedUrl.js +73 -0
  131. package/dist/file-explorer/FileRow.js +165 -0
  132. package/dist/file-explorer/FileRowsWindow.js +92 -0
  133. package/dist/file-explorer/FileTable.js +172 -0
  134. package/dist/file-explorer/FileTableHeaders.js +49 -0
  135. package/dist/file-explorer/LoadMoreRow.js +46 -0
  136. package/dist/file-explorer/TreeView.js +376 -0
  137. package/dist/file-explorer/helpers.js +537 -0
  138. package/dist/file-explorer/index.js +7 -5671
  139. package/dist/file-explorer/lib/batch.js +39 -0
  140. package/dist/file-explorer/lib/errors.js +9 -0
  141. package/dist/file-explorer/lib/paging.js +124 -0
  142. package/dist/file-explorer/lib/utils.js +322 -0
  143. package/dist/file-explorer/toasts.js +400 -0
  144. package/dist/file-explorer/treeRows.js +73 -0
  145. package/dist/file-explorer/useNearEnd.js +27 -0
  146. package/dist/form/FieldWrapper.js +54 -0
  147. package/dist/form/Fields/BooleanField.js +51 -0
  148. package/dist/form/Fields/CheckboxGroupField.js +72 -0
  149. package/dist/form/Fields/ColorField.js +33 -0
  150. package/dist/form/Fields/DropdownField.js +49 -0
  151. package/dist/form/Fields/DurationField.js +130 -0
  152. package/dist/form/Fields/LabelField.js +19 -0
  153. package/dist/form/Fields/MultiDropdownField.js +40 -0
  154. package/dist/form/Fields/NumberField.js +51 -0
  155. package/dist/form/Fields/ObjectField.js +54 -0
  156. package/dist/form/Fields/RadioField.js +49 -0
  157. package/dist/form/Fields/RangeField.js +58 -0
  158. package/dist/form/Fields/ResourceOptionIcon.js +21 -0
  159. package/dist/form/Fields/StepField.js +6 -0
  160. package/dist/form/Fields/StringField.js +37 -0
  161. package/dist/form/Fields/TextAreaField.js +31 -0
  162. package/dist/form/Fields/durationValidity.js +11 -0
  163. package/dist/form/Form.js +643 -0
  164. package/dist/form/SpecialTypes/DropdownWrapper.js +30 -0
  165. package/dist/form/SpecialTypes/FormikCustomDropdown.js +122 -0
  166. package/dist/form/SpecialTypes/FormikCustomInput.js +111 -0
  167. package/dist/form/SpecialTypes/FormikMultiSelectDropdown.js +31 -0
  168. package/dist/form/SpecialTypes/FormikNumericInput.js +60 -0
  169. package/dist/form/Wizard/WizardContainer.js +138 -0
  170. package/dist/form/Wizard/WizardNavigation.js +92 -0
  171. package/dist/form/Wizard/WizardStepContent.js +35 -0
  172. package/dist/form/Wizard/WizardStepIndicator.js +108 -0
  173. package/dist/form/Wizard/useWizardState.js +118 -0
  174. package/dist/form/Wizard/utils.js +34 -0
  175. package/dist/form/fieldContext.js +26 -0
  176. package/dist/form/fieldRegistry.js +50 -0
  177. package/dist/form/index.js +17 -2321
  178. package/dist/{chunks/FieldWrapper-Cszwg-4B.js → form/lib.js} +2 -97
  179. package/dist/form/useParsedOpts.js +62 -0
  180. package/dist/form/usePrevious.js +11 -0
  181. package/dist/form/utils/checkShowIfObject.js +14 -0
  182. package/dist/form/utils/duration.js +69 -0
  183. package/dist/form/utils/getParentValue.js +23 -0
  184. package/dist/form/utils/getPlaceholder.js +9 -0
  185. package/dist/form/utils/getValueUsingPath.js +23 -0
  186. package/dist/form/utils/secondaryField.js +22 -0
  187. package/dist/graph/AnnotationBanner.js +141 -0
  188. package/dist/graph/Collapse.js +41 -0
  189. package/dist/graph/DependencyGraph.js +1398 -0
  190. package/dist/graph/JobSummary.js +104 -0
  191. package/dist/graph/MatrixGroup.js +107 -0
  192. package/dist/graph/Reveal.js +57 -0
  193. package/dist/graph/TreeView.js +711 -0
  194. package/dist/graph/index.js +1 -2519
  195. package/dist/graph/types.js +6 -0
  196. package/dist/index.js +46 -599
  197. package/dist/list/ActionToolbar.js +184 -0
  198. package/dist/list/HoverCard.js +73 -0
  199. package/dist/list/ListPage.js +145 -0
  200. package/dist/list/ListPager.js +59 -0
  201. package/dist/list/ListTable.js +163 -0
  202. package/dist/list/ListViewControls.js +372 -0
  203. package/dist/list/RowContextMenu.js +350 -0
  204. package/dist/list/UserHoverCard.js +117 -0
  205. package/dist/list/index.js +11 -2
  206. package/dist/list/listSearch.js +137 -0
  207. package/dist/list/listView.js +210 -0
  208. package/dist/list/textEntry.js +10 -0
  209. package/dist/{chunks/logviewer-BTKuQWzw.js → logviewer/LogViewer.js} +4 -82
  210. package/dist/logviewer/index.js +2 -1
  211. package/dist/logviewer/segments.js +80 -0
  212. package/package.json +1 -1
  213. package/dist/chunks/PageHeader-0kG_iypP.js +0 -692
  214. package/dist/chunks/SwitchToggle-DShNdcao.js +0 -758
  215. package/dist/chunks/editor-Dk1rbV75.js +0 -361
  216. package/dist/chunks/list-CJm875m7.js +0 -1418
  217. /package/dist/{chunks/MarkdownImpl-CyeTVvSt.js → components/MarkdownImpl.js} +0 -0
@@ -0,0 +1,537 @@
1
+ import { useNotify, useProvisionCorsRules, useStrings } from "../components/Provider.js";
2
+ import { AlertIcon, CustomizeIcon, DiskIcon, DocumentIcon, FileIcon, FileTextIcon, FolderIcon, ImageIcon, PdfIcon, RefreshIcon, ShareIcon, SpreadsheetIcon, UserIcon, VideoIcon, ZipIcon } from "../icons.js";
3
+ import { positionKeys } from "../components/keys.js";
4
+ import Callout from "../components/Callout.js";
5
+ import { ListSkeleton } from "../list/ListTable.js";
6
+ import { formatFileSize, getFileExtension } from "./lib/utils.js";
7
+ import { CorsError } from "./lib/errors.js";
8
+ import cx from "classnames";
9
+ import { useEffect, useState, useTransition } from "react";
10
+ import { useLocalStorage } from "usehooks-ts";
11
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
12
+ import Skeleton from "react-loading-skeleton";
13
+ //#region src/file-explorer/helpers.tsx
14
+ var SIDEBAR_WIDTH_STORAGE_KEY = "fileExplorerSidebarWidth";
15
+ var contentTypeIconMap = [
16
+ {
17
+ pattern: /^image\//,
18
+ icon: /* @__PURE__ */ jsx(ImageIcon, { className: "h-4 w-4 text-blue-500" })
19
+ },
20
+ {
21
+ pattern: /^video\//,
22
+ icon: /* @__PURE__ */ jsx(VideoIcon, { className: "h-4 w-4 text-purple-500" })
23
+ },
24
+ {
25
+ pattern: /^application\/pdf$/,
26
+ icon: /* @__PURE__ */ jsx(PdfIcon, { className: "h-4 w-4 text-red-500" })
27
+ },
28
+ {
29
+ pattern: /(spreadsheet|csv|excel)/,
30
+ icon: /* @__PURE__ */ jsx(SpreadsheetIcon, { className: "h-4 w-4 text-green-500" })
31
+ },
32
+ {
33
+ pattern: /(document|word)/,
34
+ icon: /* @__PURE__ */ jsx(DocumentIcon, { className: "h-4 w-4 text-blue-400" })
35
+ },
36
+ {
37
+ pattern: /(javascript|json|css|html)/,
38
+ icon: /* @__PURE__ */ jsx(FileTextIcon, { className: "h-4 w-4 text-yellow-500" })
39
+ },
40
+ {
41
+ pattern: /(zip|gzip|tar)/,
42
+ icon: /* @__PURE__ */ jsx(ZipIcon, { className: "h-4 w-4 text-purple-600" })
43
+ }
44
+ ];
45
+ var extensionIconMap = [
46
+ {
47
+ pattern: /^(jpe?g|png|gif|svg|webp)$/i,
48
+ icon: /* @__PURE__ */ jsx(ImageIcon, { className: "h-4 w-4 text-blue-500" })
49
+ },
50
+ {
51
+ pattern: /^(mp4|mov|avi|mkv)$/i,
52
+ icon: /* @__PURE__ */ jsx(VideoIcon, { className: "h-4 w-4 text-purple-500" })
53
+ },
54
+ {
55
+ pattern: /^pdf$/i,
56
+ icon: /* @__PURE__ */ jsx(PdfIcon, { className: "h-4 w-4 text-red-500" })
57
+ },
58
+ {
59
+ pattern: /^(xlsx?|csv|ods)$/i,
60
+ icon: /* @__PURE__ */ jsx(SpreadsheetIcon, { className: "h-4 w-4 text-green-500" })
61
+ },
62
+ {
63
+ pattern: /^(docx?|odt)$/i,
64
+ icon: /* @__PURE__ */ jsx(DocumentIcon, { className: "h-4 w-4 text-blue-400" })
65
+ },
66
+ {
67
+ pattern: /^(js|ts|json|css|html|md|txt)$/i,
68
+ icon: /* @__PURE__ */ jsx(FileTextIcon, { className: "h-4 w-4 text-yellow-500" })
69
+ },
70
+ {
71
+ pattern: /^(zip|gz|gzip|tar|rar)$/i,
72
+ icon: /* @__PURE__ */ jsx(ZipIcon, { className: "h-4 w-4 text-purple-600" })
73
+ }
74
+ ];
75
+ function getNodeIcon(node, storageIconUrl, storageIconAlt = "Storage icon") {
76
+ const isUserNode = !node.storageId;
77
+ const isStorageNode = node.root;
78
+ if (isUserNode) return /* @__PURE__ */ jsx(UserIcon, { className: "h-3 w-3 mr-2" });
79
+ if (isStorageNode && node.storageType === "workspace") return /* @__PURE__ */ jsx(DiskIcon, { className: "h-4 w-4 mr-2" });
80
+ if (isStorageNode && node.storageNodeIcon) {
81
+ const storageNodeIcon = node.storageNodeIcon;
82
+ const fallbackSrc = storageIconUrl?.({ type: storageNodeIcon });
83
+ const iconSrc = node.storageImageUrl || fallbackSrc;
84
+ if (!iconSrc) return /* @__PURE__ */ jsx(DiskIcon, { className: "h-4 w-4 mr-2" });
85
+ return /* @__PURE__ */ jsx("img", {
86
+ className: "h-4 w-4 mr-2",
87
+ src: iconSrc,
88
+ alt: storageIconAlt,
89
+ onError: (e) => {
90
+ if (fallbackSrc) e.currentTarget.src = fallbackSrc;
91
+ }
92
+ });
93
+ }
94
+ if (!isStorageNode && !isUserNode && node.type === "directory") return null;
95
+ if (node.contentType) {
96
+ for (const { pattern, icon } of contentTypeIconMap) if (pattern.test(node.contentType)) return icon;
97
+ }
98
+ const ext = getFileExtension(node.name);
99
+ if (ext) {
100
+ for (const { pattern, icon } of extensionIconMap) if (pattern.test(ext)) return icon;
101
+ }
102
+ return /* @__PURE__ */ jsx(FileIcon, { className: "h-4 w-4 theme-muted-text" });
103
+ }
104
+ function renderUploadNodes(uploadNodes) {
105
+ const sorted = [...uploadNodes].sort((a, b) => a.relativePath.localeCompare(b.relativePath));
106
+ let lastFolders = [];
107
+ return sorted.map((node) => {
108
+ const parts = node.relativePath.split("/");
109
+ const folders = parts.slice(0, -1);
110
+ const fileName = parts[parts.length - 1];
111
+ let common = 0;
112
+ while (common < folders.length && common < lastFolders.length && folders[common] === lastFolders[common]) common++;
113
+ const folderElements = folders.slice(common).map((folder, i) => /* @__PURE__ */ jsxs("div", {
114
+ style: { marginLeft: (common + i) * 16 },
115
+ children: [/* @__PURE__ */ jsx(FolderIcon, { className: "inline h-3 w-3 mr-1" }), /* @__PURE__ */ jsxs("span", {
116
+ className: "font-semibold",
117
+ children: [folder, "/"]
118
+ })]
119
+ }, folders.slice(0, common + i + 1).join("/")));
120
+ lastFolders = folders;
121
+ return /* @__PURE__ */ jsxs("div", { children: [folderElements, /* @__PURE__ */ jsxs("div", {
122
+ style: { marginLeft: folders.length * 16 },
123
+ children: [
124
+ /* @__PURE__ */ jsx("span", { className: "inline-block w-3" }),
125
+ fileName,
126
+ node.file && /* @__PURE__ */ jsxs("span", {
127
+ className: "ml-2 text-xs theme-muted-text",
128
+ children: [
129
+ "(",
130
+ formatFileSize(node.file.size),
131
+ ")"
132
+ ]
133
+ })
134
+ ]
135
+ })] }, node.relativePath);
136
+ });
137
+ }
138
+ function NoFileSelectedPreview() {
139
+ const t = useStrings().fileExplorer;
140
+ return /* @__PURE__ */ jsx("div", {
141
+ className: "flex-1 flex items-center justify-center p-8",
142
+ children: /* @__PURE__ */ jsxs("div", {
143
+ className: "flex flex-col items-center max-w-sm text-center",
144
+ children: [
145
+ /* @__PURE__ */ jsx("div", {
146
+ className: "inline-flex items-center justify-center w-14 h-14 rounded-full theme-muted-panel mb-4",
147
+ children: /* @__PURE__ */ jsx(DiskIcon, { className: "h-6 w-6 theme-muted-text" })
148
+ }),
149
+ /* @__PURE__ */ jsx("h2", {
150
+ className: "text-base font-semibold mb-1",
151
+ children: t.empty.nothingSelected
152
+ }),
153
+ /* @__PURE__ */ jsx("p", {
154
+ className: "text-sm theme-muted-text",
155
+ children: t.empty.nothingSelectedHint
156
+ })
157
+ ]
158
+ })
159
+ });
160
+ }
161
+ /** Shown instead of a skeleton that has nothing left to wait for. */
162
+ function NotFoundPreview({ path, onRetry }) {
163
+ const t = useStrings().fileExplorer.notFound;
164
+ const name = path.replace(/\/$/, "").split("/").pop() || path;
165
+ return /* @__PURE__ */ jsx("div", {
166
+ className: "flex-1 flex items-center justify-center p-8",
167
+ children: /* @__PURE__ */ jsxs("div", {
168
+ className: "flex flex-col items-center max-w-sm text-center",
169
+ children: [
170
+ /* @__PURE__ */ jsx("div", {
171
+ className: "inline-flex items-center justify-center w-14 h-14 rounded-full theme-muted-panel mb-4",
172
+ children: /* @__PURE__ */ jsx(DiskIcon, { className: "h-6 w-6 theme-muted-text" })
173
+ }),
174
+ /* @__PURE__ */ jsx("h2", {
175
+ className: "text-base font-semibold mb-1",
176
+ children: t.title(name)
177
+ }),
178
+ /* @__PURE__ */ jsx("p", {
179
+ className: "text-sm theme-muted-text mb-4",
180
+ children: t.description
181
+ }),
182
+ /* @__PURE__ */ jsxs("button", {
183
+ type: "button",
184
+ className: "btn btn-info gap-2",
185
+ onClick: onRetry,
186
+ children: [/* @__PURE__ */ jsx(RefreshIcon, { className: "h-4 w-4" }), t.retry]
187
+ })
188
+ ]
189
+ })
190
+ });
191
+ }
192
+ function CorsIssuePreview({ selectedStorage, onRefresh }) {
193
+ const t = useStrings().fileExplorer.cors;
194
+ const messages = useStrings().fileExplorer.messages;
195
+ const notify = useNotify();
196
+ const provisionCorsRules = useProvisionCorsRules();
197
+ const [isPending, startTransition] = useTransition();
198
+ const handleAddCorsRules = () => {
199
+ if (!provisionCorsRules) return;
200
+ startTransition(async () => {
201
+ await addCorsRules({
202
+ provision: provisionCorsRules,
203
+ notify,
204
+ strings: messages,
205
+ csp: selectedStorage?.csp,
206
+ type: selectedStorage?.type,
207
+ username: selectedStorage?.user,
208
+ storageName: selectedStorage?.displayName,
209
+ onRefresh
210
+ });
211
+ });
212
+ };
213
+ if (isPending) return /* @__PURE__ */ jsx(CorsPropagatingPreview, {});
214
+ return /* @__PURE__ */ jsxs("div", {
215
+ className: "flex flex-col items-center justify-center max-w-lg mx-auto",
216
+ children: [/* @__PURE__ */ jsxs(Callout, {
217
+ className: "text-left",
218
+ type: "info",
219
+ children: [
220
+ /* @__PURE__ */ jsx("h4", {
221
+ className: "font-semibold mb-2",
222
+ children: t.explanation.title
223
+ }),
224
+ /* @__PURE__ */ jsx("p", {
225
+ className: "mb-2",
226
+ children: t.explanation.description
227
+ }),
228
+ /* @__PURE__ */ jsx("p", { children: t.explanation.action }),
229
+ /* @__PURE__ */ jsx("p", {
230
+ className: "mt-2 text-sm italic",
231
+ children: t.explanation.note
232
+ })
233
+ ]
234
+ }), /* @__PURE__ */ jsxs("div", {
235
+ className: "flex gap-3 justify-center",
236
+ children: [/* @__PURE__ */ jsxs("button", {
237
+ type: "button",
238
+ className: "btn btn-info cursor-pointer flex items-center",
239
+ onClick: onRefresh ? () => onRefresh() : void 0,
240
+ children: [/* @__PURE__ */ jsx(RefreshIcon, { className: "h-4 w-4 mr-2" }), t.actions.retry]
241
+ }), provisionCorsRules && /* @__PURE__ */ jsxs("button", {
242
+ type: "button",
243
+ className: "btn btn-info cursor-pointer flex items-center",
244
+ onClick: handleAddCorsRules,
245
+ children: [/* @__PURE__ */ jsx(CustomizeIcon, { className: "h-4 w-4 mr-2" }), /* @__PURE__ */ jsx("span", { children: t.actions.addRules })]
246
+ })]
247
+ })]
248
+ });
249
+ }
250
+ var CORS_PROPAGATION_BUDGET_MS = 6e4;
251
+ function CorsPropagatingPreview() {
252
+ const t = useStrings().fileExplorer.cors.propagating;
253
+ const [elapsedMs, setElapsedMs] = useState(0);
254
+ useEffect(() => {
255
+ const start = Date.now();
256
+ setElapsedMs(0);
257
+ const id = setInterval(() => {
258
+ setElapsedMs(Date.now() - start);
259
+ }, 500);
260
+ return () => clearInterval(id);
261
+ }, []);
262
+ const totalSeconds = Math.floor(elapsedMs / 1e3);
263
+ const mm = String(Math.floor(totalSeconds / 60)).padStart(2, "0");
264
+ const ss = String(totalSeconds % 60).padStart(2, "0");
265
+ const progressPct = Math.min(99, elapsedMs / CORS_PROPAGATION_BUDGET_MS * 100);
266
+ return /* @__PURE__ */ jsxs("div", {
267
+ role: "status",
268
+ "aria-live": "polite",
269
+ className: "flex flex-col items-center justify-center max-w-md mx-auto px-6 py-8 animate-[fadeInUp_400ms_ease-out]",
270
+ children: [
271
+ /* @__PURE__ */ jsxs("div", {
272
+ className: "relative w-28 h-28 mb-6 flex items-center justify-center",
273
+ children: [
274
+ /* @__PURE__ */ jsx("span", {
275
+ className: "absolute inline-flex h-full w-full rounded-full bg-blue-400/30 animate-ping",
276
+ style: { animationDuration: "2.4s" }
277
+ }),
278
+ /* @__PURE__ */ jsx("span", {
279
+ className: "absolute inline-flex h-2/3 w-2/3 rounded-full bg-blue-500/40 animate-ping",
280
+ style: {
281
+ animationDuration: "2.4s",
282
+ animationDelay: "0.6s"
283
+ }
284
+ }),
285
+ /* @__PURE__ */ jsx("span", {
286
+ className: "absolute inline-flex h-1/3 w-1/3 rounded-full bg-blue-500/60 animate-ping",
287
+ style: {
288
+ animationDuration: "2.4s",
289
+ animationDelay: "1.2s"
290
+ }
291
+ }),
292
+ /* @__PURE__ */ jsx("span", {
293
+ className: "relative inline-flex items-center justify-center w-8 h-8 rounded-full bg-blue-500 shadow-[0_0_24px_rgba(59,130,246,0.55)]",
294
+ children: /* @__PURE__ */ jsx("span", { className: "absolute inline-flex h-2 w-2 rounded-full bg-white animate-pulse" })
295
+ })
296
+ ]
297
+ }),
298
+ /* @__PURE__ */ jsx("h3", {
299
+ className: "text-lg font-semibold mb-1 tracking-tight",
300
+ children: t.title
301
+ }),
302
+ /* @__PURE__ */ jsx("p", {
303
+ className: "theme-muted-text text-sm text-center mb-6 max-w-sm",
304
+ children: t.description
305
+ }),
306
+ /* @__PURE__ */ jsxs("ol", {
307
+ className: "flex items-center gap-2 mb-6",
308
+ children: [
309
+ /* @__PURE__ */ jsx(PropagationStage, {
310
+ status: "done",
311
+ label: t.stages.submitted
312
+ }),
313
+ /* @__PURE__ */ jsx(PropagationConnector, { active: true }),
314
+ /* @__PURE__ */ jsx(PropagationStage, {
315
+ status: "active",
316
+ label: t.stages.propagating
317
+ }),
318
+ /* @__PURE__ */ jsx(PropagationConnector, { active: false }),
319
+ /* @__PURE__ */ jsx(PropagationStage, {
320
+ status: "pending",
321
+ label: t.stages.verified
322
+ })
323
+ ]
324
+ }),
325
+ /* @__PURE__ */ jsx("div", {
326
+ className: "w-full max-w-xs mb-3",
327
+ children: /* @__PURE__ */ jsx("div", {
328
+ className: "h-1 rounded-full theme-muted-panel overflow-hidden",
329
+ children: /* @__PURE__ */ jsx("div", {
330
+ className: "h-full bg-blue-500 transition-[width] duration-500 ease-linear",
331
+ style: { width: `${progressPct}%` }
332
+ })
333
+ })
334
+ }),
335
+ /* @__PURE__ */ jsxs("div", {
336
+ className: "flex items-center gap-2 theme-muted-text text-xs font-mono tabular-nums",
337
+ children: [
338
+ /* @__PURE__ */ jsxs("span", { children: [
339
+ mm,
340
+ ":",
341
+ ss
342
+ ] }),
343
+ /* @__PURE__ */ jsx("span", {
344
+ "aria-hidden": "true",
345
+ className: "opacity-40",
346
+ children: "·"
347
+ }),
348
+ /* @__PURE__ */ jsx("span", { children: t.telemetry.probing })
349
+ ]
350
+ })
351
+ ]
352
+ });
353
+ }
354
+ function PropagationStage({ status, label }) {
355
+ return /* @__PURE__ */ jsxs("li", {
356
+ className: "flex flex-col items-center gap-1.5",
357
+ children: [/* @__PURE__ */ jsxs("span", {
358
+ className: cx("relative flex items-center justify-center w-6 h-6 rounded-full border transition-colors", status === "done" && "bg-green-500 border-green-500 text-white", status === "active" && "border-blue-500", status === "pending" && "theme-border"),
359
+ children: [
360
+ status === "done" && /* @__PURE__ */ jsx("svg", {
361
+ viewBox: "0 0 16 16",
362
+ className: "h-3 w-3",
363
+ fill: "none",
364
+ stroke: "currentColor",
365
+ strokeWidth: "2.5",
366
+ strokeLinecap: "round",
367
+ strokeLinejoin: "round",
368
+ "aria-hidden": "true",
369
+ children: /* @__PURE__ */ jsx("polyline", { points: "3.5 8.5 6.5 11.5 12.5 5" })
370
+ }),
371
+ status === "active" && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", { className: "absolute inline-flex h-full w-full animate-ping rounded-full bg-blue-400/60" }), /* @__PURE__ */ jsx("span", { className: "relative inline-flex h-2 w-2 rounded-full bg-blue-500" })] }),
372
+ status === "pending" && /* @__PURE__ */ jsx("span", { className: "inline-flex h-1.5 w-1.5 rounded-full theme-muted-text opacity-60" })
373
+ ]
374
+ }), /* @__PURE__ */ jsx("span", {
375
+ className: cx("text-[11px] uppercase tracking-wider", status === "pending" ? "theme-muted-text opacity-60" : "theme-text"),
376
+ children: label
377
+ })]
378
+ });
379
+ }
380
+ function PropagationConnector({ active }) {
381
+ return /* @__PURE__ */ jsx("span", {
382
+ "aria-hidden": "true",
383
+ className: cx("h-px w-8 -mt-5 transition-colors", active ? "bg-blue-500" : "theme-border border-t")
384
+ });
385
+ }
386
+ function NoDataAvailablePreview({ selectedStorage, error, onRefresh, connectionIssueMessage = null, className, canWrite = true }) {
387
+ const t = useStrings().fileExplorer;
388
+ if (error instanceof CorsError) return /* @__PURE__ */ jsx("div", {
389
+ className: cx("flex-1 flex items-center justify-center w-full text-center", className),
390
+ children: /* @__PURE__ */ jsx(CorsIssuePreview, {
391
+ selectedStorage,
392
+ onRefresh
393
+ })
394
+ });
395
+ return /* @__PURE__ */ jsx("div", {
396
+ className: cx("flex-1 flex items-center justify-center w-full text-center", className),
397
+ children: !connectionIssueMessage ? /* @__PURE__ */ jsxs("div", {
398
+ className: "flex flex-col items-center justify-center max-w-sm p-8",
399
+ children: [
400
+ /* @__PURE__ */ jsx("div", {
401
+ className: "inline-flex items-center justify-center w-14 h-14 rounded-full theme-muted-panel mb-4",
402
+ children: /* @__PURE__ */ jsx(FileIcon, { className: "h-6 w-6 theme-muted-text" })
403
+ }),
404
+ /* @__PURE__ */ jsx("h2", {
405
+ className: "text-base font-semibold mb-1",
406
+ children: t.empty.folderEmpty
407
+ }),
408
+ /* @__PURE__ */ jsx("p", {
409
+ className: "text-sm theme-muted-text",
410
+ children: canWrite ? t.empty.dropHint : t.empty.readOnlyHint
411
+ })
412
+ ]
413
+ }) : /* @__PURE__ */ jsxs("div", {
414
+ className: "flex flex-col items-center justify-center max-w-md p-8",
415
+ children: [
416
+ /* @__PURE__ */ jsx("div", {
417
+ className: "inline-flex items-center justify-center w-14 h-14 rounded-full bg-amber-500/10 mb-4",
418
+ children: /* @__PURE__ */ jsx(AlertIcon, { className: "h-6 w-6 text-amber-500" })
419
+ }),
420
+ /* @__PURE__ */ jsx("h2", {
421
+ className: "text-base font-semibold mb-1",
422
+ children: t.empty.connectionIssue
423
+ }),
424
+ /* @__PURE__ */ jsx("p", {
425
+ className: "text-sm theme-muted-text mb-4",
426
+ children: connectionIssueMessage
427
+ }),
428
+ /* @__PURE__ */ jsxs("button", {
429
+ type: "button",
430
+ className: "btn btn-info cursor-pointer flex items-center gap-2",
431
+ onClick: onRefresh ? () => onRefresh() : void 0,
432
+ children: [/* @__PURE__ */ jsx(RefreshIcon, { className: "h-4 w-4" }), t.empty.tryAgain]
433
+ })
434
+ ]
435
+ })
436
+ });
437
+ }
438
+ function SkeletonPreview() {
439
+ const [sidebarWidth] = useLocalStorage(SIDEBAR_WIDTH_STORAGE_KEY, 300);
440
+ return /* @__PURE__ */ jsxs("div", {
441
+ className: "w-full h-full flex",
442
+ children: [/* @__PURE__ */ jsx("div", {
443
+ className: "h-full shrink-0",
444
+ style: { width: `${sidebarWidth}px` },
445
+ children: /* @__PURE__ */ jsxs("div", {
446
+ className: "h-full flex flex-col border-r theme-border bg-(--theme-panel-bg)/60",
447
+ children: [/* @__PURE__ */ jsx("div", {
448
+ className: "flex items-center justify-end h-10 px-3 shrink-0 border-b theme-border",
449
+ children: /* @__PURE__ */ jsxs("div", {
450
+ className: "flex gap-x-0.5",
451
+ children: [/* @__PURE__ */ jsx("div", { className: "h-7 w-7" }), /* @__PURE__ */ jsx("div", { className: "h-7 w-7" })]
452
+ })
453
+ }), /* @__PURE__ */ jsx("div", {
454
+ className: "overflow-auto flex-1 px-2 py-2 space-y-1.5",
455
+ children: positionKeys(6, "skeleton").map((key) => /* @__PURE__ */ jsx(Skeleton, { height: 14 }, key))
456
+ })]
457
+ })
458
+ }), /* @__PURE__ */ jsxs("div", {
459
+ className: "h-full flex flex-col flex-1 min-w-0",
460
+ children: [/* @__PURE__ */ jsx("div", { className: "h-12 shrink-0 border-b theme-border" }), /* @__PURE__ */ jsx(ListSkeleton, {})]
461
+ })]
462
+ });
463
+ }
464
+ function DragDropZone({ onDropFiles, children, className = "" }) {
465
+ const [isDragging, setIsDragging] = useState(false);
466
+ return /* @__PURE__ */ jsx("div", {
467
+ role: "none",
468
+ className: cx("transition-[box-shadow,background-color] duration-150", className, isDragging && "ring-1 ring-(--theme-link) ring-inset bg-(--theme-link)/5"),
469
+ onDragOver: (e) => {
470
+ e.preventDefault();
471
+ if (onDropFiles) setIsDragging(true);
472
+ },
473
+ onDragLeave: () => setIsDragging(false),
474
+ onDrop: (e) => {
475
+ e.preventDefault();
476
+ setIsDragging(false);
477
+ if (!onDropFiles) return;
478
+ onDropFiles(e.dataTransfer.items.length ? e.dataTransfer.items : e.dataTransfer.files);
479
+ },
480
+ children
481
+ });
482
+ }
483
+ function ShareFileButton({ node, onShare }) {
484
+ const t = useStrings().fileExplorer;
485
+ const [isPending, startTransition] = useTransition();
486
+ return /* @__PURE__ */ jsxs("button", {
487
+ type: "button",
488
+ "aria-label": t.preview.shareFile,
489
+ className: "btn btn-info cursor-pointer flex items-center justify-between",
490
+ onClick: () => {
491
+ startTransition(async () => {
492
+ await onShare(node);
493
+ });
494
+ },
495
+ disabled: isPending,
496
+ children: [/* @__PURE__ */ jsx(ShareIcon, { className: "h-4 w-4" }), /* @__PURE__ */ jsx("span", {
497
+ className: "hidden md:inline",
498
+ children: t.empty.shareThisFile
499
+ })]
500
+ });
501
+ }
502
+ async function addCorsRules({ provision, notify, strings, csp, type, username, storageName, onRefresh }) {
503
+ if (!storageName || !username || !csp) {
504
+ notify.error(strings.corsNoStorage);
505
+ return;
506
+ }
507
+ const res = await provision({
508
+ csp,
509
+ type,
510
+ username,
511
+ storageName
512
+ });
513
+ if (res.error) {
514
+ notify.error(res.error);
515
+ return;
516
+ }
517
+ if (!onRefresh) {
518
+ notify.success(strings.corsAdded);
519
+ return;
520
+ }
521
+ const pollBudgetMs = 9e4;
522
+ const pollIntervalMs = 3e3;
523
+ const deadline = Date.now() + pollBudgetMs;
524
+ await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
525
+ while (Date.now() < deadline) {
526
+ const result = await onRefresh({ silent: true });
527
+ if (!result || !result.corsError) {
528
+ await onRefresh();
529
+ notify.success(strings.corsAdded);
530
+ return;
531
+ }
532
+ await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
533
+ }
534
+ notify.warning(strings.corsPropagating);
535
+ }
536
+ //#endregion
537
+ export { CorsIssuePreview, DragDropZone, NoDataAvailablePreview, NoFileSelectedPreview, NotFoundPreview, SIDEBAR_WIDTH_STORAGE_KEY, ShareFileButton, SkeletonPreview, getNodeIcon, renderUploadNodes };