@parallelworks/ui 0.51.0 → 0.53.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 (250) hide show
  1. package/README.md +197 -17
  2. package/dist/ai/agent/toolStrings.d.ts +2 -0
  3. package/dist/ai/agent/toolStrings.js +20 -18
  4. package/dist/ai/ai.css +17 -3
  5. package/dist/ai/components/AllocationSelector.js +5 -1
  6. package/dist/ai/components/AttachmentManager.js +51 -42
  7. package/dist/ai/components/AttachmentUpload.d.ts +4 -2
  8. package/dist/ai/components/AttachmentUpload.js +9 -9
  9. package/dist/ai/components/BlockedGroupBanner.js +8 -14
  10. package/dist/ai/components/BranchNavigator.js +11 -12
  11. package/dist/ai/components/ChatEmptyState.js +12 -19
  12. package/dist/ai/components/ChatInput.d.ts +4 -3
  13. package/dist/ai/components/ChatInput.js +27 -13
  14. package/dist/ai/components/ChatMessage.js +45 -121
  15. package/dist/ai/components/ChatMessageList.d.ts +5 -2
  16. package/dist/ai/components/ChatMessageList.js +89 -51
  17. package/dist/ai/components/ChatSidebar.js +11 -7
  18. package/dist/ai/components/ChatThread.js +1 -13
  19. package/dist/ai/components/DragOverlay.js +3 -3
  20. package/dist/ai/components/MessageAttachments.d.ts +10 -0
  21. package/dist/ai/components/MessageAttachments.js +78 -0
  22. package/dist/ai/components/ModelSelector.js +3 -3
  23. package/dist/ai/components/PastedText.js +2 -2
  24. package/dist/ai/components/ProviderIssueBanner.js +19 -23
  25. package/dist/ai/components/ShareDialog.js +2 -2
  26. package/dist/ai/components/agent/ActivityLine.d.ts +0 -2
  27. package/dist/ai/components/agent/ActivityLine.js +8 -51
  28. package/dist/ai/components/agent/AgentMessageParts.js +114 -53
  29. package/dist/ai/core/ChatProvider.d.ts +16 -5
  30. package/dist/ai/core/ChatProvider.js +41 -8
  31. package/dist/ai/core/config.js +4 -3
  32. package/dist/ai/index.d.ts +1 -1
  33. package/dist/ai/index.js +3 -3
  34. package/dist/ai/strings.d.ts +29 -3
  35. package/dist/ai/strings.js +80 -26
  36. package/dist/ai/types.d.ts +4 -0
  37. package/dist/ai/ui/Notice.d.ts +2 -2
  38. package/dist/ai/ui/Notice.js +29 -62
  39. package/dist/ai/ui/sidebar.d.ts +5 -3
  40. package/dist/ai/ui/sidebar.js +22 -10
  41. package/dist/components/ActionMenu.d.ts +1 -0
  42. package/dist/components/ActionMenu.js +6 -1
  43. package/dist/components/AppLink.d.ts +26 -0
  44. package/dist/components/AppLink.js +51 -0
  45. package/dist/components/Avatar.d.ts +2 -1
  46. package/dist/components/Avatar.js +4 -2
  47. package/dist/components/Button.d.ts +15 -5
  48. package/dist/components/Button.js +47 -40
  49. package/dist/components/Callout.d.ts +31 -7
  50. package/dist/components/Callout.js +50 -19
  51. package/dist/components/Card.d.ts +11 -6
  52. package/dist/components/Card.js +14 -8
  53. package/dist/components/Checkbox.js +2 -1
  54. package/dist/components/ColorInput.js +5 -3
  55. package/dist/components/Combobox.js +49 -19
  56. package/dist/components/ConfirmModal.d.ts +19 -8
  57. package/dist/components/ConfirmModal.js +31 -53
  58. package/dist/components/CopyButton.d.ts +38 -0
  59. package/dist/components/CopyButton.js +68 -0
  60. package/dist/components/CreateModal.js +118 -111
  61. package/dist/components/DatePicker.js +12 -8
  62. package/dist/components/DescriptionList.d.ts +25 -5
  63. package/dist/components/DescriptionList.js +56 -22
  64. package/dist/components/Disclosure.js +1 -1
  65. package/dist/components/Drawer.js +10 -16
  66. package/dist/components/Field.d.ts +16 -5
  67. package/dist/components/Field.js +63 -8
  68. package/dist/components/IconButton.d.ts +14 -5
  69. package/dist/components/IconButton.js +25 -14
  70. package/dist/components/InfoTip.d.ts +12 -1
  71. package/dist/components/InfoTip.js +13 -2
  72. package/dist/components/Input.d.ts +14 -8
  73. package/dist/components/Input.js +46 -31
  74. package/dist/components/Loader.js +1 -1
  75. package/dist/components/MarkdownImpl.d.ts +1 -0
  76. package/dist/components/MarkdownImpl.js +1 -0
  77. package/dist/components/MenuEntries.d.ts +4 -0
  78. package/dist/components/MenuEntries.js +11 -12
  79. package/dist/components/Meter.js +5 -4
  80. package/dist/components/Modal.d.ts +28 -4
  81. package/dist/components/Modal.js +37 -14
  82. package/dist/components/Overview.d.ts +20 -12
  83. package/dist/components/Overview.js +14 -9
  84. package/dist/components/PageHeader.d.ts +47 -65
  85. package/dist/components/PageHeader.js +275 -153
  86. package/dist/components/PageHeaderAction.d.ts +67 -0
  87. package/dist/components/PageHeaderAction.js +107 -0
  88. package/dist/components/Pagination.js +6 -16
  89. package/dist/components/Popover.d.ts +4 -1
  90. package/dist/components/Popover.js +5 -3
  91. package/dist/components/Provider.d.ts +79 -19
  92. package/dist/components/Provider.js +140 -130
  93. package/dist/components/Radio.js +2 -1
  94. package/dist/components/RefreshButton.js +7 -8
  95. package/dist/components/RequiredMark.js +1 -1
  96. package/dist/components/Section.js +1 -1
  97. package/dist/components/Select.d.ts +4 -9
  98. package/dist/components/Select.js +24 -11
  99. package/dist/components/SettingModeOption.d.ts +1 -1
  100. package/dist/components/SettingModeOption.js +7 -1
  101. package/dist/components/SettingsCard.d.ts +5 -3
  102. package/dist/components/SettingsCard.js +27 -20
  103. package/dist/components/Slider.js +1 -1
  104. package/dist/components/StatusBadge.js +2 -2
  105. package/dist/components/Switch.js +5 -4
  106. package/dist/components/Table.d.ts +30 -20
  107. package/dist/components/Table.js +50 -73
  108. package/dist/components/Tabs.d.ts +3 -7
  109. package/dist/components/Tabs.js +6 -10
  110. package/dist/components/ThemeEditor.js +18 -8
  111. package/dist/components/Toast.d.ts +11 -3
  112. package/dist/components/Toast.js +45 -20
  113. package/dist/components/buttonClasses.js +1 -1
  114. package/dist/components/comboboxItems.d.ts +4 -0
  115. package/dist/components/comboboxItems.js +6 -1
  116. package/dist/components/dismiss.d.ts +12 -0
  117. package/dist/components/dismiss.js +19 -0
  118. package/dist/components/fieldBox.d.ts +4 -0
  119. package/dist/components/fieldBox.js +7 -3
  120. package/dist/components/floating.d.ts +3 -3
  121. package/dist/components/floating.js +1 -1
  122. package/dist/components/focus.d.ts +5 -0
  123. package/dist/components/focus.js +21 -1
  124. package/dist/components/markdownCodeBreaks.js +3 -4
  125. package/dist/components/pageHeaderStore.d.ts +41 -0
  126. package/dist/components/pageHeaderStore.js +67 -0
  127. package/dist/components/pathBreaks.d.ts +8 -0
  128. package/dist/components/pathBreaks.js +28 -0
  129. package/dist/components/segmented.js +1 -1
  130. package/dist/components/shortcutKey.d.ts +2 -1
  131. package/dist/components/shortcutKey.js +19 -2
  132. package/dist/components/splitter.js +1 -1
  133. package/dist/components/useCssIsDark.js +40 -18
  134. package/dist/components/useTheme.js +9 -10
  135. package/dist/dev.d.ts +9 -0
  136. package/dist/dev.js +14 -0
  137. package/dist/editor/Editor.d.ts +3 -2
  138. package/dist/editor/Editor.js +24 -5
  139. package/dist/editor/EditorField.d.ts +2 -1
  140. package/dist/editor/EditorField.js +11 -29
  141. package/dist/editor/FormCodePanel.d.ts +7 -3
  142. package/dist/editor/FormCodePanel.js +14 -7
  143. package/dist/editor/Monaco.d.ts +22 -6
  144. package/dist/editor/Monaco.js +177 -113
  145. package/dist/editor/editorModel.d.ts +1 -1
  146. package/dist/editor/editorModel.js +1 -1
  147. package/dist/editor/index.d.ts +6 -5
  148. package/dist/editor/index.js +5 -4
  149. package/dist/editor/languages.d.ts +24 -0
  150. package/dist/editor/languages.js +31 -0
  151. package/dist/editor/monacoFeatures.d.ts +7 -0
  152. package/dist/editor/monacoFeatures.js +19 -0
  153. package/dist/editor/themes.d.ts +8 -5
  154. package/dist/editor/themes.js +65 -32
  155. package/dist/editor/workers.d.ts +3 -3
  156. package/dist/editor/workers.js +8 -4
  157. package/dist/editor/yaml.d.ts +6 -2
  158. package/dist/editor/yaml.js +11 -2
  159. package/dist/editor/yamlLanguage.js +55 -38
  160. package/dist/file-explorer/FileExplorer.d.ts +18 -4
  161. package/dist/file-explorer/FileExplorer.js +204 -142
  162. package/dist/file-explorer/FileExplorerContext.js +1 -1
  163. package/dist/file-explorer/FilePreview/StreamedBadge.js +3 -1
  164. package/dist/file-explorer/FilePreview/Viewer.js +14 -10
  165. package/dist/file-explorer/FilePreview/index.js +4 -4
  166. package/dist/file-explorer/FileRow.d.ts +6 -2
  167. package/dist/file-explorer/FileRow.js +35 -17
  168. package/dist/file-explorer/FileRowsWindow.d.ts +2 -1
  169. package/dist/file-explorer/FileRowsWindow.js +36 -4
  170. package/dist/file-explorer/FileTable.d.ts +3 -1
  171. package/dist/file-explorer/FileTable.js +6 -3
  172. package/dist/file-explorer/TreeView.d.ts +5 -1
  173. package/dist/file-explorer/TreeView.js +86 -39
  174. package/dist/file-explorer/helpers.d.ts +2 -1
  175. package/dist/file-explorer/helpers.js +24 -23
  176. package/dist/file-explorer/lib/utils.d.ts +3 -0
  177. package/dist/file-explorer/lib/utils.js +6 -1
  178. package/dist/file-explorer/toasts.js +27 -19
  179. package/dist/file-explorer/treeRows.d.ts +6 -0
  180. package/dist/file-explorer/treeRows.js +19 -1
  181. package/dist/file-explorer/useNearEnd.js +3 -6
  182. package/dist/form/Fields/CheckboxGroupField.js +12 -5
  183. package/dist/form/Fields/DurationField.js +1 -1
  184. package/dist/form/Fields/LabelField.js +1 -1
  185. package/dist/form/Fields/ObjectField.d.ts +1 -1
  186. package/dist/form/Fields/ObjectField.js +3 -2
  187. package/dist/form/Fields/StringField.js +16 -29
  188. package/dist/form/Fields/TextAreaField.js +3 -4
  189. package/dist/form/Form.js +3 -8
  190. package/dist/form/Wizard/WizardNavigation.js +0 -3
  191. package/dist/form/Wizard/utils.js +2 -1
  192. package/dist/form/fieldFrame.d.ts +1 -1
  193. package/dist/form/fieldFrame.js +2 -2
  194. package/dist/form/types/fieldComponentTypes.d.ts +2 -1
  195. package/dist/graph/AnnotationBanner.d.ts +1 -2
  196. package/dist/graph/AnnotationBanner.js +30 -32
  197. package/dist/graph/Connectors.js +4 -1
  198. package/dist/graph/DependencyGraph.js +2 -2
  199. package/dist/graph/GraphEditor.js +11 -9
  200. package/dist/graph/GraphEditorDialogs.js +1 -1
  201. package/dist/graph/GraphNode.js +7 -4
  202. package/dist/graph/InputDialog.js +1 -1
  203. package/dist/graph/InputsEditor.js +14 -11
  204. package/dist/graph/MatrixGroup.js +9 -3
  205. package/dist/graph/Reveal.js +18 -10
  206. package/dist/graph/ShortcutsButton.d.ts +11 -2
  207. package/dist/graph/ShortcutsButton.js +14 -3
  208. package/dist/graph/TreeView.js +35 -18
  209. package/dist/graph/WorkflowSettingsDialog.js +1 -1
  210. package/dist/graph/editorFields.js +1 -1
  211. package/dist/graph/editorRows.js +16 -10
  212. package/dist/graph/editorStrings.d.ts +7 -0
  213. package/dist/graph/editorStrings.js +8 -1
  214. package/dist/graph/inputRefs.js +1 -1
  215. package/dist/graph/settingsViews.js +11 -18
  216. package/dist/graph/stepWith.js +1 -1
  217. package/dist/icons.d.ts +2 -0
  218. package/dist/icons.js +4 -2
  219. package/dist/index.d.ts +12 -12
  220. package/dist/index.js +16 -16
  221. package/dist/list/ActionToolbar.d.ts +42 -6
  222. package/dist/list/ActionToolbar.js +298 -101
  223. package/dist/list/ListPage.d.ts +15 -23
  224. package/dist/list/ListPage.js +42 -43
  225. package/dist/list/ListTable.d.ts +37 -7
  226. package/dist/list/ListTable.js +52 -12
  227. package/dist/list/ListViewControls.js +1 -1
  228. package/dist/list/UserHoverCard.js +7 -15
  229. package/dist/list/index.d.ts +2 -2
  230. package/dist/list/index.js +2 -2
  231. package/dist/list/listSearch.js +12 -10
  232. package/dist/list/listView.d.ts +10 -1
  233. package/dist/list/listView.js +15 -1
  234. package/dist/logviewer/LogViewer.d.ts +4 -2
  235. package/dist/logviewer/LogViewer.js +87 -69
  236. package/dist/logviewer/logviewer.css +3 -2
  237. package/dist/reducedMotion.d.ts +5 -0
  238. package/dist/reducedMotion.js +20 -0
  239. package/dist/safeUrl.d.ts +1 -1
  240. package/dist/safeUrl.js +4 -2
  241. package/dist/styles.css +1 -1
  242. package/package.json +5 -2
  243. package/dist/components/Breadcrumbs.d.ts +0 -37
  244. package/dist/components/Breadcrumbs.js +0 -90
  245. package/dist/components/CopyToClipboard.d.ts +0 -17
  246. package/dist/components/CopyToClipboard.js +0 -66
  247. package/dist/components/Sort.d.ts +0 -9
  248. package/dist/components/Sort.js +0 -42
  249. package/dist/file-explorer/FilePreview/CodePreviewEditor.d.ts +0 -6
  250. package/dist/file-explorer/FilePreview/CodePreviewEditor.js +0 -64
@@ -3,15 +3,26 @@ import { useLocalPersistedState } from "./persistedState.js";
3
3
  import { Toaster } from "./Toast.js";
4
4
  import { TooltipProvider } from "./Tooltip.js";
5
5
  import { jsx, jsxs } from "react/jsx-runtime";
6
- import { createContext, use, useCallback, useContext, useEffect, useMemo, useState } from "react";
6
+ import { createContext, use, useCallback, useContext, useEffect, useRef, useState } from "react";
7
+ import { dequal } from "dequal";
7
8
  //#region src/components/Provider.tsx
9
+ var isGroup = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
10
+ function mergeStrings(defaults, overrides) {
11
+ if (!isGroup(overrides) || !isGroup(defaults)) return defaults;
12
+ const merged = { ...defaults };
13
+ for (const [key, value] of Object.entries(overrides)) {
14
+ if (value === void 0) continue;
15
+ merged[key] = isGroup(value) && isGroup(merged[key]) ? mergeStrings(merged[key], value) : value;
16
+ }
17
+ return merged;
18
+ }
8
19
  var DefaultLink = ({ href, ...rest }) => /* @__PURE__ */ jsx("a", {
9
20
  href: safeUrl(href),
10
21
  ...rest
11
22
  });
12
23
  /** The provider's link slot, with a plain anchor fallback. */
13
24
  function useLink() {
14
- return useContext(UIContext).slots.link ?? DefaultLink;
25
+ return useContext(SlotsContext).link ?? DefaultLink;
15
26
  }
16
27
  var defaultUseRunFile = () => ({
17
28
  data: void 0,
@@ -84,6 +95,13 @@ var DEFAULTS = {
84
95
  remove: "Remove",
85
96
  sort: "Sort",
86
97
  userAvatar: "User avatar",
98
+ presence: {
99
+ online: "online",
100
+ offline: "offline",
101
+ busy: "busy",
102
+ away: "away"
103
+ },
104
+ withPresence: (name, presence) => `${name}, ${presence}`,
87
105
  moreInfo: "More information",
88
106
  actions: "Actions",
89
107
  edit: "Edit",
@@ -92,9 +110,12 @@ var DEFAULTS = {
92
110
  clearSearch: "Clear search",
93
111
  filterPlaceholder: "Filter…",
94
112
  breadcrumb: "Breadcrumb",
113
+ showFullPath: "Show full path",
95
114
  yes: "Yes",
96
115
  no: "No",
97
116
  opensInNewTab: "(opens in a new tab)",
117
+ codeEditor: "Code editor",
118
+ readOnlyText: "This text is read-only.",
98
119
  resizePanel: "Resize panel",
99
120
  panelWidth: (px) => `${px} pixels wide`,
100
121
  refresh: "Refresh",
@@ -106,7 +127,8 @@ var DEFAULTS = {
106
127
  noOptionsFound: "No options found",
107
128
  showOptions: "Show options",
108
129
  add: (text) => `Add “${text}”`,
109
- limitReached: (max) => `Up to ${max}`
130
+ limitReached: (max) => `Up to ${max}`,
131
+ removeValue: (label) => `Remove ${label}`
110
132
  },
111
133
  datePicker: {
112
134
  pickDate: "Pick a date",
@@ -176,9 +198,9 @@ var DEFAULTS = {
176
198
  top: "Top",
177
199
  clearSelection: "Clear selection",
178
200
  copyLines: (count) => count === 1 ? "Copy 1 line" : `Copy ${count} lines`,
179
- copyAll: "Copy All",
180
- hideDebug: "Hide Debug",
181
- showDebug: "Show Debug",
201
+ copyAll: "Copy all",
202
+ hideDebug: "Hide debug",
203
+ showDebug: "Show debug",
182
204
  filterLogs: "Filter logs",
183
205
  beginningOfLog: "Beginning of log",
184
206
  loadingOlderEntries: "Loading older entries…",
@@ -195,7 +217,8 @@ var DEFAULTS = {
195
217
  endBeforeStart: "End time must be after the start time.",
196
218
  endInFuture: "End time cannot be in the future.",
197
219
  follow: "Follow",
198
- following: "Following"
220
+ following: "Following",
221
+ selectLine: (line) => `Select line ${line}`
199
222
  },
200
223
  dag: {
201
224
  workflow: "Workflow",
@@ -203,7 +226,7 @@ var DEFAULTS = {
203
226
  status: "Status",
204
227
  runtime: "Runtime",
205
228
  submitted: "Submitted",
206
- resetView: "Reset View",
229
+ resetView: "Reset view",
207
230
  previousGraph: "Back to the previous graph",
208
231
  nextGraph: "Forward to the next graph",
209
232
  matrixOf: (name) => `Matrix: ${name}`,
@@ -227,6 +250,23 @@ var DEFAULTS = {
227
250
  warning: "Warning",
228
251
  notice: "Notice"
229
252
  },
253
+ annotationsLabel: ({ error, warning, notice }) => `Annotations: ${[
254
+ [
255
+ error,
256
+ "error",
257
+ "errors"
258
+ ],
259
+ [
260
+ warning,
261
+ "warning",
262
+ "warnings"
263
+ ],
264
+ [
265
+ notice,
266
+ "notice",
267
+ "notices"
268
+ ]
269
+ ].filter(([count]) => count).map(([count, one, many]) => `${count} ${count === 1 ? one : many}`).join(", ")}`,
230
270
  annotationSource: (job, step) => `in ${job} → ${step}`,
231
271
  stepNumber: (index) => `step ${index}`
232
272
  },
@@ -245,12 +285,13 @@ var DEFAULTS = {
245
285
  select: (name) => `Select ${name}`,
246
286
  viewDetails: "View details",
247
287
  openFolder: "Open folder",
288
+ link: "link",
248
289
  detailsTab: "Details",
249
290
  previewTab: "Preview",
250
291
  preview: "Preview",
251
292
  openFullPreview: "Open full preview",
252
293
  previewLayout: "Preview layout",
253
- quickLook: "Quick Look",
294
+ compact: "Compact",
254
295
  fullWindow: "Full window",
255
296
  streamed: "Streamed",
256
297
  streamedTooltip: "Streamed securely to your browser over a short-lived signed URL — never written to disk.",
@@ -298,12 +339,12 @@ var DEFAULTS = {
298
339
  uri: "URI",
299
340
  cors: {
300
341
  explanation: {
301
- title: "CORS Configuration Required",
342
+ title: "CORS configuration required",
302
343
  description: "This storage location cannot be accessed from the browser because it is missing Cross-Origin Resource Sharing (CORS) rules.",
303
344
  action: "You can automatically configure these rules to allow access from this domain.",
304
345
  note: "Note: Changes may take up to 30 seconds to propagate."
305
346
  },
306
- actions: { addRules: "Add CORS Rules" },
347
+ actions: { addRules: "Add CORS rules" },
307
348
  propagating: {
308
349
  title: "Propagating CORS rules",
309
350
  description: "The storage provider is rolling out the new rules to its endpoints. This usually completes within a minute.",
@@ -341,7 +382,7 @@ var DEFAULTS = {
341
382
  noItemsForDeletion: "No items selected for deletion.",
342
383
  deleting: "Deleting item(s) from storage...",
343
384
  deleteSomeFailed: "Failed to delete one or more items. Please try again.",
344
- deleteSuccess: "Deleted item(s) from storage successfully!",
385
+ deleteSuccess: "Deleted from storage.",
345
386
  deleteFailed: (message) => `Failed to delete item(s): ${message}`,
346
387
  noFilesToUpload: "No files to upload or target path not selected.",
347
388
  invalidUploadTarget: "This target path is not valid for upload.",
@@ -351,14 +392,16 @@ var DEFAULTS = {
351
392
  corsNoStorage: "No storage selected",
352
393
  corsAdded: "CORS rules added successfully",
353
394
  corsPropagating: "CORS rules were added, but are still propagating. Try again in a moment.",
354
- previewUnsupported: "Preview is not supported for this storage."
395
+ previewUnsupported: "Preview is not supported for this storage.",
396
+ loadFailed: (name, message) => `Failed to load contents for ${name}: ${message}`,
397
+ unknownError: "Unknown error"
355
398
  },
356
399
  chrome: {
357
400
  explorer: "Explorer",
358
401
  upload: "Upload",
359
402
  downloadFromBrowser: "From browser",
360
403
  access: "Access",
361
- manageAccess: "Manage Access",
404
+ manageAccess: "Manage access",
362
405
  selectAll: "Select all",
363
406
  name: "Name",
364
407
  size: "Size",
@@ -373,21 +416,25 @@ var DEFAULTS = {
373
416
  storageClass: "Storage class",
374
417
  details: "Details",
375
418
  selectFiles: "Select files",
376
- selectFolder: "Select folder"
419
+ selectFolder: "Select folder",
420
+ files: "Files",
421
+ folders: "Folders",
422
+ location: "Location",
423
+ shareHelp: "This will generate a pre-signed URL for this file. Anyone with this link can temporarily access and download the file, even if they don't have an account. The link will automatically expire after 12 hours."
377
424
  },
378
425
  confirmUpload: {
379
- title: "Confirm Upload",
426
+ title: "Confirm upload",
380
427
  text: (path) => `Please confirm the following objects you want to upload to ${path}.`,
381
428
  defaultPath: "the selected path",
382
429
  noPath: "No path selected",
383
430
  confirm: "Confirm",
384
431
  target: "Target:",
385
- sizeLimitTitle: "Upload Size Limit Exceeded",
432
+ sizeLimitTitle: "Upload size limit exceeded",
386
433
  sizeLimitBody: (total, max) => `The total upload size (${total}) exceeds the maximum allowed limit of ${max}.`,
387
434
  sizeLimitHint: "Please reduce the number of files or upload them in smaller batches."
388
435
  },
389
436
  confirmDelete: {
390
- title: "Confirm Delete",
437
+ title: "Confirm delete",
391
438
  text: "Are you sure you want to delete the following item(s)? Folders are deleted with everything inside them. This action cannot be undone."
392
439
  },
393
440
  empty: {
@@ -400,14 +447,14 @@ var DEFAULTS = {
400
447
  shareThisFile: "Share this file"
401
448
  },
402
449
  upload: {
403
- inQueue: (position, total) => `In Queue (#${position} of ${total})`,
450
+ inQueue: (position, total) => `In queue (#${position} of ${total})`,
404
451
  queuedShort: (position, total) => `Queued #${position} / ${total}`,
405
452
  destination: "Destination:",
406
453
  eta: "ETA:",
407
454
  uploading: "Uploading...",
408
- completeTitle: "Upload Complete!",
409
- failedTitle: "Upload Failed",
410
- unknownTitle: "Unknown Status",
455
+ completeTitle: "Upload complete",
456
+ failedTitle: "Upload failed",
457
+ unknownTitle: "Unknown status",
411
458
  unknownShort: "Unknown",
412
459
  canceled: "Canceled",
413
460
  completed: "Completed",
@@ -420,14 +467,14 @@ var DEFAULTS = {
420
467
  minimizeDetails: "Minimize details",
421
468
  sessionNotQueued: (id, status) => `Upload session with ID ${id} is not queued, current status is ${status}`,
422
469
  allCanceled: (count) => `All ${count} file(s) were canceled by user.`,
423
- someUploaded: (count) => `${count} file(s) uploaded successfully!`,
470
+ someUploaded: (count) => `${count} file(s) uploaded.`,
424
471
  someCanceled: (count) => `${count} file(s) canceled by user.`,
425
- allUploaded: "Upload file(s) successfully!",
472
+ allUploaded: "Uploaded the file(s).",
426
473
  failedSummary: (failed, total) => `${failed}/${total} files failed to upload:`,
427
474
  failReasonGeneric: "The file(s) may be too large or the connection may have been interrupted.",
428
475
  refreshFailed: (name, message) => `Failed to refresh storage data for ${name}. ${message}. Please try again.`,
429
476
  unknownError: "Unknown error",
430
- overallProgress: "Overall Progress",
477
+ overallProgress: "Overall progress",
431
478
  cancelFile: (name) => `Cancel ${name}`,
432
479
  confirmCancelFile: "Cancel?",
433
480
  confirmCancelAll: "Cancel all uploading files?",
@@ -451,8 +498,6 @@ var DEFAULTS = {
451
498
  allSteps: "All steps",
452
499
  stepDone: "Done",
453
500
  stepNeedsAttention: "Needs a fix",
454
- previousStep: "Go to previous step",
455
- nextStep: "Go to next step",
456
501
  runWizard: "Execute",
457
502
  fixErrorsToContinue: "Please fix errors before proceeding",
458
503
  stepFailed: "An error occurred",
@@ -474,6 +519,9 @@ var DEFAULTS = {
474
519
  labelId: "ID",
475
520
  labelUrl: "URL",
476
521
  couldNotLoad: (noun) => `Couldn't load ${noun}`,
522
+ data: "data",
523
+ count: (count, noun) => `${count} ${noun}`,
524
+ matchCount: (matches, total, nounPlural) => `${matches} of ${total} ${nounPlural}`,
477
525
  displayOptions: "Display options",
478
526
  grouping: "Grouping",
479
527
  ordering: "Ordering",
@@ -483,6 +531,7 @@ var DEFAULTS = {
483
531
  descending: "Descending",
484
532
  columnHeaders: "Column headers",
485
533
  showColumnHeaders: "Show column headers",
534
+ selectAll: "Select all",
486
535
  showActions: "Show actions",
487
536
  showRowActions: "Show row actions",
488
537
  alwaysShowActions: "Always show actions",
@@ -520,28 +569,32 @@ var DEFAULTS = {
520
569
  },
521
570
  slots: {}
522
571
  };
523
- var UIContext = createContext(DEFAULTS);
572
+ var StringsContext = createContext(DEFAULTS.strings);
573
+ var NavigationContext = createContext(DEFAULTS.navigation);
574
+ var DataContext = createContext(DEFAULTS.data);
575
+ var SlotsContext = createContext(DEFAULTS.slots);
576
+ var EngineContext = createContext(void 0);
524
577
  function useStrings() {
525
- return useContext(UIContext).strings;
578
+ return useContext(StringsContext);
526
579
  }
527
580
  function useNavigation() {
528
- return useContext(UIContext).navigation;
581
+ return useContext(NavigationContext);
529
582
  }
530
583
  function useWorkflowJsonResolver() {
531
- return useContext(UIContext).data.resolveWorkflowJson;
584
+ return useContext(DataContext).resolveWorkflowJson;
532
585
  }
533
586
  function useRepoSuggestions() {
534
- return useContext(UIContext).data.repoSuggestions;
587
+ return useContext(DataContext).repoSuggestions;
535
588
  }
536
589
  var NO_ACTIONS = {};
537
590
  function useWorkflowActions() {
538
- return useContext(UIContext).data.workflowActions ?? NO_ACTIONS;
591
+ return useContext(DataContext).workflowActions ?? NO_ACTIONS;
539
592
  }
540
593
  function useSecretVariablesResolver() {
541
- return useContext(UIContext).data.resolveSecretVariables;
594
+ return useContext(DataContext).resolveSecretVariables;
542
595
  }
543
596
  function useSlots() {
544
- return useContext(UIContext).slots;
597
+ return useContext(SlotsContext);
545
598
  }
546
599
  var loadedEngines = /* @__PURE__ */ new WeakMap();
547
600
  function loadEngine(load) {
@@ -563,18 +616,18 @@ function resolveEngine(source) {
563
616
  }
564
617
  /** The engine when one is provided and `enabled`; suspends while a loader resolves. */
565
618
  function useOptionalWorkflowEngine(enabled = true) {
566
- const source = useContext(UIContext).engine;
619
+ const source = useContext(EngineContext);
567
620
  if (!enabled || !source) return;
568
621
  return resolveEngine(source);
569
622
  }
570
623
  function useWorkflowEngine() {
571
- const source = useContext(UIContext).engine;
624
+ const source = useContext(EngineContext);
572
625
  if (!source) throw new Error("Workflow forms and graphs need a UIProvider with an engine.");
573
626
  return resolveEngine(source);
574
627
  }
575
628
  /** The engine once it has loaded, without suspending; renders again when a loader resolves. */
576
629
  function useLoadedWorkflowEngine() {
577
- const source = useContext(UIContext).engine;
630
+ const source = useContext(EngineContext);
578
631
  const [, setLoaded] = useState(0);
579
632
  const entry = typeof source === "function" ? loadEngine(source) : void 0;
580
633
  const engine = typeof source === "function" ? entry?.engine : source;
@@ -598,114 +651,71 @@ function useWorkflowEditing() {
598
651
  }
599
652
  /** Resolves the engine without suspending, for async callers such as editor completions. */
600
653
  function useWorkflowEngineLoader() {
601
- const source = useContext(UIContext).engine;
654
+ const source = useContext(EngineContext);
602
655
  return useCallback(async () => {
603
656
  if (!source) return;
604
657
  return typeof source === "function" ? loadEngine(source).promise : source;
605
658
  }, [source]);
606
659
  }
607
660
  function useProvisionCorsRules() {
608
- return useContext(UIContext).data.provisionCorsRules;
661
+ return useContext(DataContext).provisionCorsRules;
609
662
  }
610
663
  function useRunFile(slug, path, options) {
611
- const { useRunFile: boundUseRunFile } = useContext(UIContext).data;
664
+ const { useRunFile: boundUseRunFile } = useContext(DataContext);
612
665
  return boundUseRunFile(slug, path, options);
613
666
  }
614
667
  function usePersistedState(key, defaultValue) {
615
- const { usePersistedState: boundUsePersistedState } = useContext(UIContext).data;
668
+ const { usePersistedState: boundUsePersistedState } = useContext(DataContext);
616
669
  return boundUsePersistedState(key, defaultValue);
617
670
  }
618
- function UIProvider({ strings, navigation, data, slots, engine, children }) {
671
+ function useByValue(value) {
672
+ const ref = useRef(value);
673
+ if (ref.current !== value && !dequal(ref.current, value)) ref.current = value;
674
+ return ref.current;
675
+ }
676
+ function useMerged(compute, input) {
677
+ const stableInput = useByValue(input);
678
+ const ref = useRef(null);
679
+ if (!ref.current || ref.current.input !== stableInput) ref.current = {
680
+ input: stableInput,
681
+ value: compute()
682
+ };
683
+ return ref.current.value;
684
+ }
685
+ function UIProvider({ strings, navigation, data, slots, engine: engineProp, children }) {
686
+ const [firstLoader] = useState(() => typeof engineProp === "function" ? engineProp : void 0);
687
+ const engine = typeof engineProp === "function" ? firstLoader ?? engineProp : engineProp;
619
688
  useEffect(() => {
620
689
  if (typeof engine === "function") loadEngine(engine);
621
690
  }, [engine]);
622
- const value = useMemo(() => ({
623
- strings: {
624
- modal: {
625
- ...DEFAULTS.strings.modal,
626
- ...strings?.modal
627
- },
628
- common: {
629
- ...DEFAULTS.strings.common,
630
- ...strings?.common
631
- },
632
- dropdown: {
633
- ...DEFAULTS.strings.dropdown,
634
- ...strings?.dropdown
635
- },
636
- datePicker: {
637
- ...DEFAULTS.strings.datePicker,
638
- ...strings?.datePicker
639
- },
640
- colorInput: {
641
- ...DEFAULTS.strings.colorInput,
642
- ...strings?.colorInput
643
- },
644
- oneTimeCode: {
645
- ...DEFAULTS.strings.oneTimeCode,
646
- ...strings?.oneTimeCode
647
- },
648
- theme: {
649
- ...DEFAULTS.strings.theme,
650
- ...strings?.theme
651
- },
652
- logviewer: {
653
- ...DEFAULTS.strings.logviewer,
654
- ...strings?.logviewer
655
- },
656
- dag: {
657
- ...DEFAULTS.strings.dag,
658
- ...strings?.dag
659
- },
660
- jobActions: {
661
- ...DEFAULTS.strings.jobActions,
662
- ...strings?.jobActions
663
- },
664
- graphEditor: {
665
- ...DEFAULTS.strings.graphEditor,
666
- ...strings?.graphEditor
667
- },
668
- inputsEditor: {
669
- ...DEFAULTS.strings.inputsEditor,
670
- ...strings?.inputsEditor
671
- },
672
- fileExplorer: {
673
- ...DEFAULTS.strings.fileExplorer,
674
- ...strings?.fileExplorer
675
- },
676
- form: {
677
- ...DEFAULTS.strings.form,
678
- ...strings?.form
679
- },
680
- time: {
681
- ...DEFAULTS.strings.time,
682
- ...strings?.time
683
- },
684
- list: {
685
- ...DEFAULTS.strings.list,
686
- ...strings?.list
687
- }
688
- },
689
- navigation: {
690
- ...DEFAULTS.navigation,
691
- ...navigation
692
- },
693
- data: {
694
- ...DEFAULTS.data,
695
- ...data
696
- },
697
- slots: slots ?? DEFAULTS.slots,
698
- engine
699
- }), [
700
- strings,
701
- navigation,
702
- data,
703
- slots,
704
- engine
705
- ]);
706
- return /* @__PURE__ */ jsxs(UIContext.Provider, {
707
- value,
708
- children: [/* @__PURE__ */ jsx(TooltipProvider, { children }), /* @__PURE__ */ jsx(Toaster, {})]
691
+ const mergedStrings = useMerged(() => mergeStrings(DEFAULTS.strings, strings), strings);
692
+ const mergedData = useMerged(() => ({
693
+ ...DEFAULTS.data,
694
+ ...data
695
+ }), data);
696
+ const stableSlots = useByValue(slots ?? DEFAULTS.slots);
697
+ const navigationRef = useRef(navigation);
698
+ navigationRef.current = navigation;
699
+ const [stableNavigation] = useState(() => ({
700
+ goTo: (to) => (navigationRef.current?.goTo ?? DEFAULTS.navigation.goTo)(to),
701
+ openStepSource: (uses, sourceUrl) => (navigationRef.current?.openStepSource ?? DEFAULTS.navigation.openStepSource)(uses, sourceUrl),
702
+ openExternal: (href) => (navigationRef.current?.openExternal ?? DEFAULTS.navigation.openExternal)(href)
703
+ }));
704
+ return /* @__PURE__ */ jsx(StringsContext, {
705
+ value: mergedStrings,
706
+ children: /* @__PURE__ */ jsx(NavigationContext, {
707
+ value: stableNavigation,
708
+ children: /* @__PURE__ */ jsx(DataContext, {
709
+ value: mergedData,
710
+ children: /* @__PURE__ */ jsx(SlotsContext, {
711
+ value: stableSlots,
712
+ children: /* @__PURE__ */ jsxs(EngineContext, {
713
+ value: engine,
714
+ children: [/* @__PURE__ */ jsx(TooltipProvider, { children }), /* @__PURE__ */ jsx(Toaster, {})]
715
+ })
716
+ })
717
+ })
718
+ })
709
719
  });
710
720
  }
711
721
  //#endregion
@@ -1,4 +1,5 @@
1
1
  import { cx } from "../cx.js";
2
+ import { focusOutline } from "./fieldBox.js";
2
3
  import { jsx } from "react/jsx-runtime";
3
4
  import { Radio } from "@base-ui/react/radio";
4
5
  import { RadioGroup } from "@base-ui/react/radio-group";
@@ -8,7 +9,7 @@ import { RadioGroup } from "@base-ui/react/radio-group";
8
9
  function Radio$1({ className, ...props }) {
9
10
  return /* @__PURE__ */ jsx(Radio.Root, {
10
11
  ...props,
11
- className: cx("flex size-4 shrink-0 items-center justify-center rounded-full border border-(--theme-border) bg-(--theme-input-bg) cursor-pointer outline-none transition-colors", "data-checked:border-(--theme-accent) data-checked:bg-(--theme-accent)", "focus-visible:ring-2 focus-visible:ring-(--theme-focus-ring) aria-invalid:border-(--theme-error)", "data-disabled:cursor-not-allowed data-disabled:opacity-50", className),
12
+ className: cx("flex size-4 shrink-0 items-center justify-center rounded-full border border-(--theme-border-strong) bg-(--theme-input-bg) cursor-pointer transition-colors motion-reduce:transition-none", focusOutline, "data-checked:border-(--theme-accent) data-checked:bg-(--theme-accent)", "aria-invalid:border-(--theme-error)", "data-disabled:cursor-not-allowed data-disabled:opacity-50", className),
12
13
  children: /* @__PURE__ */ jsx(Radio.Indicator, { className: "size-1.5 rounded-full bg-(--theme-accent-text)" })
13
14
  });
14
15
  }
@@ -1,20 +1,16 @@
1
1
  import { cx } from "../cx.js";
2
- import { RefreshIcon } from "../icons.js";
3
2
  import { buttonClasses } from "./buttonClasses.js";
3
+ import { RefreshIcon } from "../icons.js";
4
4
  import { Tooltip } from "./Tooltip.js";
5
5
  import { useStrings } from "./Provider.js";
6
6
  import { useRelativeTime } from "./relativeTime.js";
7
7
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
8
- import { useEffect, useRef, useState } from "react";
8
+ import { useState } from "react";
9
9
  //#region src/components/RefreshButton.tsx
10
10
  /** Fetches again on demand, and says so while it does, out loud too. */
11
11
  function RefreshButton({ onRefresh, refreshing = false, updatedAt, size = "md", iconOnly = false }) {
12
12
  const { common: t } = useStrings();
13
13
  const [pending, setPending] = useState(false);
14
- const mounted = useRef(true);
15
- useEffect(() => () => {
16
- mounted.current = false;
17
- }, []);
18
14
  const busy = refreshing || pending;
19
15
  const ago = useRelativeTime(updatedAt);
20
16
  const refresh = () => {
@@ -22,7 +18,7 @@ function RefreshButton({ onRefresh, refreshing = false, updatedAt, size = "md",
22
18
  const result = onRefresh();
23
19
  if (result instanceof Promise) {
24
20
  setPending(true);
25
- result.finally(() => mounted.current && setPending(false));
21
+ result.finally(() => setPending(false));
26
22
  }
27
23
  };
28
24
  const button = /* @__PURE__ */ jsxs("button", {
@@ -38,7 +34,10 @@ function RefreshButton({ onRefresh, refreshing = false, updatedAt, size = "md",
38
34
  children: [/* @__PURE__ */ jsx(RefreshIcon, {
39
35
  "aria-hidden": "true",
40
36
  className: cx("shrink-0 motion-reduce:animate-none motion-reduce:transition-none", busy ? "animate-spin" : "transition-transform duration-300 group-hover:rotate-180")
41
- }), !iconOnly && (ago ? t.updated(ago) : t.refresh)]
37
+ }), !iconOnly && (ago ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("span", {
38
+ className: "sr-only",
39
+ children: [t.refresh, ". "]
40
+ }), t.updated(ago)] }) : t.refresh)]
42
41
  });
43
42
  return /* @__PURE__ */ jsxs(Fragment, { children: [iconOnly ? /* @__PURE__ */ jsx(Tooltip, {
44
43
  content: t.refresh,
@@ -3,7 +3,7 @@ import { jsx } from "react/jsx-runtime";
3
3
  function RequiredMark() {
4
4
  return /* @__PURE__ */ jsx("span", {
5
5
  "aria-hidden": "true",
6
- className: "ml-0.5 text-(--theme-error)",
6
+ className: "ml-0.5 text-(--theme-error-text)",
7
7
  children: "*"
8
8
  });
9
9
  }
@@ -75,7 +75,7 @@ function Section({ title, description, beside, actions, variant = "plain", colla
75
75
  children: /* @__PURE__ */ jsxs(Collapsible.Trigger, {
76
76
  ...titleProps,
77
77
  "aria-describedby": describedBy,
78
- className: cx("group flex min-w-0 cursor-pointer items-center gap-1 text-left", fill && "w-full", titleClasses[variant], foldedTitleClasses[variant]),
78
+ className: cx("group flex min-w-0 cursor-pointer items-center gap-1 rounded-sm text-left focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--theme-focus)", fill && "w-full", titleClasses[variant], foldedTitleClasses[variant]),
79
79
  children: [/* @__PURE__ */ jsx(ChevronRightIcon, {
80
80
  "aria-hidden": "true",
81
81
  className: cx("shrink-0 transition-transform group-data-panel-open:rotate-90 motion-reduce:transition-none", "px-1 text-[1.25rem]")
@@ -1,14 +1,9 @@
1
1
  import { Select as BaseSelect } from '@base-ui/react/select';
2
- import type { ReactElement, ReactNode } from 'react';
2
+ import { type ReactElement, type ReactNode } from 'react';
3
+ import { type ComboboxItem } from './comboboxItems.js';
3
4
  import { type FieldBoxSize } from './fieldBox.js';
4
- export interface SelectItem<Value> {
5
- value: Value;
6
- label: string;
7
- /** A second line under the label, such as what an option does. */
8
- description?: string | undefined;
9
- icon?: ReactNode;
10
- disabled?: boolean | undefined;
11
- }
5
+ /** An option of a Select: the same shape as a Combobox's, so a list moves between them as is. */
6
+ export type SelectItem<Value> = ComboboxItem<Value>;
12
7
  export type SelectProps<Value, Multiple extends boolean | undefined = false> = Omit<BaseSelect.Root.Props<Value, Multiple>, 'items' | 'children'> & {
13
8
  items: readonly SelectItem<Value>[];
14
9
  placeholder?: string | undefined;
@@ -1,15 +1,18 @@
1
1
  import { cx } from "../cx.js";
2
2
  import { CheckIcon, ChevronDownIcon } from "../icons.js";
3
- import { panelClassName, panelItemClassName, positionerClassName } from "./floating.js";
3
+ import { panelClassName, positionerClassName } from "./floating.js";
4
4
  import { Tooltip } from "./Tooltip.js";
5
5
  import { fieldBox } from "./fieldBox.js";
6
+ import { pickerItemClassName } from "./comboboxItems.js";
6
7
  import { jsx, jsxs } from "react/jsx-runtime";
8
+ import { useId } from "react";
7
9
  import { Select } from "@base-ui/react/select";
8
10
  //#region src/components/Select.tsx
9
11
  var triggerClassName = "flex cursor-pointer items-center justify-between gap-2 pr-1.5 text-left";
10
12
  /** Picks one value, or several with `multiple`, from a short list. Use
11
13
  * Combobox when the list is long enough to need filtering. */
12
14
  function Select$1({ items, placeholder, className, "aria-label": ariaLabel, "aria-labelledby": labelledBy, "aria-describedby": describedBy, "aria-invalid": invalid, "aria-required": required, trigger, triggerTooltip, size = "md", onItemHighlighted, ...rootProps }) {
15
+ const uid = useId();
13
16
  const labelOf = (value) => items.find((item) => Object.is(item.value, value))?.label;
14
17
  const triggerProps = {
15
18
  "aria-label": ariaLabel,
@@ -50,26 +53,36 @@ function Select$1({ items, placeholder, className, "aria-label": ariaLabel, "ari
50
53
  className: cx("min-w-(--anchor-width) max-w-[min(20rem,var(--available-width))]", panelClassName),
51
54
  children: /* @__PURE__ */ jsx(Select.List, {
52
55
  className: "max-h-[min(15rem,var(--available-height))] overflow-y-auto py-1",
53
- children: items.map((item) => /* @__PURE__ */ jsxs(Select.Item, {
56
+ children: items.map((item, index) => /* @__PURE__ */ jsxs(Select.Item, {
54
57
  value: item.value,
55
58
  disabled: item.disabled,
59
+ "aria-labelledby": `${uid}${index}label`,
60
+ "aria-describedby": item.description && `${uid}${index}description`,
56
61
  onFocus: onItemHighlighted && (() => onItemHighlighted(item.value)),
57
- className: cx("grid grid-cols-[1rem_1fr]", panelItemClassName),
62
+ className: pickerItemClassName,
58
63
  children: [
59
- /* @__PURE__ */ jsx(Select.ItemIndicator, {
60
- className: "col-start-1",
61
- children: /* @__PURE__ */ jsx(CheckIcon, { className: "size-3.5" })
64
+ item.icon && /* @__PURE__ */ jsx("span", {
65
+ className: "flex shrink-0 items-center",
66
+ children: item.icon
62
67
  }),
63
68
  /* @__PURE__ */ jsxs("span", {
64
- className: "col-start-2 flex min-w-0 items-center gap-2",
65
- children: [item.icon, /* @__PURE__ */ jsx(Select.ItemText, {
69
+ className: "flex min-w-0 flex-col",
70
+ children: [/* @__PURE__ */ jsx(Select.ItemText, {
71
+ id: `${uid}${index}label`,
66
72
  className: "truncate",
67
73
  children: item.label
74
+ }), item.description && /* @__PURE__ */ jsx("span", {
75
+ id: `${uid}${index}description`,
76
+ className: "text-xs leading-snug text-(--theme-muted-text-color)",
77
+ children: item.description
68
78
  })]
69
79
  }),
70
- item.description && /* @__PURE__ */ jsx("span", {
71
- className: "col-start-2 text-xs text-(--theme-muted-text-color)",
72
- children: item.description
80
+ /* @__PURE__ */ jsx(Select.ItemIndicator, {
81
+ className: "ml-auto flex shrink-0 items-center",
82
+ children: /* @__PURE__ */ jsx(CheckIcon, {
83
+ "aria-hidden": "true",
84
+ className: "size-3.5"
85
+ })
73
86
  })
74
87
  ]
75
88
  }, String(item.value)))
@@ -4,5 +4,5 @@ export declare function SettingModeOption({ value, label, description, disabled,
4
4
  value: string;
5
5
  label: string;
6
6
  description: string;
7
- disabled?: boolean;
7
+ disabled?: boolean | undefined;
8
8
  }): import("react").JSX.Element;