@parallelworks/ui 0.17.0 → 0.19.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 (169) hide show
  1. package/README.md +86 -6
  2. package/dist/ai/adapter/memoryStore.d.ts +8 -0
  3. package/dist/ai/adapter/mock/index.d.ts +2 -0
  4. package/dist/ai/adapter/mock/index.js +81 -0
  5. package/dist/ai/adapter/mock/mockAdapter.d.ts +4 -0
  6. package/dist/ai/adapter/openai/createOpenAIStream.d.ts +9 -0
  7. package/dist/ai/adapter/openai/errors.d.ts +3 -0
  8. package/dist/ai/adapter/openai/index.d.ts +6 -0
  9. package/dist/ai/adapter/openai/index.js +334 -0
  10. package/dist/ai/adapter/openai/openaiAdapter.d.ts +9 -0
  11. package/dist/ai/adapter/openai/responses.d.ts +4 -0
  12. package/dist/ai/adapter/openai/sse.d.ts +24 -0
  13. package/dist/ai/adapter/openai/wire.d.ts +40 -0
  14. package/dist/ai/adapter/types.d.ts +131 -0
  15. package/dist/ai/agent/classifier.d.ts +2 -0
  16. package/dist/ai/agent/diff.d.ts +35 -0
  17. package/dist/ai/agent/diffHighlight.d.ts +6 -0
  18. package/dist/ai/agent/index.d.ts +6 -0
  19. package/dist/ai/agent/permissions.d.ts +11 -0
  20. package/dist/ai/agent/toolfmt.d.ts +18 -0
  21. package/dist/ai/agent/transcript.d.ts +38 -0
  22. package/dist/ai/ai.css +325 -0
  23. package/dist/ai/components/AllocationSelector.d.ts +4 -0
  24. package/dist/ai/components/AttachmentManager.d.ts +1 -0
  25. package/dist/ai/components/AttachmentUpload.d.ts +24 -0
  26. package/dist/ai/components/BlockedGroupBanner.d.ts +1 -0
  27. package/dist/ai/components/BranchNavigator.d.ts +8 -0
  28. package/dist/ai/components/ChatEmptyState.d.ts +3 -0
  29. package/dist/ai/components/ChatInput.d.ts +45 -0
  30. package/dist/ai/components/ChatLayout.d.ts +5 -0
  31. package/dist/ai/components/ChatMessage.d.ts +24 -0
  32. package/dist/ai/components/ChatMessageList.d.ts +35 -0
  33. package/dist/ai/components/ChatSidebar.d.ts +5 -0
  34. package/dist/ai/components/ChatThread.d.ts +3 -0
  35. package/dist/ai/components/ComposerChrome.d.ts +18 -0
  36. package/dist/ai/components/ComposerFrame.d.ts +16 -0
  37. package/dist/ai/components/DragOverlay.d.ts +5 -0
  38. package/dist/ai/components/ModelSelector.d.ts +6 -0
  39. package/dist/ai/components/ShareDialog.d.ts +11 -0
  40. package/dist/ai/components/SlashMenu.d.ts +28 -0
  41. package/dist/ai/components/agent/ActivityLine.d.ts +21 -0
  42. package/dist/ai/components/agent/AgentMessageParts.d.ts +54 -0
  43. package/dist/ai/components/agent/PermissionPicker.d.ts +11 -0
  44. package/dist/ai/components/attachmentKeys.d.ts +4 -0
  45. package/dist/ai/core/ChatProvider.d.ts +66 -0
  46. package/dist/ai/core/KeyboardShortcutsProvider.d.ts +5 -0
  47. package/dist/ai/core/chatReducer.d.ts +114 -0
  48. package/dist/ai/core/config.d.ts +47 -0
  49. package/dist/ai/core/events.d.ts +1 -0
  50. package/dist/ai/core/exportConversation.d.ts +4 -0
  51. package/dist/ai/core/greeting.d.ts +3 -0
  52. package/dist/ai/core/parts.d.ts +11 -0
  53. package/dist/ai/core/useDragDrop.d.ts +14 -0
  54. package/dist/ai/core/useKeyboardShortcuts.d.ts +12 -0
  55. package/dist/ai/core/useSSEStream.d.ts +34 -0
  56. package/dist/ai/index.d.ts +40 -0
  57. package/dist/ai/index.js +6645 -0
  58. package/dist/ai/strings.d.ts +167 -0
  59. package/dist/ai/types.d.ts +236 -0
  60. package/dist/ai/ui/Avatar.d.ts +8 -0
  61. package/dist/ai/ui/Dropdown.d.ts +31 -0
  62. package/dist/ai/ui/Markdown.d.ts +8 -0
  63. package/dist/ai/ui/Notice.d.ts +21 -0
  64. package/dist/ai/ui/buttons.d.ts +1 -0
  65. package/dist/ai/ui/codeBreaks.d.ts +16 -0
  66. package/dist/ai/ui/prose.d.ts +1 -0
  67. package/dist/ai/ui/sidebar.d.ts +81 -0
  68. package/dist/ai/utils.d.ts +4 -0
  69. package/dist/assets/{editor.worker-CuBRIwi-.js → editor.worker-BmHUIVG4.js} +194 -163
  70. package/dist/assets/{json.worker-8ytS02vz.js → json.worker-D8bJ92nw.js} +384 -338
  71. package/dist/assets/{yaml.worker-DJC-VUcv.js → yaml.worker-C4gyGAko.js} +15657 -13823
  72. package/dist/chunks/{CodePreviewEditor-UAtnpmOV.js → CodePreviewEditor-YqQBz1YL.js} +2 -2
  73. package/dist/chunks/ConfirmModal-aOR4O1QE.js +79 -0
  74. package/dist/chunks/{lib-CUTRDpa6.js → FieldWrapper-Cszwg-4B.js} +52 -55
  75. package/dist/chunks/{CreateModal-BbV5cTj7.js → Markdown-CM-FenNE.js} +25 -97
  76. package/dist/chunks/Monaco-DJ8MW-Dq.js +110 -0
  77. package/dist/chunks/{PageHeader-MxuOs9cH.js → PageHeader-0kG_iypP.js} +170 -105
  78. package/dist/chunks/{Provider-DHmZ3v9i.js → Provider-CDYurraE.js} +60 -24
  79. package/dist/chunks/{SwitchToggle-BRQoEwLZ.js → SwitchToggle-DShNdcao.js} +143 -140
  80. package/dist/chunks/{Table-C6JdFFiJ.js → Table-DU2MW8xz.js} +6 -4
  81. package/dist/chunks/{Tooltip-n9w7Tkt1.js → Tooltip-K5HJr4_p.js} +32 -5
  82. package/dist/chunks/duration-BOv8Phl8.js +17 -0
  83. package/dist/chunks/{editor-mNznodJN.js → editor-Dk1rbV75.js} +33 -19
  84. package/dist/chunks/focus-D_iZJTW1.js +7 -0
  85. package/dist/chunks/{list-7k0eaI5N.js → list-CJm875m7.js} +497 -379
  86. package/dist/chunks/logviewer-BTKuQWzw.js +828 -0
  87. package/dist/chunks/memoryStore-CC91S5LP.js +152 -0
  88. package/dist/chunks/types-Yy0NrerF.js +11 -0
  89. package/dist/components/AddMenu.d.ts +1 -0
  90. package/dist/components/Avatar.d.ts +13 -0
  91. package/dist/components/Breadcrumbs.d.ts +1 -1
  92. package/dist/components/Dropdown.d.ts +3 -1
  93. package/dist/components/EmptyState.d.ts +1 -1
  94. package/dist/components/Indicator.d.ts +2 -2
  95. package/dist/components/Input.d.ts +1 -1
  96. package/dist/components/LetterBadge.d.ts +1 -1
  97. package/dist/components/MarkdownImpl.d.ts +1 -1
  98. package/dist/components/Provider.d.ts +18 -65
  99. package/dist/components/SettingRow.d.ts +1 -1
  100. package/dist/components/SettingsGroup.d.ts +1 -1
  101. package/dist/components/focus.d.ts +2 -0
  102. package/dist/components/keys.d.ts +12 -0
  103. package/dist/duration.d.ts +3 -0
  104. package/dist/editor/Monaco.d.ts +1 -20
  105. package/dist/editor/index.d.ts +2 -1
  106. package/dist/editor/index.js +2 -2
  107. package/dist/editor/yaml.d.ts +5 -0
  108. package/dist/engine.d.ts +98 -0
  109. package/dist/file-explorer/FileExplorer.d.ts +11 -2
  110. package/dist/file-explorer/FileExplorerContext.d.ts +1 -1
  111. package/dist/file-explorer/FilePreview/CodePreviewEditor.d.ts +1 -1
  112. package/dist/file-explorer/FilePreview/previewType.d.ts +1 -1
  113. package/dist/file-explorer/FileRow.d.ts +1 -1
  114. package/dist/file-explorer/helpers.d.ts +4 -4
  115. package/dist/file-explorer/index.d.ts +3 -3
  116. package/dist/file-explorer/index.js +632 -665
  117. package/dist/file-explorer/lib/types.d.ts +6 -1
  118. package/dist/file-explorer/lib/utils.d.ts +1 -3
  119. package/dist/file-explorer/useNearEnd.d.ts +1 -1
  120. package/dist/form/FieldWrapper.d.ts +2 -1
  121. package/dist/form/Fields/ResourceOptionIcon.d.ts +1 -1
  122. package/dist/form/Form.d.ts +7 -22
  123. package/dist/form/index.d.ts +11 -12
  124. package/dist/form/index.js +1333 -1454
  125. package/dist/form/lib.d.ts +6 -1
  126. package/dist/form/types/fieldComponentTypes.d.ts +4 -2
  127. package/dist/form/types/fieldTypes.d.ts +6 -20
  128. package/dist/form/useParsedOpts.d.ts +2 -2
  129. package/dist/form/utils/{slurmDuration.d.ts → duration.d.ts} +2 -2
  130. package/dist/{workflow → graph}/MatrixGroup.d.ts +2 -2
  131. package/dist/{workflow → graph}/index.d.ts +1 -1
  132. package/dist/{workflow → graph}/index.js +220 -185
  133. package/dist/{workflow → graph}/types.d.ts +3 -3
  134. package/dist/icons.d.ts +20 -21
  135. package/dist/icons.js +3 -3
  136. package/dist/index.d.ts +38 -39
  137. package/dist/index.js +355 -354
  138. package/dist/list/ListTable.d.ts +1 -1
  139. package/dist/list/ListViewControls.d.ts +2 -2
  140. package/dist/list/RowContextMenu.d.ts +9 -9
  141. package/dist/list/UserHoverCard.d.ts +45 -0
  142. package/dist/list/index.d.ts +9 -8
  143. package/dist/list/index.js +3 -3
  144. package/dist/logviewer/LogViewer.d.ts +1 -1
  145. package/dist/logviewer/index.d.ts +1 -0
  146. package/dist/logviewer/index.js +2 -742
  147. package/dist/logviewer/segments.d.ts +9 -0
  148. package/dist/styles/Geist-Variable.woff2 +0 -0
  149. package/dist/styles/GeistMono-Variable.woff2 +0 -0
  150. package/dist/styles/base.css +57 -0
  151. package/dist/styles/fonts.css +15 -0
  152. package/dist/styles/theme.css +9 -41
  153. package/dist/styles.css +1 -1
  154. package/dist/theme/index.js +2 -2
  155. package/package.json +45 -20
  156. package/LICENSE +0 -21
  157. package/dist/chunks/Monaco-DVyIpyv4.js +0 -1046
  158. package/dist/editor/usesGitlab.d.ts +0 -97
  159. package/dist/form/Fields/BucketReadOnlyField.d.ts +0 -7
  160. package/dist/form/types/workflow-schema.d.ts +0 -1145
  161. package/dist/form/utils/pwResolver.d.ts +0 -18
  162. package/dist/chunks/{BareModal-BqroLbZ5.js → BareModal-BtRiQezg.js} +1 -1
  163. package/dist/chunks/{MarkdownImpl-Bq4QhrtA.js → MarkdownImpl-CyeTVvSt.js} +1 -1
  164. /package/dist/{workflow → graph}/AnnotationBanner.d.ts +0 -0
  165. /package/dist/{workflow → graph}/Collapse.d.ts +0 -0
  166. /package/dist/{workflow → graph}/DependencyGraph.d.ts +0 -0
  167. /package/dist/{workflow → graph}/JobSummary.d.ts +0 -0
  168. /package/dist/{workflow → graph}/Reveal.d.ts +0 -0
  169. /package/dist/{workflow → graph}/TreeView.d.ts +0 -0
@@ -1,13 +1,24 @@
1
+ import { i as useNotify, l as useSlots, n as useLink, u as useStrings } from "./Provider-CDYurraE.js";
1
2
  import { AddIcon, CheckIcon, ChevronRightIcon, ClipboardIcon, CopyIcon, EditIcon, IdCardIcon, KeyIcon, LinkIcon, MailIcon, MoreIcon, UserIcon } from "../icons.js";
2
- import { i as useNotify, l as useSlots, n as useLink, u as useStrings } from "./Provider-DHmZ3v9i.js";
3
- import { n as TOOLTIP_ID } from "./Tooltip-n9w7Tkt1.js";
3
+ import { n as TOOLTIP_ID, o as keyedByContent } from "./Tooltip-K5HJr4_p.js";
4
+ import { Menu, MenuButton, MenuItem, MenuItems } from "@headlessui/react";
4
5
  import cx from "classnames";
5
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
- import React, { Fragment as Fragment$1, createContext, useCallback, useContext, useEffect, useLayoutEffect, useRef, useState } from "react";
6
+ import React, { Fragment, createContext, useCallback, useContext, useEffect, useLayoutEffect, useRef, useState } from "react";
7
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
7
8
  import { createPortal } from "react-dom";
8
- import { Menu, MenuButton, MenuItem, MenuItems } from "@headlessui/react";
9
9
  //#region src/components/AddMenu.tsx
10
10
  var addMenuItemClasses = "flex w-full items-center gap-2 px-3 py-1.5 text-[13px] text-(--theme-app) data-[focus]:bg-(--theme-muted-panel-bg) cursor-pointer";
11
+ function itemButtonProps(item) {
12
+ if (!item.disabled) return { onClick: item.onSelect };
13
+ return {
14
+ "aria-disabled": true,
15
+ ...item.hint ? {
16
+ "aria-label": `${item.label}. ${item.hint}`,
17
+ "data-tooltip-id": TOOLTIP_ID,
18
+ "data-tooltip-content": item.hint
19
+ } : {}
20
+ };
21
+ }
11
22
  function AddMenu({ items, label, buttonClassName, zClassName = "z-50", children }) {
12
23
  const Link = useLink();
13
24
  return /* @__PURE__ */ jsxs(Menu, { children: [/* @__PURE__ */ jsx(MenuButton, {
@@ -18,20 +29,63 @@ function AddMenu({ items, label, buttonClassName, zClassName = "z-50", children
18
29
  }), /* @__PURE__ */ jsx(MenuItems, {
19
30
  anchor: "bottom start",
20
31
  className: cx("mt-1 min-w-52 rounded-lg border border-(--theme-border) bg-(--theme-app-bg) py-1 shadow-lg focus:outline-none", zClassName),
21
- children: items.map((item) => /* @__PURE__ */ jsxs(Fragment$1, { children: [item.separatorAbove && /* @__PURE__ */ jsx("div", { className: "my-1 border-t border-(--theme-border)" }), /* @__PURE__ */ jsx(MenuItem, { children: item.to && !item.disabled ? /* @__PURE__ */ jsxs(Link, {
22
- to: item.to,
23
- className: addMenuItemClasses,
24
- children: [item.icon, item.label]
25
- }) : /* @__PURE__ */ jsxs("button", {
26
- type: "button",
27
- onClick: item.onSelect,
28
- disabled: item.disabled,
29
- className: cx(addMenuItemClasses, item.disabled && "opacity-50 cursor-not-allowed"),
30
- children: [item.icon, item.label]
31
- }) })] }, item.label))
32
+ children: items.map((item) => /* @__PURE__ */ jsxs(Fragment, { children: [item.separatorAbove && /* @__PURE__ */ jsx("div", { className: "my-1 border-t border-(--theme-border)" }), /* @__PURE__ */ jsx(MenuItem, {
33
+ disabled: item.disabled ?? false,
34
+ children: item.to && !item.disabled ? /* @__PURE__ */ jsxs(Link, {
35
+ to: item.to,
36
+ className: addMenuItemClasses,
37
+ children: [item.icon, item.label]
38
+ }) : /* @__PURE__ */ jsxs("button", {
39
+ type: "button",
40
+ ...itemButtonProps(item),
41
+ className: cx(addMenuItemClasses, item.disabled && "opacity-50 cursor-not-allowed"),
42
+ children: [item.icon, item.label]
43
+ })
44
+ })] }, item.label))
32
45
  })] });
33
46
  }
34
47
  //#endregion
48
+ //#region src/components/Avatar.tsx
49
+ var SIZE_CLASSES = {
50
+ sm: "w-6 h-6 text-xs",
51
+ md: "w-8 h-8 text-sm",
52
+ lg: "w-10 h-10 text-base",
53
+ xl: "w-12 h-12 text-lg",
54
+ "2xl": "w-16 h-16 text-xl"
55
+ };
56
+ var STATUS_CLASSES = {
57
+ online: "bg-green-500",
58
+ offline: "bg-(--theme-muted-text-color)",
59
+ busy: "bg-red-500",
60
+ away: "bg-yellow-500"
61
+ };
62
+ /** Up to two initials: the first and last word of a name split on spaces and dots. */
63
+ function avatarInitials(name) {
64
+ const parts = (name ?? "").split(/[\s.]+/).filter(Boolean);
65
+ if (parts.length >= 2) return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
66
+ return parts[0]?.[0]?.toUpperCase() || "?";
67
+ }
68
+ function Avatar({ src, name, size = "md", status, className }) {
69
+ const strings = useStrings();
70
+ const [erroredUrl, setErroredUrl] = useState(null);
71
+ const showImage = !!src && erroredUrl !== src;
72
+ return /* @__PURE__ */ jsxs("div", {
73
+ className: cx("relative inline-flex", className),
74
+ children: [showImage ? /* @__PURE__ */ jsx("img", {
75
+ src,
76
+ alt: name || strings.common.userAvatar,
77
+ onError: () => setErroredUrl(src),
78
+ className: cx("rounded-full object-cover", SIZE_CLASSES[size])
79
+ }) : /* @__PURE__ */ jsx("div", {
80
+ className: cx("rounded-full flex items-center justify-center font-medium", "bg-gradient-to-br from-[var(--gradient-start,var(--theme-element))] to-[var(--gradient-mid,var(--theme-link))] text-white", SIZE_CLASSES[size]),
81
+ children: avatarInitials(name)
82
+ }), status && /* @__PURE__ */ jsx("span", {
83
+ "data-testid": "online-indicator",
84
+ className: cx("absolute bottom-0 right-0 block rounded-full ring-2 ring-(--theme-app-bg)", STATUS_CLASSES[status], size === "sm" ? "w-1.5 h-1.5" : "w-2.5 h-2.5")
85
+ })]
86
+ });
87
+ }
88
+ //#endregion
35
89
  //#region src/components/Breadcrumbs.tsx
36
90
  var BreadcrumbContext = createContext({
37
91
  breadcrumbs: [],
@@ -170,25 +224,27 @@ function assembleRowMenu({ lead = [], actions, exclude, order, trailing = ["dele
170
224
  function useRowMenu(zClassName = "z-50") {
171
225
  const [menu, setMenu] = useState(null);
172
226
  const onCloseRef = useRef(void 0);
227
+ const openMenu = useCallback((x, y, items, onClose) => {
228
+ if (items.length > 0) {
229
+ onCloseRef.current?.();
230
+ onCloseRef.current = onClose;
231
+ setMenu({
232
+ x,
233
+ y,
234
+ items
235
+ });
236
+ }
237
+ }, []);
238
+ const close = useCallback(() => {
239
+ onCloseRef.current?.();
240
+ onCloseRef.current = void 0;
241
+ setMenu(null);
242
+ }, []);
173
243
  return {
174
- openMenu: useCallback((x, y, items, onClose) => {
175
- if (items.length > 0) {
176
- onCloseRef.current?.();
177
- onCloseRef.current = onClose;
178
- setMenu({
179
- x,
180
- y,
181
- items
182
- });
183
- }
184
- }, []),
244
+ openMenu,
185
245
  contextMenu: /* @__PURE__ */ jsx(RowContextMenu, {
186
246
  state: menu,
187
- onClose: useCallback(() => {
188
- onCloseRef.current?.();
189
- onCloseRef.current = void 0;
190
- setMenu(null);
191
- }, []),
247
+ onClose: close,
192
248
  zClassName
193
249
  })
194
250
  };
@@ -288,14 +344,14 @@ function RowContextMenu({ state, onClose, zClassName }) {
288
344
  }
289
345
  var MENU_ITEM_CLASSES = "flex w-full items-center gap-2.5 px-3 py-1.5 text-left text-[13px] hover:bg-(--theme-muted-panel-bg) transition-colors cursor-pointer [&>svg]:h-4 [&>svg]:w-4 [&>svg]:shrink-0";
290
346
  function MenuItemList({ items, onClose, side }) {
291
- return items.map((item, i) => item.kind === "divider" ? /* @__PURE__ */ jsx("div", {
347
+ return keyedByContent(items, (it) => it.kind === "divider" ? "divider" : it.label).map(({ key, item }) => item.kind === "divider" ? /* @__PURE__ */ jsx("div", {
292
348
  "aria-hidden": "true",
293
349
  className: "my-1 h-px bg-(--theme-border)"
294
- }, `divider-${i}`) : /* @__PURE__ */ jsx(MenuRow, {
350
+ }, key) : /* @__PURE__ */ jsx(MenuRow, {
295
351
  item,
296
352
  onClose,
297
353
  side
298
- }, `${item.label}-${i}`));
354
+ }, key));
299
355
  }
300
356
  function MenuRow({ item, onClose, side }) {
301
357
  const Link = useLink();
@@ -338,12 +394,21 @@ function MenuRow({ item, onClose, side }) {
338
394
  })]
339
395
  });
340
396
  }
341
- if (item.kind === "link") return /* @__PURE__ */ jsxs(Link, {
342
- to: item.to,
343
- onClick: onClose,
344
- className: cx(MENU_ITEM_CLASSES, item.destructive ? "text-red-500" : "text-(--theme-app)"),
345
- children: [item.icon, item.label]
346
- });
397
+ if (item.kind === "link") {
398
+ const className = cx(MENU_ITEM_CLASSES, item.destructive ? "text-red-500" : "text-(--theme-app)");
399
+ if (item.reloadDocument) return /* @__PURE__ */ jsxs("a", {
400
+ href: item.to,
401
+ onClick: onClose,
402
+ className,
403
+ children: [item.icon, item.label]
404
+ });
405
+ return /* @__PURE__ */ jsxs(Link, {
406
+ to: item.to,
407
+ onClick: onClose,
408
+ className,
409
+ children: [item.icon, item.label]
410
+ });
411
+ }
347
412
  return /* @__PURE__ */ jsxs("button", {
348
413
  type: "button",
349
414
  disabled: item.disabled && !item.tooltip,
@@ -369,62 +434,62 @@ function MenuRow({ item, onClose, side }) {
369
434
  ]
370
435
  });
371
436
  }
372
- /** Builds the Copy submenu entries for whichever fields a row has, in stable
373
- * order. The menu itself performs the copy and notifies; `t` is an optional
374
- * host translator for the field labels (falls back to the provider defaults'
375
- * English). */
376
- function copySubmenu({ name, nameLabel, email, username, uid, id, url, extra, t }) {
377
- const items = [
378
- {
379
- label: nameLabel ?? (t ? t("rowContextMenu.labelName") : "name"),
380
- value: name,
381
- icon: /* @__PURE__ */ jsx(CopyIcon, {})
382
- },
383
- {
384
- label: t ? t("rowContextMenu.labelEmail") : "email",
385
- value: email,
386
- icon: /* @__PURE__ */ jsx(MailIcon, {})
387
- },
388
- {
389
- label: t ? t("rowContextMenu.labelUsername") : "username",
390
- value: username,
391
- icon: /* @__PURE__ */ jsx(UserIcon, {})
392
- },
393
- {
394
- label: t ? t("rowContextMenu.labelUid") : "UID",
395
- value: uid === null || uid === void 0 ? null : String(uid),
396
- icon: /* @__PURE__ */ jsx(KeyIcon, {})
397
- },
398
- {
399
- label: t ? t("rowContextMenu.labelId") : "ID",
400
- value: id,
401
- icon: /* @__PURE__ */ jsx(IdCardIcon, {})
402
- },
403
- {
404
- label: t ? t("rowContextMenu.labelUrl") : "URL",
405
- value: url,
406
- icon: /* @__PURE__ */ jsx(LinkIcon, {})
407
- },
408
- ...(extra ?? []).map((e) => ({
409
- label: e.label,
410
- value: e.value,
411
- icon: e.icon ?? /* @__PURE__ */ jsx(CopyIcon, {})
412
- }))
413
- ].filter((f) => f.value).map((f) => ({
414
- kind: "action",
415
- label: t ? t("rowContextMenu.copy", { label: f.label }) : `Copy ${f.label}`,
416
- icon: f.icon,
417
- copy: {
418
- text: f.value,
419
- label: f.label
420
- }
421
- }));
422
- return {
423
- kind: "submenu",
424
- label: t ? t("common.copy") : "Copy",
425
- icon: /* @__PURE__ */ jsx(ClipboardIcon, {}),
426
- items
427
- };
437
+ /** Returns a builder for the Copy submenu, labeled from the provider's strings. */
438
+ function useCopySubmenu() {
439
+ const { list: t } = useStrings();
440
+ return useCallback(({ name, nameLabel, email, username, uid, id, url, extra }) => {
441
+ const items = [
442
+ {
443
+ label: nameLabel ?? t.labelName,
444
+ value: name,
445
+ icon: /* @__PURE__ */ jsx(CopyIcon, {})
446
+ },
447
+ {
448
+ label: t.labelEmail,
449
+ value: email,
450
+ icon: /* @__PURE__ */ jsx(MailIcon, {})
451
+ },
452
+ {
453
+ label: t.labelUsername,
454
+ value: username,
455
+ icon: /* @__PURE__ */ jsx(UserIcon, {})
456
+ },
457
+ {
458
+ label: t.labelUid,
459
+ value: uid === null || uid === void 0 ? null : String(uid),
460
+ icon: /* @__PURE__ */ jsx(KeyIcon, {})
461
+ },
462
+ {
463
+ label: t.labelId,
464
+ value: id,
465
+ icon: /* @__PURE__ */ jsx(IdCardIcon, {})
466
+ },
467
+ {
468
+ label: t.labelUrl,
469
+ value: url,
470
+ icon: /* @__PURE__ */ jsx(LinkIcon, {})
471
+ },
472
+ ...(extra ?? []).map((e) => ({
473
+ label: e.label,
474
+ value: e.value,
475
+ icon: e.icon ?? /* @__PURE__ */ jsx(CopyIcon, {})
476
+ }))
477
+ ].filter((f) => f.value).map((f) => ({
478
+ kind: "action",
479
+ label: t.copy(f.label),
480
+ icon: f.icon,
481
+ copy: {
482
+ text: f.value,
483
+ label: f.label
484
+ }
485
+ }));
486
+ return {
487
+ kind: "submenu",
488
+ label: t.copyMenu,
489
+ icon: /* @__PURE__ */ jsx(ClipboardIcon, {}),
490
+ items
491
+ };
492
+ }, [t]);
428
493
  }
429
494
  /** Stays visible while active (menu open) so it doesn't vanish behind the overlay. */
430
495
  function MoreButton({ onOpen, active, className }) {
@@ -451,7 +516,7 @@ var headerAddButtonClasses = "inline-flex h-[26px] shrink-0 items-center gap-1.5
451
516
  function HeaderAddButton({ to, onClick, label, word = "add", menu, disabled = false, disabledHint }) {
452
517
  const { common } = useStrings();
453
518
  const Link = useLink();
454
- const content = /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(AddIcon, { className: "w-3 h-3" }), /* @__PURE__ */ jsx("span", { children: word === "create" ? common.create : common.add })] });
519
+ const content = /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(AddIcon, { className: "w-3 h-3" }), /* @__PURE__ */ jsx("span", { children: word === "create" ? common.create : common.add })] });
455
520
  if (menu) return /* @__PURE__ */ jsx(AddMenu, {
456
521
  items: menu,
457
522
  label,
@@ -493,7 +558,7 @@ function HeaderActionMenu({ items, label = "Actions" }) {
493
558
  function HeaderRowMenu({ items, label = "Actions" }) {
494
559
  const { openMenu, contextMenu } = useRowMenu();
495
560
  if (items.length === 0) return null;
496
- return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("button", {
561
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("button", {
497
562
  type: "button",
498
563
  "aria-label": label,
499
564
  title: label,
@@ -548,7 +613,7 @@ function BreadcrumbsActionButton({ icon: Icon, label, ariaLabel, to, onClick, di
548
613
  "data-tooltip-id": TOOLTIP_ID,
549
614
  "data-tooltip-content": tooltip
550
615
  } : {};
551
- const content = /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Icon, { className: "w-3 h-3" }), label] });
616
+ const content = /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Icon, { className: "w-3 h-3" }), label] });
552
617
  if (to && !disabled) return /* @__PURE__ */ jsx(Link, {
553
618
  to,
554
619
  className: breadcrumbsActionClasses,
@@ -583,19 +648,19 @@ function PageHeader({ breadcrumbs, title, titleAction, actions, toolbar, classNa
583
648
  /* @__PURE__ */ jsx("nav", {
584
649
  "aria-label": "Breadcrumb",
585
650
  className: "flex items-center gap-2 min-w-0 text-[13px]",
586
- children: crumbs.map((crumb, idx) => {
651
+ children: keyedByContent(crumbs, (c) => c.href ?? (typeof c.label === "string" ? c.label : "crumb")).map(({ key, item: crumb }, idx) => {
587
652
  if (idx === crumbs.length - 1) return /* @__PURE__ */ jsx("h1", {
588
653
  className: "m-0 text-[13px] font-medium leading-none text-(--theme-app) truncate",
589
654
  children: crumb.label
590
- }, `${crumb.label}-${idx}`);
591
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [crumb.href ? /* @__PURE__ */ jsx(Link, {
655
+ }, key);
656
+ return /* @__PURE__ */ jsxs(Fragment, { children: [crumb.href ? /* @__PURE__ */ jsx(Link, {
592
657
  to: crumb.href,
593
658
  className: "text-(--theme-muted-text-color) hover:text-(--theme-app) transition-colors cursor-pointer whitespace-nowrap",
594
659
  children: crumb.label
595
660
  }) : /* @__PURE__ */ jsx("span", {
596
661
  className: "text-(--theme-muted-text-color) whitespace-nowrap",
597
662
  children: crumb.label
598
- }), /* @__PURE__ */ jsx(ChevronRightIcon, { className: "w-3 h-3 opacity-60 shrink-0 text-(--theme-muted-text-color)" })] }, `${crumb.label}-${idx}`);
663
+ }), /* @__PURE__ */ jsx(ChevronRightIcon, { className: "w-3 h-3 opacity-60 shrink-0 text-(--theme-muted-text-color)" })] }, key);
599
664
  })
600
665
  }),
601
666
  titleAction,
@@ -624,4 +689,4 @@ function PageHeader({ breadcrumbs, title, titleAction, actions, toolbar, classNa
624
689
  });
625
690
  }
626
691
  //#endregion
627
- export { useSetDefaultBreadcrumbs as C, useSetBreadcrumbs as S, useRowMenuActive as _, HeaderAddButton as a, useClearBreadcrumbs as b, PageHeader as c, assembleRowMenu as d, copySubmenu as f, useRowMenu as g, toolbarActionToRowAction as h, HeaderActionMenu as i, headerActionButtonClasses as l, toRowMenuItem as m, BreadcrumbsRightAction as n, HeaderEditButton as o, rowContextMenuProps as p, BreadcrumbsTitleAction as r, HeaderRowMenu as s, BreadcrumbsActionButton as t, MoreButton as u, BreadcrumbProvider as v, AddMenu as w, useHideBreadcrumbs as x, useBreadcrumb as y };
692
+ export { useSetDefaultBreadcrumbs as C, AddMenu as E, useSetBreadcrumbs as S, avatarInitials as T, useRowMenuActive as _, HeaderAddButton as a, useClearBreadcrumbs as b, PageHeader as c, assembleRowMenu as d, rowContextMenuProps as f, useRowMenu as g, useCopySubmenu as h, HeaderActionMenu as i, headerActionButtonClasses as l, toolbarActionToRowAction as m, BreadcrumbsRightAction as n, HeaderEditButton as o, toRowMenuItem as p, BreadcrumbsTitleAction as r, HeaderRowMenu as s, BreadcrumbsActionButton as t, MoreButton as u, BreadcrumbProvider as v, Avatar as w, useHideBreadcrumbs as x, useBreadcrumb as y };
@@ -1,6 +1,6 @@
1
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
- import { createContext, useContext, useMemo } from "react";
1
+ import { createContext, use, useCallback, useContext, useEffect, useMemo } from "react";
3
2
  import { useLocalStorage } from "usehooks-ts";
3
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
4
4
  //#region src/components/Provider.tsx
5
5
  var DefaultLink = ({ to, onClick, className, children, ...rest }) => /* @__PURE__ */ jsx("a", {
6
6
  href: to,
@@ -58,7 +58,8 @@ var DEFAULTS = {
58
58
  showHiddenFieldsHint: "Includes fields hidden by default because they're specific to each resource, such as name and group.",
59
59
  jsonHasErrors: "JSON has errors, please fix before saving",
60
60
  remove: "Remove",
61
- sort: "Sort"
61
+ sort: "Sort",
62
+ userAvatar: "User avatar"
62
63
  },
63
64
  dropdown: {
64
65
  select: (type) => `Select ${type}`,
@@ -84,7 +85,7 @@ var DEFAULTS = {
84
85
  timeRangeActive: "Time range active",
85
86
  timeRangeOn: "ON",
86
87
  filterByTimeRange: "Filter by time range",
87
- timeRangeHelp: "Times are interpreted in your local timezone. Applying a range re-queries the journal on the cluster and replaces what is loaded. Setting an end time stops live tailing until you clear it.",
88
+ timeRangeHelp: "Times are interpreted in your local timezone. Applying a range re-queries the log source and replaces what is loaded. Setting an end time stops live tailing until you clear it.",
88
89
  timeRangeFrom: "From",
89
90
  timeRangeTo: "To",
90
91
  apply: "Apply",
@@ -187,7 +188,7 @@ var DEFAULTS = {
187
188
  },
188
189
  propagating: {
189
190
  title: "Propagating CORS rules",
190
- description: "Azure is rolling out the new rules to its storage endpoints. This usually completes within a minute.",
191
+ description: "The storage provider is rolling out the new rules to its endpoints. This usually completes within a minute.",
191
192
  stages: {
192
193
  submitted: "Submitted",
193
194
  propagating: "Propagating",
@@ -245,6 +246,7 @@ var DEFAULTS = {
245
246
  collapse: "Collapse",
246
247
  upload: "Upload",
247
248
  download: "Download",
249
+ downloadFromBrowser: "From browser",
248
250
  access: "Access",
249
251
  manageAccess: "Manage Access",
250
252
  delete: "Delete",
@@ -318,11 +320,7 @@ var DEFAULTS = {
318
320
  form: {
319
321
  invalidDuration: "Enter a duration as DD-HH:MM:SS or HH:MM:SS.",
320
322
  durationOutOfRange: (min, max) => `Must be between ${min} and ${max}.`,
321
- durationBelowMin: (min) => `Must be at least ${min}.`,
322
- readOnly: "Read-only",
323
- readWrite: "Read-write",
324
- readOnlyDescription: "Read-only mounts can list and download objects, but cannot upload, modify, or delete them.",
325
- readOnlyForced: "Your access to this bucket is read-only, so this mount cannot be writable."
323
+ durationBelowMin: (min) => `Must be at least ${min}.`
326
324
  },
327
325
  time: {
328
326
  now: "now",
@@ -332,6 +330,7 @@ var DEFAULTS = {
332
330
  years: (n) => `${n}y`
333
331
  },
334
332
  list: {
333
+ copyMenu: "Copy",
335
334
  copy: (label) => `Copy ${label}`,
336
335
  copied: (label) => `Copied ${label}`,
337
336
  couldntCopy: (label) => `Couldn't copy ${label}`,
@@ -367,7 +366,7 @@ var DEFAULTS = {
367
366
  perPage: "Per page",
368
367
  paginationPrevious: "Previous",
369
368
  paginationNext: "Next",
370
- paginationShowing: (name, start, end) => /* @__PURE__ */ jsxs(Fragment, { children: [
369
+ paginationShowing: (name, start, end) => /* @__PURE__ */ jsxs(Fragment$1, { children: [
371
370
  "Showing ",
372
371
  name,
373
372
  " ",
@@ -382,7 +381,7 @@ var DEFAULTS = {
382
381
  children: end
383
382
  })
384
383
  ] }),
385
- paginationShowingTimeRange: (name, startTime, endTime) => /* @__PURE__ */ jsxs(Fragment, { children: [
384
+ paginationShowingTimeRange: (name, startTime, endTime) => /* @__PURE__ */ jsxs(Fragment$1, { children: [
386
385
  "Showing ",
387
386
  name,
388
387
  " from ",
@@ -390,8 +389,8 @@ var DEFAULTS = {
390
389
  className: "font-medium",
391
390
  children: startTime
392
391
  }),
392
+ " to",
393
393
  " ",
394
- "to ",
395
394
  /* @__PURE__ */ jsx("span", {
396
395
  className: "font-medium",
397
396
  children: endTime
@@ -401,8 +400,9 @@ var DEFAULTS = {
401
400
  },
402
401
  navigation: {
403
402
  goTo: (to) => window.location.assign(to),
404
- toWorkflow: () => {},
405
- toMarketItem: () => {},
403
+ openStepSource: (_uses, sourceUrl) => {
404
+ if (sourceUrl) window.open(sourceUrl, "_blank");
405
+ },
406
406
  openExternal: (href) => window.open(href, "_blank")
407
407
  },
408
408
  data: {
@@ -424,15 +424,46 @@ function useNavigation() {
424
424
  function useSlots() {
425
425
  return useContext(UIContext).slots;
426
426
  }
427
- function useWorkflowJsonResolver() {
428
- return useContext(UIContext).data.resolveWorkflowJson;
427
+ var loadedEngines = /* @__PURE__ */ new WeakMap();
428
+ function loadEngine(load) {
429
+ let entry = loadedEngines.get(load);
430
+ if (!entry) {
431
+ const created = { promise: load() };
432
+ created.promise.then((engine) => {
433
+ created.engine = engine;
434
+ });
435
+ loadedEngines.set(load, created);
436
+ entry = created;
437
+ }
438
+ return entry;
439
+ }
440
+ function resolveEngine(source) {
441
+ if (typeof source !== "function") return source;
442
+ const entry = loadEngine(source);
443
+ return entry.engine ?? use(entry.promise);
444
+ }
445
+ /** The engine when one is provided and `enabled`; suspends while a loader resolves. */
446
+ function useOptionalWorkflowEngine(enabled = true) {
447
+ const source = useContext(UIContext).engine;
448
+ if (!enabled || !source) return;
449
+ return resolveEngine(source);
450
+ }
451
+ function useWorkflowEngine() {
452
+ const source = useContext(UIContext).engine;
453
+ if (!source) throw new Error("Workflow forms and graphs need a UIProvider with an engine.");
454
+ return resolveEngine(source);
455
+ }
456
+ /** Resolves the engine without suspending, for async callers such as editor completions. */
457
+ function useWorkflowEngineLoader() {
458
+ const source = useContext(UIContext).engine;
459
+ return useCallback(async () => {
460
+ if (!source) return;
461
+ return typeof source === "function" ? loadEngine(source).promise : source;
462
+ }, [source]);
429
463
  }
430
464
  function useProvisionCorsRules() {
431
465
  return useContext(UIContext).data.provisionCorsRules;
432
466
  }
433
- function useRepoSuggestions() {
434
- return useContext(UIContext).data.repoSuggestions;
435
- }
436
467
  function useRunFile(slug, path, options) {
437
468
  const { useRunFile: boundUseRunFile } = useContext(UIContext).data;
438
469
  return boundUseRunFile(slug, path, options);
@@ -441,7 +472,10 @@ function usePersistedState(key, defaultValue) {
441
472
  const { usePersistedState: boundUsePersistedState } = useContext(UIContext).data;
442
473
  return boundUsePersistedState(key, defaultValue);
443
474
  }
444
- function UIProvider({ notify, strings, navigation, data, slots, children }) {
475
+ function UIProvider({ notify, strings, navigation, data, slots, engine, children }) {
476
+ useEffect(() => {
477
+ if (typeof engine === "function") loadEngine(engine);
478
+ }, [engine]);
445
479
  const value = useMemo(() => ({
446
480
  notify: {
447
481
  ...DEFAULTS.notify,
@@ -498,13 +532,15 @@ function UIProvider({ notify, strings, navigation, data, slots, children }) {
498
532
  ...DEFAULTS.data,
499
533
  ...data
500
534
  },
501
- slots: slots ?? DEFAULTS.slots
535
+ slots: slots ?? DEFAULTS.slots,
536
+ engine
502
537
  }), [
503
538
  notify,
504
539
  strings,
505
540
  navigation,
506
541
  data,
507
- slots
542
+ slots,
543
+ engine
508
544
  ]);
509
545
  return /* @__PURE__ */ jsx(UIContext.Provider, {
510
546
  value,
@@ -512,4 +548,4 @@ function UIProvider({ notify, strings, navigation, data, slots, children }) {
512
548
  });
513
549
  }
514
550
  //#endregion
515
- export { usePersistedState as a, useRunFile as c, useWorkflowJsonResolver as d, useNotify as i, useSlots as l, useLink as n, useProvisionCorsRules as o, useNavigation as r, useRepoSuggestions as s, UIProvider as t, useStrings as u };
551
+ export { useOptionalWorkflowEngine as a, useRunFile as c, useWorkflowEngine as d, useWorkflowEngineLoader as f, useNotify as i, useSlots as l, useLink as n, usePersistedState as o, useNavigation as r, useProvisionCorsRules as s, UIProvider as t, useStrings as u };