@parallelworks/ui 0.18.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 (349) hide show
  1. package/README.md +86 -6
  2. package/dist/ai/adapter/memoryStore.d.ts +8 -0
  3. package/dist/ai/adapter/memoryStore.js +152 -0
  4. package/dist/ai/adapter/mock/index.d.ts +2 -0
  5. package/dist/ai/adapter/mock/index.js +3 -0
  6. package/dist/ai/adapter/mock/mockAdapter.d.ts +4 -0
  7. package/dist/ai/adapter/mock/mockAdapter.js +81 -0
  8. package/dist/ai/adapter/openai/createOpenAIStream.d.ts +9 -0
  9. package/dist/ai/adapter/openai/createOpenAIStream.js +33 -0
  10. package/dist/ai/adapter/openai/errors.d.ts +3 -0
  11. package/dist/ai/adapter/openai/errors.js +37 -0
  12. package/dist/ai/adapter/openai/index.d.ts +6 -0
  13. package/dist/ai/adapter/openai/index.js +6 -0
  14. package/dist/ai/adapter/openai/openaiAdapter.d.ts +9 -0
  15. package/dist/ai/adapter/openai/openaiAdapter.js +54 -0
  16. package/dist/ai/adapter/openai/responses.d.ts +4 -0
  17. package/dist/ai/adapter/openai/responses.js +108 -0
  18. package/dist/ai/adapter/openai/sse.d.ts +24 -0
  19. package/dist/ai/adapter/openai/sse.js +112 -0
  20. package/dist/ai/adapter/openai/wire.d.ts +40 -0
  21. package/dist/ai/adapter/types.d.ts +131 -0
  22. package/dist/ai/adapter/types.js +11 -0
  23. package/dist/ai/agent/classifier.d.ts +2 -0
  24. package/dist/ai/agent/classifier.js +12 -0
  25. package/dist/ai/agent/diff.d.ts +35 -0
  26. package/dist/ai/agent/diff.js +223 -0
  27. package/dist/ai/agent/diffHighlight.d.ts +6 -0
  28. package/dist/ai/agent/diffHighlight.js +101 -0
  29. package/dist/ai/agent/index.d.ts +6 -0
  30. package/dist/ai/agent/permissions.d.ts +11 -0
  31. package/dist/ai/agent/permissions.js +29 -0
  32. package/dist/ai/agent/toolfmt.d.ts +18 -0
  33. package/dist/ai/agent/toolfmt.js +383 -0
  34. package/dist/ai/agent/transcript.d.ts +38 -0
  35. package/dist/ai/agent/transcript.js +127 -0
  36. package/dist/ai/ai.css +325 -0
  37. package/dist/ai/components/AllocationSelector.d.ts +4 -0
  38. package/dist/ai/components/AllocationSelector.js +56 -0
  39. package/dist/ai/components/AttachmentManager.d.ts +1 -0
  40. package/dist/ai/components/AttachmentManager.js +144 -0
  41. package/dist/ai/components/AttachmentUpload.d.ts +24 -0
  42. package/dist/ai/components/AttachmentUpload.js +179 -0
  43. package/dist/ai/components/BlockedGroupBanner.d.ts +1 -0
  44. package/dist/ai/components/BlockedGroupBanner.js +29 -0
  45. package/dist/ai/components/BranchNavigator.d.ts +8 -0
  46. package/dist/ai/components/BranchNavigator.js +57 -0
  47. package/dist/ai/components/ChatEmptyState.d.ts +3 -0
  48. package/dist/ai/components/ChatEmptyState.js +171 -0
  49. package/dist/ai/components/ChatInput.d.ts +45 -0
  50. package/dist/ai/components/ChatInput.js +265 -0
  51. package/dist/ai/components/ChatLayout.d.ts +5 -0
  52. package/dist/ai/components/ChatLayout.js +15 -0
  53. package/dist/ai/components/ChatMessage.d.ts +24 -0
  54. package/dist/ai/components/ChatMessage.js +338 -0
  55. package/dist/ai/components/ChatMessageList.d.ts +35 -0
  56. package/dist/ai/components/ChatMessageList.js +301 -0
  57. package/dist/ai/components/ChatSidebar.d.ts +5 -0
  58. package/dist/ai/components/ChatSidebar.js +345 -0
  59. package/dist/ai/components/ChatThread.d.ts +3 -0
  60. package/dist/ai/components/ChatThread.js +198 -0
  61. package/dist/ai/components/ComposerChrome.d.ts +18 -0
  62. package/dist/ai/components/ComposerChrome.js +50 -0
  63. package/dist/ai/components/ComposerFrame.d.ts +16 -0
  64. package/dist/ai/components/ComposerFrame.js +33 -0
  65. package/dist/ai/components/DragOverlay.d.ts +5 -0
  66. package/dist/ai/components/DragOverlay.js +20 -0
  67. package/dist/ai/components/ModelSelector.d.ts +6 -0
  68. package/dist/ai/components/ModelSelector.js +343 -0
  69. package/dist/ai/components/ShareDialog.d.ts +11 -0
  70. package/dist/ai/components/ShareDialog.js +260 -0
  71. package/dist/ai/components/SlashMenu.d.ts +28 -0
  72. package/dist/ai/components/SlashMenu.js +91 -0
  73. package/dist/ai/components/agent/ActivityLine.d.ts +21 -0
  74. package/dist/ai/components/agent/ActivityLine.js +151 -0
  75. package/dist/ai/components/agent/AgentMessageParts.d.ts +54 -0
  76. package/dist/ai/components/agent/AgentMessageParts.js +721 -0
  77. package/dist/ai/components/agent/PermissionPicker.d.ts +11 -0
  78. package/dist/ai/components/agent/PermissionPicker.js +38 -0
  79. package/dist/ai/components/attachmentKeys.d.ts +4 -0
  80. package/dist/ai/components/attachmentKeys.js +10 -0
  81. package/dist/ai/core/ChatProvider.d.ts +66 -0
  82. package/dist/ai/core/ChatProvider.js +848 -0
  83. package/dist/ai/core/KeyboardShortcutsProvider.d.ts +5 -0
  84. package/dist/ai/core/KeyboardShortcutsProvider.js +9 -0
  85. package/dist/ai/core/chatReducer.d.ts +114 -0
  86. package/dist/ai/core/chatReducer.js +223 -0
  87. package/dist/ai/core/config.d.ts +47 -0
  88. package/dist/ai/core/config.js +45 -0
  89. package/dist/ai/core/events.d.ts +1 -0
  90. package/dist/ai/core/events.js +4 -0
  91. package/dist/ai/core/exportConversation.d.ts +4 -0
  92. package/dist/ai/core/exportConversation.js +42 -0
  93. package/dist/ai/core/greeting.d.ts +3 -0
  94. package/dist/ai/core/greeting.js +38 -0
  95. package/dist/ai/core/parts.d.ts +11 -0
  96. package/dist/ai/core/parts.js +84 -0
  97. package/dist/ai/core/useDragDrop.d.ts +14 -0
  98. package/dist/ai/core/useDragDrop.js +36 -0
  99. package/dist/ai/core/useKeyboardShortcuts.d.ts +12 -0
  100. package/dist/ai/core/useKeyboardShortcuts.js +77 -0
  101. package/dist/ai/core/useSSEStream.d.ts +34 -0
  102. package/dist/ai/core/useSSEStream.js +98 -0
  103. package/dist/ai/index.d.ts +40 -0
  104. package/dist/ai/index.js +44 -0
  105. package/dist/ai/strings.d.ts +167 -0
  106. package/dist/ai/strings.js +175 -0
  107. package/dist/ai/types.d.ts +236 -0
  108. package/dist/ai/ui/Avatar.d.ts +8 -0
  109. package/dist/ai/ui/Avatar.js +35 -0
  110. package/dist/ai/ui/Dropdown.d.ts +31 -0
  111. package/dist/ai/ui/Dropdown.js +110 -0
  112. package/dist/ai/ui/Markdown.d.ts +8 -0
  113. package/dist/ai/ui/Markdown.js +79 -0
  114. package/dist/ai/ui/Notice.d.ts +21 -0
  115. package/dist/ai/ui/Notice.js +77 -0
  116. package/dist/ai/ui/buttons.d.ts +1 -0
  117. package/dist/ai/ui/codeBreaks.d.ts +16 -0
  118. package/dist/ai/ui/codeBreaks.js +36 -0
  119. package/dist/ai/ui/prose.d.ts +1 -0
  120. package/dist/ai/ui/prose.js +13 -0
  121. package/dist/ai/ui/sidebar.d.ts +81 -0
  122. package/dist/ai/ui/sidebar.js +148 -0
  123. package/dist/ai/utils.d.ts +4 -0
  124. package/dist/ai/utils.js +23 -0
  125. package/dist/assets/{editor.worker-CuBRIwi-.js → editor.worker-BmHUIVG4.js} +194 -163
  126. package/dist/assets/{json.worker-8ytS02vz.js → json.worker-D8bJ92nw.js} +384 -338
  127. package/dist/assets/{yaml.worker-DJC-VUcv.js → yaml.worker-C4gyGAko.js} +15657 -13823
  128. package/dist/components/AddMenu.js +46 -0
  129. package/dist/components/Avatar.d.ts +1 -1
  130. package/dist/components/Avatar.js +46 -0
  131. package/dist/{chunks/BareModal-BtRiQezg.js → components/BareModal.js} +1 -1
  132. package/dist/components/Breadcrumbs.d.ts +1 -1
  133. package/dist/components/Breadcrumbs.js +83 -0
  134. package/dist/components/Button.js +83 -0
  135. package/dist/components/Callout.js +23 -0
  136. package/dist/components/Card.js +31 -0
  137. package/dist/components/CollapsiblePanel.js +77 -0
  138. package/dist/components/ConfirmModal.js +74 -0
  139. package/dist/components/CopyToClipboard.js +81 -0
  140. package/dist/{chunks/CreateModal-BY6DLmur.js → components/CreateModal.js} +10 -189
  141. package/dist/components/DescriptionList.js +42 -0
  142. package/dist/components/Dropdown.d.ts +1 -1
  143. package/dist/components/Dropdown.js +349 -0
  144. package/dist/components/EmptyState.d.ts +1 -1
  145. package/dist/components/EmptyState.js +27 -0
  146. package/dist/components/Filter.js +32 -0
  147. package/dist/components/FilterPill.js +13 -0
  148. package/dist/components/IconButton.js +34 -0
  149. package/dist/components/Indicator.d.ts +2 -2
  150. package/dist/{chunks/Indicator-hBSIxOPK.js → components/Indicator.js} +1 -1
  151. package/dist/components/Input.d.ts +1 -1
  152. package/dist/components/Input.js +88 -0
  153. package/dist/components/LetterBadge.d.ts +1 -1
  154. package/dist/components/LetterBadge.js +13 -0
  155. package/dist/components/Listbox.js +123 -0
  156. package/dist/{chunks/Loader-BXoXTZGc.js → components/Loader.js} +1 -1
  157. package/dist/components/Markdown.js +15 -0
  158. package/dist/components/MarkdownImpl.d.ts +1 -1
  159. package/dist/components/MultiSelect.js +171 -0
  160. package/dist/components/Overview.js +39 -0
  161. package/dist/components/PageHeader.js +194 -0
  162. package/dist/components/Pagination.js +35 -0
  163. package/dist/components/Provider.d.ts +16 -65
  164. package/dist/{chunks/Provider-Ghua9PkN.js → components/Provider.js} +54 -20
  165. package/dist/{chunks/RequiredMark-DfLdYbYZ.js → components/RequiredMark.js} +1 -1
  166. package/dist/components/SectionHeader.js +11 -0
  167. package/dist/components/SettingModeOption.js +30 -0
  168. package/dist/components/SettingRow.d.ts +1 -1
  169. package/dist/components/SettingRow.js +35 -0
  170. package/dist/components/SettingsCard.js +31 -0
  171. package/dist/components/SettingsGroup.d.ts +1 -1
  172. package/dist/components/SettingsGroup.js +17 -0
  173. package/dist/components/Sort.js +42 -0
  174. package/dist/components/StatusBadge.js +63 -0
  175. package/dist/components/SwitchToggle.js +59 -0
  176. package/dist/{chunks/SwitchToggleSmall-FcsaYSTs.js → components/SwitchToggleSmall.js} +1 -1
  177. package/dist/{chunks/Table-4OHjdKdO.js → components/Table.js} +7 -5
  178. package/dist/components/Toggle.js +20 -0
  179. package/dist/{chunks/Tooltip-Crxo_eU_.js → components/Tooltip.js} +6 -4
  180. package/dist/{chunks/StatusBadge-C1Blx_cW.js → components/dropdownUtils.js} +2 -63
  181. package/dist/components/focus.d.ts +2 -0
  182. package/dist/components/focus.js +7 -0
  183. package/dist/components/ghostButton.js +7 -0
  184. package/dist/components/inputClasses.js +4 -0
  185. package/dist/components/keys.d.ts +12 -0
  186. package/dist/components/keys.js +27 -0
  187. package/dist/components/relativeTime.js +32 -0
  188. package/dist/{chunks/useCssIsDark-DHr05dG2.js → components/useCssIsDark.js} +1 -1
  189. package/dist/duration.d.ts +3 -0
  190. package/dist/duration.js +17 -0
  191. package/dist/editor/Editor.js +13 -0
  192. package/dist/editor/EditorField.js +53 -0
  193. package/dist/editor/FormCodePanel.js +173 -0
  194. package/dist/editor/Monaco.d.ts +1 -20
  195. package/dist/editor/Monaco.js +112 -0
  196. package/dist/editor/index.d.ts +2 -1
  197. package/dist/editor/index.js +7 -2
  198. package/dist/editor/themes.js +91 -0
  199. package/dist/editor/workers.js +29 -0
  200. package/dist/editor/yaml.d.ts +5 -0
  201. package/dist/editor/yaml.js +15 -0
  202. package/dist/engine.d.ts +98 -0
  203. package/dist/file-explorer/FileExplorer.d.ts +11 -2
  204. package/dist/file-explorer/FileExplorer.js +1402 -0
  205. package/dist/file-explorer/FileExplorerContext.d.ts +1 -1
  206. package/dist/file-explorer/FileExplorerContext.js +370 -0
  207. package/dist/file-explorer/FilePreview/CodePreviewEditor.d.ts +1 -1
  208. package/dist/{chunks/CodePreviewEditor-4lx3kE-w.js → file-explorer/FilePreview/CodePreviewEditor.js} +3 -2
  209. package/dist/file-explorer/FilePreview/Inline.js +45 -0
  210. package/dist/file-explorer/FilePreview/StreamedBadge.js +16 -0
  211. package/dist/file-explorer/FilePreview/Viewer.js +526 -0
  212. package/dist/file-explorer/FilePreview/index.js +266 -0
  213. package/dist/file-explorer/FilePreview/parse.js +63 -0
  214. package/dist/file-explorer/FilePreview/previewCache.js +98 -0
  215. package/dist/file-explorer/FilePreview/previewType.d.ts +1 -1
  216. package/dist/file-explorer/FilePreview/previewType.js +151 -0
  217. package/dist/file-explorer/FilePreview/readCappedBytes.js +196 -0
  218. package/dist/file-explorer/FilePreview/useObjectBlobUrl.js +95 -0
  219. package/dist/file-explorer/FilePreview/useObjectText.js +109 -0
  220. package/dist/file-explorer/FilePreview/usePresignedUrl.js +73 -0
  221. package/dist/file-explorer/FileRow.d.ts +1 -1
  222. package/dist/file-explorer/FileRow.js +165 -0
  223. package/dist/file-explorer/FileRowsWindow.js +92 -0
  224. package/dist/file-explorer/FileTable.js +172 -0
  225. package/dist/file-explorer/FileTableHeaders.js +49 -0
  226. package/dist/file-explorer/LoadMoreRow.js +46 -0
  227. package/dist/file-explorer/TreeView.js +376 -0
  228. package/dist/file-explorer/helpers.d.ts +4 -4
  229. package/dist/file-explorer/helpers.js +537 -0
  230. package/dist/file-explorer/index.d.ts +3 -3
  231. package/dist/file-explorer/index.js +7 -5705
  232. package/dist/file-explorer/lib/batch.js +39 -0
  233. package/dist/file-explorer/lib/errors.js +9 -0
  234. package/dist/file-explorer/lib/paging.js +124 -0
  235. package/dist/file-explorer/lib/types.d.ts +6 -1
  236. package/dist/file-explorer/lib/utils.d.ts +1 -3
  237. package/dist/file-explorer/lib/utils.js +322 -0
  238. package/dist/file-explorer/toasts.js +400 -0
  239. package/dist/file-explorer/treeRows.js +73 -0
  240. package/dist/file-explorer/useNearEnd.d.ts +1 -1
  241. package/dist/file-explorer/useNearEnd.js +27 -0
  242. package/dist/form/FieldWrapper.d.ts +2 -2
  243. package/dist/form/FieldWrapper.js +54 -0
  244. package/dist/form/Fields/BooleanField.js +51 -0
  245. package/dist/form/Fields/CheckboxGroupField.js +72 -0
  246. package/dist/form/Fields/ColorField.js +33 -0
  247. package/dist/form/Fields/DropdownField.js +49 -0
  248. package/dist/form/Fields/DurationField.js +130 -0
  249. package/dist/form/Fields/LabelField.js +19 -0
  250. package/dist/form/Fields/MultiDropdownField.js +40 -0
  251. package/dist/form/Fields/NumberField.js +51 -0
  252. package/dist/form/Fields/ObjectField.js +54 -0
  253. package/dist/form/Fields/RadioField.js +49 -0
  254. package/dist/form/Fields/RangeField.js +58 -0
  255. package/dist/form/Fields/ResourceOptionIcon.d.ts +1 -1
  256. package/dist/form/Fields/ResourceOptionIcon.js +21 -0
  257. package/dist/form/Fields/StepField.js +6 -0
  258. package/dist/form/Fields/StringField.js +37 -0
  259. package/dist/form/Fields/TextAreaField.js +31 -0
  260. package/dist/form/Fields/durationValidity.js +11 -0
  261. package/dist/form/Form.d.ts +4 -21
  262. package/dist/form/Form.js +643 -0
  263. package/dist/form/SpecialTypes/DropdownWrapper.js +30 -0
  264. package/dist/form/SpecialTypes/FormikCustomDropdown.js +122 -0
  265. package/dist/form/SpecialTypes/FormikCustomInput.js +111 -0
  266. package/dist/form/SpecialTypes/FormikMultiSelectDropdown.js +31 -0
  267. package/dist/form/SpecialTypes/FormikNumericInput.js +60 -0
  268. package/dist/form/Wizard/WizardContainer.js +138 -0
  269. package/dist/form/Wizard/WizardNavigation.js +92 -0
  270. package/dist/form/Wizard/WizardStepContent.js +35 -0
  271. package/dist/form/Wizard/WizardStepIndicator.js +108 -0
  272. package/dist/form/Wizard/useWizardState.js +118 -0
  273. package/dist/form/Wizard/utils.js +34 -0
  274. package/dist/form/fieldContext.js +26 -0
  275. package/dist/form/fieldRegistry.js +50 -0
  276. package/dist/form/index.d.ts +11 -12
  277. package/dist/form/index.js +18 -2445
  278. package/dist/form/lib.d.ts +6 -1
  279. package/dist/{chunks/FieldWrapper-Bef01EWO.js → form/lib.js} +5 -104
  280. package/dist/form/types/fieldComponentTypes.d.ts +3 -2
  281. package/dist/form/types/fieldTypes.d.ts +6 -20
  282. package/dist/form/useParsedOpts.d.ts +1 -1
  283. package/dist/form/useParsedOpts.js +62 -0
  284. package/dist/form/usePrevious.js +11 -0
  285. package/dist/form/utils/checkShowIfObject.js +14 -0
  286. package/dist/form/utils/{slurmDuration.d.ts → duration.d.ts} +2 -2
  287. package/dist/form/utils/duration.js +69 -0
  288. package/dist/form/utils/getParentValue.js +23 -0
  289. package/dist/form/utils/getPlaceholder.js +9 -0
  290. package/dist/form/utils/getValueUsingPath.js +23 -0
  291. package/dist/form/utils/secondaryField.js +22 -0
  292. package/dist/graph/AnnotationBanner.js +141 -0
  293. package/dist/graph/Collapse.js +41 -0
  294. package/dist/{workflow/index.js → graph/DependencyGraph.js} +76 -1163
  295. package/dist/graph/JobSummary.js +104 -0
  296. package/dist/{workflow → graph}/MatrixGroup.d.ts +2 -2
  297. package/dist/graph/MatrixGroup.js +107 -0
  298. package/dist/graph/Reveal.js +57 -0
  299. package/dist/graph/TreeView.js +711 -0
  300. package/dist/{workflow → graph}/index.d.ts +1 -1
  301. package/dist/graph/index.js +2 -0
  302. package/dist/{workflow → graph}/types.d.ts +3 -3
  303. package/dist/graph/types.js +6 -0
  304. package/dist/icons.d.ts +20 -21
  305. package/dist/index.d.ts +38 -40
  306. package/dist/index.js +47 -599
  307. package/dist/list/ActionToolbar.js +184 -0
  308. package/dist/list/HoverCard.js +73 -0
  309. package/dist/list/ListPage.js +145 -0
  310. package/dist/list/ListPager.js +59 -0
  311. package/dist/list/ListTable.d.ts +1 -1
  312. package/dist/list/ListTable.js +163 -0
  313. package/dist/list/ListViewControls.d.ts +2 -2
  314. package/dist/list/ListViewControls.js +372 -0
  315. package/dist/list/RowContextMenu.js +350 -0
  316. package/dist/list/UserHoverCard.js +117 -0
  317. package/dist/list/index.d.ts +9 -9
  318. package/dist/list/index.js +11 -2
  319. package/dist/list/listSearch.js +137 -0
  320. package/dist/list/listView.js +210 -0
  321. package/dist/list/textEntry.js +10 -0
  322. package/dist/logviewer/LogViewer.d.ts +1 -1
  323. package/dist/logviewer/LogViewer.js +750 -0
  324. package/dist/logviewer/index.d.ts +1 -0
  325. package/dist/logviewer/index.js +3 -742
  326. package/dist/logviewer/segments.d.ts +9 -0
  327. package/dist/logviewer/segments.js +80 -0
  328. package/dist/styles/fonts.css +4 -4
  329. package/dist/styles/theme.css +6 -4
  330. package/dist/styles.css +1 -1
  331. package/dist/theme/index.js +2 -2
  332. package/package.json +38 -14
  333. package/LICENSE +0 -202
  334. package/dist/chunks/Monaco-C1POOdVv.js +0 -1046
  335. package/dist/chunks/PageHeader-l49p1nM9.js +0 -690
  336. package/dist/chunks/SwitchToggle-CHPP8uZQ.js +0 -755
  337. package/dist/chunks/editor-9_uVtUyy.js +0 -347
  338. package/dist/chunks/list-qrojZZNv.js +0 -1411
  339. package/dist/editor/usesGitlab.d.ts +0 -97
  340. package/dist/form/Fields/BucketReadOnlyField.d.ts +0 -7
  341. package/dist/form/types/workflow-schema.d.ts +0 -1145
  342. package/dist/form/utils/pwResolver.d.ts +0 -18
  343. package/dist/{chunks/MarkdownImpl-Bq4QhrtA.js → components/MarkdownImpl.js} +1 -1
  344. /package/dist/{workflow → graph}/AnnotationBanner.d.ts +0 -0
  345. /package/dist/{workflow → graph}/Collapse.d.ts +0 -0
  346. /package/dist/{workflow → graph}/DependencyGraph.d.ts +0 -0
  347. /package/dist/{workflow → graph}/JobSummary.d.ts +0 -0
  348. /package/dist/{workflow → graph}/Reveal.d.ts +0 -0
  349. /package/dist/{workflow → graph}/TreeView.d.ts +0 -0
@@ -12,4 +12,9 @@ export declare function enforceOneMustBeTrue(items: Array<Record<string, unknown
12
12
  export declare function flattenGroups(schema: unknown): Record<string, unknown>;
13
13
  /**Not a pure function. Edits 'obj' passed into function */
14
14
  export declare function impureSetValueFromPath(obj: Record<string, unknown>, path: string, value: unknown): void;
15
- export declare function initializeValues(options: unknown, srcData?: object, ignoreDefaultStrings?: boolean): Record<string, unknown> | undefined;
15
+ export declare function initializeValues(options: unknown, srcData?: object,
16
+ /** Fields whose schema default the host wants left blank. */
17
+ blankDefault?: (field: {
18
+ type?: string;
19
+ default?: unknown;
20
+ }) => boolean): Record<string, unknown> | undefined;
@@ -1,52 +1,4 @@
1
- import { t as RequiredMark } from "./RequiredMark-DfLdYbYZ.js";
2
- import cx from "classnames";
3
- import { createContext, useContext, useId, useMemo } from "react";
4
- import { jsx, jsxs } from "react/jsx-runtime";
5
- //#region src/form/fieldContext.tsx
6
- var FieldContext = createContext({ required: false });
7
- var FieldProvider = FieldContext.Provider;
8
- /** True when the surrounding FieldWrapper is showing the required asterisk. */
9
- function useFieldRequired() {
10
- return useContext(FieldContext).required;
11
- }
12
- /** Ties the single focusable control of a field to its FieldWrapper label. */
13
- function useFieldControlProps() {
14
- const { id, descriptionId } = useContext(FieldContext);
15
- return {
16
- id,
17
- "aria-describedby": descriptionId
18
- };
19
- }
20
- /** For controls and groups that can only be named through aria-labelledby. */
21
- function useFieldLabelledByProps() {
22
- const { labelId, descriptionId } = useContext(FieldContext);
23
- return {
24
- "aria-labelledby": labelId,
25
- "aria-describedby": descriptionId
26
- };
27
- }
28
- //#endregion
29
- //#region src/form/utils/secondaryField.ts
30
- function findSecondaryOption(options, value) {
31
- for (const candidate of options) {
32
- if (!candidate || typeof candidate !== "object") continue;
33
- const option = candidate;
34
- if (option.value === value) return option;
35
- if (Array.isArray(option.options)) {
36
- const nestedOption = findSecondaryOption(option.options, value);
37
- if (nestedOption) return nestedOption;
38
- }
39
- }
40
- }
41
- function applySecondaryField(secondaryField, secondaryValue, setFieldValue) {
42
- if (secondaryField === void 0 || secondaryValue === void 0) return;
43
- const fields = Array.isArray(secondaryField) ? secondaryField : [secondaryField];
44
- const values = Array.isArray(secondaryValue) ? secondaryValue : [secondaryValue];
45
- fields.forEach((field, index) => {
46
- setFieldValue(field, values[index]);
47
- });
48
- }
49
- //#endregion
1
+ import { applySecondaryField, findSecondaryOption } from "./utils/secondaryField.js";
50
2
  //#region src/form/lib.ts
51
3
  var EMPTY_ENTRY = {};
52
4
  function asRecord(value) {
@@ -122,7 +74,7 @@ function impureSetValueFromPath(obj, path, value) {
122
74
  }
123
75
  current[pathArray[pathArray.length - 1]] = value;
124
76
  }
125
- function initializeValues(options, srcData = {}, ignoreDefaultStrings = false) {
77
+ function initializeValues(options, srcData = {}, blankDefault) {
126
78
  if (!options || typeof options !== "object") return;
127
79
  const schema = options;
128
80
  const source = srcData;
@@ -168,7 +120,7 @@ function initializeValues(options, srcData = {}, ignoreDefaultStrings = false) {
168
120
  if ((fieldSchema.type === "dropdown" || fieldSchema.type === "storage") && fieldSchema.secondaryField && fieldSchema.options && Array.isArray(fieldSchema.options)) {
169
121
  const option = findSecondaryOption(fieldSchema.options, data[field]);
170
122
  applySecondaryField(fieldSchema.secondaryField, option?.secondaryValue, (secondaryField, secondaryValue) => {
171
- if (!(fieldSchema.type === "storage" && Object.prototype.hasOwnProperty.call(options, secondaryField) && source[secondaryField] !== void 0)) impureSetValueFromPath(acc, secondaryField, secondaryValue);
123
+ if (!(fieldSchema.type === "storage" && Object.hasOwn(options, secondaryField) && source[secondaryField] !== void 0)) impureSetValueFromPath(acc, secondaryField, secondaryValue);
172
124
  });
173
125
  }
174
126
  return acc;
@@ -195,61 +147,10 @@ function initializeValues(options, srcData = {}, ignoreDefaultStrings = false) {
195
147
  }
196
148
  }
197
149
  if (fieldSchema.type === "multi-dropdown" || fieldSchema.type === "checkbox-group") acc[field] = [];
198
- if (fieldSchema.default !== void 0) {
199
- const dflt = fieldSchema.default;
200
- const isPwResource = typeof dflt === "string" && dflt.startsWith("pw://");
201
- acc[field] = fieldSchema.type === "string" || ignoreDefaultStrings && !isPwResource && (fieldSchema.type === "textarea" || fieldSchema.type === "compute-clusters" || fieldSchema.type === "compute-resources") ? "" : dflt;
202
- }
150
+ if (fieldSchema.default !== void 0) acc[field] = fieldSchema.type === "string" || blankDefault?.(fieldSchema) ? "" : fieldSchema.default;
203
151
  if (fieldSchema.prefillDefault && fieldSchema.default !== void 0) acc[field] = fieldSchema.default;
204
152
  return acc;
205
153
  }, data);
206
154
  }
207
155
  //#endregion
208
- //#region src/form/FieldWrapper.tsx
209
- function FieldWrapper({ label, tooltipComponent, description, labelPosition = "left", spaceCompact = false, optional = false, children }) {
210
- const isOptional = Boolean(resolvedFlag(optional));
211
- const uid = useId();
212
- const id = `${uid}control`;
213
- const labelId = `${uid}label`;
214
- const descriptionId = description ? `${uid}description` : void 0;
215
- const field = useMemo(() => ({
216
- required: !isOptional,
217
- id,
218
- labelId,
219
- descriptionId
220
- }), [
221
- isOptional,
222
- id,
223
- labelId,
224
- descriptionId
225
- ]);
226
- return /* @__PURE__ */ jsxs("div", {
227
- className: cx("flex w-full", labelPosition === "left" ? "items-start" : "items-left flex-col"),
228
- children: [/* @__PURE__ */ jsxs("label", {
229
- htmlFor: id,
230
- id: labelId,
231
- className: cx("relative", labelPosition === "left" ? "form-label" : "form-label-top", spaceCompact && "form-label-compact"),
232
- children: [
233
- label,
234
- !isOptional && /* @__PURE__ */ jsx(RequiredMark, {}),
235
- tooltipComponent
236
- ]
237
- }), /* @__PURE__ */ jsxs("div", {
238
- className: "w-full",
239
- children: [/* @__PURE__ */ jsx(FieldProvider, {
240
- value: field,
241
- children: typeof children === "function" ? children({
242
- id,
243
- labelId,
244
- describedBy: descriptionId
245
- }) : children
246
- }), description && /* @__PURE__ */ jsx("div", {
247
- id: descriptionId,
248
- className: "text-xs theme-muted-text mt-1 leading-relaxed",
249
- children: description
250
- })]
251
- })]
252
- });
253
- }
254
- //#endregion
255
- export { initializeValues as a, findSecondaryOption as c, useFieldLabelledByProps as d, useFieldRequired as f, impureSetValueFromPath as i, FieldProvider as l, enforceOneMustBeTrue as n, resolvedFlag as o, flattenGroups as r, applySecondaryField as s, FieldWrapper as t, useFieldControlProps as u };
156
+ export { enforceOneMustBeTrue, flattenGroups, impureSetValueFromPath, initializeValues, resolvedFlag };
@@ -1,5 +1,5 @@
1
1
  import type { TSetFormDirty } from '../Form.js';
2
- import type { FieldType, LabelPosition, SchemaField } from './fieldTypes.js';
2
+ import type { BaseField, LabelPosition, RuntimeFieldExtensions } from './fieldTypes.js';
3
3
  /** Intentionally loose to allow both manual types and schema-generated types. */
4
4
  interface FieldBase {
5
5
  type?: string;
@@ -29,5 +29,6 @@ export interface FieldComponentProps<TField extends FieldBase = FieldBase, TValu
29
29
  setFieldValue?: (field: string, value: unknown, shouldValidate?: boolean) => void;
30
30
  setFieldTouched?: (field: string, isTouched?: boolean, shouldValidate?: boolean) => void;
31
31
  }
32
- export type FieldProps<T extends SchemaField['type'], TValue = unknown> = FieldComponentProps<FieldType<T>, TValue>;
32
+ /** Props for a field component, given the field definition it renders. */
33
+ export type FieldProps<TField extends FieldBase = BaseField, TValue = unknown> = FieldComponentProps<TField & RuntimeFieldExtensions, TValue>;
33
34
  export {};
@@ -1,20 +1,8 @@
1
- import type { Hidden, Ignore, Inputs, Optional } from './workflow-schema.js';
2
1
  export type LabelPosition = 'left' | 'top';
3
- export type FieldResource = string | {
4
- type: string;
5
- id: string;
6
- name?: string;
7
- user?: string;
8
- };
9
- type InputFieldValue = Inputs[string];
10
- export type SchemaField = Exclude<InputFieldValue, {
11
- labelPosition?: LabelPosition;
12
- }>;
13
- export type FieldType<T extends SchemaField['type']> = Extract<SchemaField, {
14
- type: T;
15
- }> & RuntimeFieldExtensions;
2
+ /** A flag a field may set literally or as an expression the engine resolves. */
3
+ export type FieldFlag = string | boolean;
16
4
  /** NOT part of the workflow JSON schema — added by the form system at runtime. */
17
- interface RuntimeFieldExtensions {
5
+ export interface RuntimeFieldExtensions {
18
6
  name?: string;
19
7
  description?: string;
20
8
  showInUI?: boolean;
@@ -30,19 +18,17 @@ interface RuntimeFieldExtensions {
30
18
  resetOnChange?: boolean;
31
19
  options?: unknown;
32
20
  }
33
- /** Legacy — use schema types from workflow-schema.d.ts for new field components. */
34
21
  export interface BaseField extends RuntimeFieldExtensions {
35
22
  type: string;
36
23
  label?: string;
37
24
  tooltip?: string | string[];
38
- hidden?: Hidden;
39
- optional?: Optional;
40
- ignore?: Ignore;
25
+ hidden?: FieldFlag;
26
+ optional?: FieldFlag;
27
+ ignore?: FieldFlag;
41
28
  collapsed?: boolean;
42
29
  disabled?: boolean;
43
30
  default?: unknown;
44
31
  }
45
- /** Permissive type for backward-compatible components; new code uses workflow-schema.d.ts types. */
46
32
  type AnyField = BaseField;
47
33
  interface WizardConfig {
48
34
  /** Must be 'wizard' to activate wizard mode */
@@ -1,4 +1,4 @@
1
- import { type WorkflowVariables } from '@parallelworks/workflow-parser';
1
+ import type { WorkflowVariables } from '../engine.js';
2
2
  /**
3
3
  * useMemo won't work here — Formik values changes on every keystroke, so this hook extracts which inputs.* keys the schema references and re-parses only when those change. Defaults `userVars`/`secretKeys` to empty — callers in React scope should pass them from `useUserVars()` so the parser leaves `${{ var.SECRET }}` literal during template eval (otherwise the recursive substitution turns `"https://${{ var.PAT }}@host/"` into `"https://@host/"`).
4
4
  */
@@ -0,0 +1,62 @@
1
+ import { useWorkflowEngine } from "../components/Provider.js";
2
+ import { useRef } from "react";
3
+ import deepEqual from "fast-deep-equal";
4
+ //#region src/form/useParsedOpts.ts
5
+ var EMPTY_VARS = {};
6
+ var EMPTY_KEYS = [];
7
+ /**
8
+ * useMemo won't work here — Formik values changes on every keystroke, so this hook extracts which inputs.* keys the schema references and re-parses only when those change. Defaults `userVars`/`secretKeys` to empty — callers in React scope should pass them from `useUserVars()` so the parser leaves `${{ var.SECRET }}` literal during template eval (otherwise the recursive substitution turns `"https://${{ var.PAT }}@host/"` into `"https://@host/"`).
9
+ */
10
+ function useParsedOpts(rawOptions, values, organizationVariables, userVars = EMPTY_VARS, secretKeys = EMPTY_KEYS, remoteVars = EMPTY_VARS) {
11
+ const engine = useWorkflowEngine();
12
+ const c = useRef({
13
+ rawOptions: null,
14
+ orgVars: void 0,
15
+ userVars: null,
16
+ secretKeys: null,
17
+ remoteVars: null,
18
+ converted: {},
19
+ inputDeps: /* @__PURE__ */ new Set(),
20
+ hasExpressions: false,
21
+ relevantSnapshot: {},
22
+ result: null
23
+ }).current;
24
+ if (rawOptions !== c.rawOptions) {
25
+ c.rawOptions = rawOptions;
26
+ c.converted = engine.convertInputs(rawOptions);
27
+ const { inputDeps, hasExpressions } = engine.inputDependencies(c.converted);
28
+ c.inputDeps = inputDeps;
29
+ c.hasExpressions = hasExpressions;
30
+ c.result = null;
31
+ }
32
+ if (organizationVariables !== c.orgVars || userVars !== c.userVars || secretKeys !== c.secretKeys || remoteVars !== c.remoteVars) {
33
+ c.orgVars = organizationVariables;
34
+ c.userVars = userVars;
35
+ c.secretKeys = secretKeys;
36
+ c.remoteVars = remoteVars;
37
+ c.result = null;
38
+ }
39
+ if (c.result !== null) {
40
+ if (c.inputDeps.size === 0) return c.result;
41
+ let inputsChanged = false;
42
+ for (const key of c.inputDeps) if (!deepEqual(values[key], c.relevantSnapshot[key])) {
43
+ inputsChanged = true;
44
+ break;
45
+ }
46
+ if (!inputsChanged) return c.result;
47
+ }
48
+ const parsed = engine.evaluate({
49
+ inputs: values,
50
+ obj: c.converted,
51
+ orgVars: organizationVariables,
52
+ userVars,
53
+ secretKeys,
54
+ remoteVars
55
+ });
56
+ c.result = parsed;
57
+ c.relevantSnapshot = {};
58
+ for (const key of c.inputDeps) c.relevantSnapshot[key] = values[key];
59
+ return parsed;
60
+ }
61
+ //#endregion
62
+ export { useParsedOpts };
@@ -0,0 +1,11 @@
1
+ import { useEffect, useRef } from "react";
2
+ //#region src/form/usePrevious.ts
3
+ function usePrevious(value) {
4
+ const ref = useRef(void 0);
5
+ useEffect(() => {
6
+ ref.current = value;
7
+ });
8
+ return ref.current;
9
+ }
10
+ //#endregion
11
+ export { usePrevious };
@@ -0,0 +1,14 @@
1
+ import { getValueUsingPath } from "./getValueUsingPath.js";
2
+ //#region src/form/utils/checkShowIfObject.ts
3
+ function checkShowIfObject(showIfObject, formValues, index) {
4
+ const valueList = [];
5
+ for (let [key, value] of Object.entries(showIfObject)) {
6
+ if (index !== void 0) key = key.replace("[index]", `[${index}]`);
7
+ const dependsOnValue = getValueUsingPath(formValues, key);
8
+ if (typeof value === "boolean" || typeof value === "string" || typeof value === "number") valueList.push(dependsOnValue !== null && dependsOnValue !== void 0 && dependsOnValue.toString() === value.toString());
9
+ else if (Array.isArray(value)) valueList.push(value.includes(dependsOnValue));
10
+ }
11
+ return valueList;
12
+ }
13
+ //#endregion
14
+ export { checkShowIfObject };
@@ -1,5 +1,5 @@
1
- export declare function parseSlurmDuration(text: string): number | null;
2
- export declare function formatSecondsAsSlurmDuration(totalSeconds: number): string;
1
+ export declare function parseDuration(text: string): number | null;
2
+ export declare function formatDuration(totalSeconds: number): string;
3
3
  export declare const FLEX_MAX_DURATION_RANGE: {
4
4
  min: number;
5
5
  max: number;
@@ -0,0 +1,69 @@
1
+ import { Duration } from "luxon";
2
+ //#region src/form/utils/duration.ts
3
+ var WITH_DAYS = /^(\d+)-(\d{1,2})(?::(\d{1,2})(?::(\d{1,2}))?)?$/;
4
+ var WITHOUT_DAYS = /^(\d+):(\d{1,2}):(\d{1,2})$/;
5
+ function parseDuration(text) {
6
+ const trimmed = text.trim();
7
+ let days = 0;
8
+ let hours;
9
+ let minutes;
10
+ let seconds;
11
+ const withDays = trimmed.match(WITH_DAYS);
12
+ if (withDays) {
13
+ days = Number(withDays[1]);
14
+ hours = Number(withDays[2]);
15
+ minutes = Number(withDays[3] ?? 0);
16
+ seconds = Number(withDays[4] ?? 0);
17
+ if (hours > 23) return null;
18
+ } else {
19
+ const withoutDays = trimmed.match(WITHOUT_DAYS);
20
+ if (!withoutDays) return null;
21
+ hours = Number(withoutDays[1]);
22
+ minutes = Number(withoutDays[2]);
23
+ seconds = Number(withoutDays[3]);
24
+ }
25
+ if (minutes > 59 || seconds > 59) return null;
26
+ return days * 86400 + hours * 3600 + minutes * 60 + seconds;
27
+ }
28
+ function formatDuration(totalSeconds) {
29
+ if (!Number.isFinite(totalSeconds) || totalSeconds < 0) return "";
30
+ const parts = Duration.fromObject({ seconds: Math.floor(totalSeconds) }).shiftTo("days", "hours", "minutes", "seconds");
31
+ const pad = (n) => String(n).padStart(2, "0");
32
+ const time = `${pad(parts.hours)}:${pad(parts.minutes)}:${pad(parts.seconds)}`;
33
+ return parts.days > 0 ? `${parts.days}-${time}` : time;
34
+ }
35
+ var FLEX_MAX_DURATION_RANGE = {
36
+ min: 600,
37
+ max: 604800
38
+ };
39
+ var FLEX_WAIT_TIME_RANGE = {
40
+ min: 30,
41
+ max: 604800
42
+ };
43
+ var STANDARD_MAX_DURATION_RANGE = {
44
+ min: 30,
45
+ max: 10368e3
46
+ };
47
+ var DURATION_PATH = /^partitions\[\d+\]\.(maxDuration|flexStartWaitTime|suspendTime)$/;
48
+ function collectPartitionDurationIssues(partitions, invalidDurationPaths) {
49
+ const issues = new Set(invalidDurationPaths.filter((path) => DURATION_PATH.test(path)));
50
+ (partitions ?? []).forEach((partition, i) => {
51
+ const p = partition;
52
+ const check = (fieldName, range, required) => {
53
+ const raw = p?.[fieldName];
54
+ if (raw === void 0 || raw === null || raw === "") {
55
+ if (required) issues.add(`partitions[${i}].${fieldName}`);
56
+ return;
57
+ }
58
+ const value = Number(raw);
59
+ if (!Number.isFinite(value) || value < range.min || value > range.max) issues.add(`partitions[${i}].${fieldName}`);
60
+ };
61
+ if (p?.provisioningMode === "flex") {
62
+ check("maxDuration", FLEX_MAX_DURATION_RANGE, true);
63
+ check("flexStartWaitTime", FLEX_WAIT_TIME_RANGE, true);
64
+ } else check("maxDuration", STANDARD_MAX_DURATION_RANGE, false);
65
+ });
66
+ return [...issues];
67
+ }
68
+ //#endregion
69
+ export { FLEX_MAX_DURATION_RANGE, FLEX_WAIT_TIME_RANGE, STANDARD_MAX_DURATION_RANGE, collectPartitionDurationIssues, formatDuration, parseDuration };
@@ -0,0 +1,23 @@
1
+ import { getValueUsingPath } from "./getValueUsingPath.js";
2
+ import { checkShowIfObject } from "./checkShowIfObject.js";
3
+ //#region src/form/utils/getParentValue.ts
4
+ function getParentValue(index, targetField, values, dependentPath, field) {
5
+ let parentValue;
6
+ if (typeof targetField === "object" && targetField !== null && !Array.isArray(targetField)) parentValue = !checkShowIfObject(targetField, values, index).includes(false);
7
+ else if (field.depends_on) {
8
+ dependentPath = field.depends_on;
9
+ if (index !== void 0) dependentPath = field.depends_on.replace("[index]", `[${index}]`);
10
+ const dependsOnValue = getValueUsingPath(values, dependentPath);
11
+ const dependsOnText = dependsOnValue === null || dependsOnValue === void 0 ? void 0 : String(dependsOnValue);
12
+ if (Array.isArray(targetField)) parentValue = targetField.includes(dependsOnValue) || targetField.includes(dependsOnText);
13
+ else if (typeof targetField === "string") parentValue = dependsOnText !== void 0 && targetField.includes(dependsOnText);
14
+ else parentValue = targetField === dependsOnValue;
15
+ } else {
16
+ dependentPath = typeof targetField === "string" ? targetField : "";
17
+ if (index !== void 0 && typeof targetField === "string") dependentPath = targetField.replace("[index]", `[${index}]`);
18
+ parentValue = getValueUsingPath(values, dependentPath);
19
+ }
20
+ return parentValue;
21
+ }
22
+ //#endregion
23
+ export { getParentValue };
@@ -0,0 +1,9 @@
1
+ //#region src/form/utils/getPlaceholder.ts
2
+ /** `placeholder=""` (empty string) intentionally overrides the default; undefined does not. */
3
+ function getPlaceholder(placeholder, defaultValue) {
4
+ if (placeholder !== void 0) return placeholder;
5
+ if (defaultValue && (typeof defaultValue === "string" || typeof defaultValue === "number")) return defaultValue.toString();
6
+ return "";
7
+ }
8
+ //#endregion
9
+ export { getPlaceholder };
@@ -0,0 +1,23 @@
1
+ //#region src/form/utils/getValueUsingPath.ts
2
+ function getValueUsingPath(obj, path) {
3
+ if (typeof path !== "string" || !path) return;
4
+ const keys = path.split(".");
5
+ let current = obj;
6
+ for (const key of keys) {
7
+ if (!current || typeof current !== "object") return;
8
+ const container = current;
9
+ if (key.includes("[")) {
10
+ const [arrayKey = "", indexStr = ""] = key.split("[");
11
+ const index = parseInt(indexStr.slice(0, -1), 10);
12
+ const list = container[arrayKey];
13
+ if (!Array.isArray(list) || isNaN(index)) return;
14
+ current = list[index];
15
+ } else {
16
+ if (!(key in container)) return;
17
+ current = container[key];
18
+ }
19
+ }
20
+ return current;
21
+ }
22
+ //#endregion
23
+ export { getValueUsingPath };
@@ -0,0 +1,22 @@
1
+ //#region src/form/utils/secondaryField.ts
2
+ function findSecondaryOption(options, value) {
3
+ for (const candidate of options) {
4
+ if (!candidate || typeof candidate !== "object") continue;
5
+ const option = candidate;
6
+ if (option.value === value) return option;
7
+ if (Array.isArray(option.options)) {
8
+ const nestedOption = findSecondaryOption(option.options, value);
9
+ if (nestedOption) return nestedOption;
10
+ }
11
+ }
12
+ }
13
+ function applySecondaryField(secondaryField, secondaryValue, setFieldValue) {
14
+ if (secondaryField === void 0 || secondaryValue === void 0) return;
15
+ const fields = Array.isArray(secondaryField) ? secondaryField : [secondaryField];
16
+ const values = Array.isArray(secondaryValue) ? secondaryValue : [secondaryValue];
17
+ fields.forEach((field, index) => {
18
+ setFieldValue(field, values[index]);
19
+ });
20
+ }
21
+ //#endregion
22
+ export { applySecondaryField, findSecondaryOption };
@@ -0,0 +1,141 @@
1
+ import { ChevronDownIcon, ChevronRightIcon, ErrorIcon, InfoIcon, WarningIcon } from "../icons.js";
2
+ import { keyedByContent } from "../components/keys.js";
3
+ import cx from "classnames";
4
+ import { useState } from "react";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ //#region src/graph/AnnotationBanner.tsx
7
+ var typeOrder = {
8
+ error: 0,
9
+ warning: 1,
10
+ notice: 2
11
+ };
12
+ var typeConfig = {
13
+ error: {
14
+ icon: ErrorIcon,
15
+ label: "Error",
16
+ accentClass: "text-red-500",
17
+ bgClass: "bg-red-500/5 dark:bg-red-500/10",
18
+ countBg: "bg-red-500/15 text-red-700 dark:text-red-400"
19
+ },
20
+ warning: {
21
+ icon: WarningIcon,
22
+ label: "Warning",
23
+ accentClass: "text-yellow-500",
24
+ bgClass: "bg-yellow-500/5 dark:bg-yellow-500/10",
25
+ countBg: "bg-yellow-500/15 text-yellow-700 dark:text-yellow-400"
26
+ },
27
+ notice: {
28
+ icon: InfoIcon,
29
+ label: "Notice",
30
+ accentClass: "text-blue-500",
31
+ bgClass: "bg-blue-500/5 dark:bg-blue-500/10",
32
+ countBg: "bg-blue-500/15 text-blue-700 dark:text-blue-400"
33
+ }
34
+ };
35
+ function collectAnnotations(executedJobs, parentPath) {
36
+ const annotations = [];
37
+ for (const [jobName, job] of Object.entries(executedJobs)) {
38
+ const fullJobName = parentPath ? `${parentPath} > ${jobName}` : jobName;
39
+ const steps = job?.steps;
40
+ if (!Array.isArray(steps)) continue;
41
+ for (let stepIndex = 0; stepIndex < steps.length; stepIndex++) {
42
+ const step = steps[stepIndex];
43
+ const stepAnnotations = step?.annotations;
44
+ if (Array.isArray(stepAnnotations)) {
45
+ for (const annotation of stepAnnotations) if (annotation?.message) annotations.push({
46
+ type: annotation.type || "notice",
47
+ message: annotation.message,
48
+ title: annotation.title,
49
+ file: annotation.file,
50
+ line: annotation.line,
51
+ jobName: fullJobName,
52
+ stepName: step?.name,
53
+ stepIndex
54
+ });
55
+ }
56
+ const subJobs = step?.subworkflow?.jobs;
57
+ if (subJobs && typeof subJobs === "object") annotations.push(...collectAnnotations(subJobs, fullJobName));
58
+ }
59
+ }
60
+ annotations.sort((a, b) => (typeOrder[a.type] ?? 2) - (typeOrder[b.type] ?? 2));
61
+ return annotations;
62
+ }
63
+ function AnnotationBanner({ executedJobs }) {
64
+ const [expanded, setExpanded] = useState(false);
65
+ if (!executedJobs) return null;
66
+ const annotations = collectAnnotations(executedJobs);
67
+ if (annotations.length === 0) return null;
68
+ const counts = {
69
+ error: 0,
70
+ warning: 0,
71
+ notice: 0
72
+ };
73
+ for (const a of annotations) counts[a.type]++;
74
+ const ChevronIcon = expanded ? ChevronDownIcon : ChevronRightIcon;
75
+ return /* @__PURE__ */ jsxs("div", {
76
+ className: cx("rounded-lg border border-[var(--theme-border)] overflow-hidden", "bg-[var(--theme-panel-bg)]"),
77
+ children: [/* @__PURE__ */ jsxs("button", {
78
+ type: "button",
79
+ onClick: () => setExpanded((prev) => !prev),
80
+ className: cx("w-full flex items-center gap-3 px-4 py-2.5 text-left", "hover:bg-[var(--theme-hover)] transition-colors", expanded && "border-b border-[var(--theme-border)]"),
81
+ children: [
82
+ /* @__PURE__ */ jsx(ChevronIcon, { className: "w-3.5 h-3.5 text-[var(--theme-muted-text-color)] shrink-0" }),
83
+ /* @__PURE__ */ jsx("span", {
84
+ className: "text-sm font-medium text-[var(--theme-panel-color)]",
85
+ children: "Annotations"
86
+ }),
87
+ /* @__PURE__ */ jsx("div", {
88
+ className: "flex items-center gap-1.5",
89
+ children: [
90
+ "error",
91
+ "warning",
92
+ "notice"
93
+ ].map((type) => {
94
+ if (!counts[type]) return null;
95
+ const config = typeConfig[type];
96
+ const Icon = config.icon;
97
+ return /* @__PURE__ */ jsxs("span", {
98
+ className: cx("inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs font-medium", config.countBg),
99
+ children: [/* @__PURE__ */ jsx(Icon, { className: "w-3 h-3" }), counts[type]]
100
+ }, type);
101
+ })
102
+ })
103
+ ]
104
+ }), expanded && /* @__PURE__ */ jsx("div", {
105
+ className: "divide-y divide-[var(--theme-border)] max-h-[400px] overflow-y-auto",
106
+ children: keyedByContent(annotations, (a) => a.id ?? `${a.type}:${a.title}:${a.message}`).map(({ key, item: annotation }) => {
107
+ const config = typeConfig[annotation.type] || typeConfig.notice;
108
+ const Icon = config.icon;
109
+ return /* @__PURE__ */ jsxs("div", {
110
+ className: cx("flex items-start gap-2.5 px-4 py-2 text-sm", config.bgClass),
111
+ children: [/* @__PURE__ */ jsx(Icon, { className: cx("w-4 h-4 mt-0.5 shrink-0", config.accentClass) }), /* @__PURE__ */ jsxs("div", {
112
+ className: "flex-1 min-w-0",
113
+ children: [
114
+ /* @__PURE__ */ jsxs("span", {
115
+ className: cx("font-medium", config.accentClass),
116
+ children: [annotation.title || config.label, ":"]
117
+ }),
118
+ " ",
119
+ /* @__PURE__ */ jsx("span", {
120
+ className: "text-[var(--theme-panel-color)]",
121
+ children: annotation.message
122
+ }),
123
+ /* @__PURE__ */ jsxs("span", {
124
+ className: "text-[var(--theme-muted-text-color)] ml-2 text-xs",
125
+ children: [
126
+ "in ",
127
+ annotation.jobName,
128
+ " →",
129
+ " ",
130
+ annotation.stepName || `step ${annotation.stepIndex}`
131
+ ]
132
+ })
133
+ ]
134
+ })]
135
+ }, key);
136
+ })
137
+ })]
138
+ });
139
+ }
140
+ //#endregion
141
+ export { AnnotationBanner };
@@ -0,0 +1,41 @@
1
+ import { useState } from "react";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { AnimatePresence, motion } from "framer-motion";
4
+ //#region src/graph/Collapse.tsx
5
+ function Collapse({ expanded, children, releaseOverflow = true }) {
6
+ const [overflowVisible, setOverflowVisible] = useState(false);
7
+ return /* @__PURE__ */ jsx(AnimatePresence, {
8
+ initial: false,
9
+ children: expanded && /* @__PURE__ */ jsx(motion.div, {
10
+ initial: {
11
+ height: 0,
12
+ opacity: 0
13
+ },
14
+ animate: {
15
+ height: "auto",
16
+ opacity: 1
17
+ },
18
+ exit: {
19
+ height: 0,
20
+ opacity: 0
21
+ },
22
+ transition: {
23
+ duration: .2,
24
+ ease: [
25
+ .25,
26
+ .1,
27
+ .25,
28
+ 1
29
+ ]
30
+ },
31
+ style: { overflow: overflowVisible ? "visible" : "hidden" },
32
+ onAnimationStart: () => setOverflowVisible(false),
33
+ onAnimationComplete: () => {
34
+ if (expanded && releaseOverflow) setOverflowVisible(true);
35
+ },
36
+ children
37
+ }, "collapse")
38
+ });
39
+ }
40
+ //#endregion
41
+ export { Collapse };