@morscherlab/mint-sdk 1.2.0-beta.1 → 1.2.0-beta.11

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 (408) hide show
  1. package/README.md +35 -5
  2. package/dist/{ExperimentPopover-tLwJ7XF4.js → ExperimentPopover-oL0fg_A0.js} +6 -4
  3. package/dist/ExperimentPopover-oL0fg_A0.js.map +1 -0
  4. package/dist/{ExperimentSelectorModal-DyPAUCLw.js → ExperimentSelectorModal-BeEOomw_.js} +5 -5
  5. package/dist/ExperimentSelectorModal-BeEOomw_.js.map +1 -0
  6. package/dist/{SettingsModal-BgKY93zh.js → SettingsModal-Dphh3RrI.js} +5 -8
  7. package/dist/SettingsModal-Dphh3RrI.js.map +1 -0
  8. package/dist/{EmptyState-p90quq8Z.js → Skeleton-DxtwJ5gt.js} +111 -93
  9. package/dist/Skeleton-DxtwJ5gt.js.map +1 -0
  10. package/dist/__tests__/components/ExperimentTimeline.test.d.ts +1 -0
  11. package/dist/__tests__/components/PluginWorkspaceView.internal.test.d.ts +1 -0
  12. package/dist/__tests__/components/SecretInput.test.d.ts +1 -0
  13. package/dist/__tests__/components/WellEditPopupInternal.test.d.ts +1 -0
  14. package/dist/__tests__/composables/useListReorder.test.d.ts +1 -0
  15. package/dist/__tests__/composables/usePluginConfig.test.d.ts +15 -0
  16. package/dist/__tests__/styles/cssTokens.test.d.ts +1 -0
  17. package/dist/components/ActionMenu.vue.d.ts +1 -1
  18. package/dist/components/AppAvatarMenu.vue.d.ts +4 -0
  19. package/dist/components/AppPluginSwitcher.vue.d.ts +2 -0
  20. package/dist/components/AppSidebar.vue.d.ts +1 -1
  21. package/dist/components/AuditTrail.vue.d.ts +13 -0
  22. package/dist/components/AutoGroupModal.vue.d.ts +1 -1
  23. package/dist/components/BatchProgressList.vue.d.ts +17 -0
  24. package/dist/components/BioTemplateExperimentWorkspaceView.vue.d.ts +2 -2
  25. package/dist/components/DataFrame.vue.d.ts +14 -2
  26. package/dist/components/DatePicker.vue.d.ts +1 -1
  27. package/dist/components/DateTimePicker.vue.d.ts +2 -0
  28. package/dist/components/DropdownButton.vue.d.ts +2 -0
  29. package/dist/components/ExperimentDataViewer.vue.d.ts +26 -1
  30. package/dist/components/ExperimentPopover.vue.d.ts +1 -0
  31. package/dist/components/ExperimentTimeline.vue.d.ts +29 -1
  32. package/dist/components/FitPanel.vue.d.ts +1 -1
  33. package/dist/components/JobsStatusTray.vue.d.ts +9 -2
  34. package/dist/components/LcmsSequenceTable.vue.d.ts +29 -1
  35. package/dist/components/PluginWorkspaceView.props.d.ts +29 -1
  36. package/dist/components/PluginWorkspaceView.vue.d.ts +5 -5
  37. package/dist/components/ProgressBar.vue.d.ts +1 -1
  38. package/dist/components/ProtocolStepEditor.vue.d.ts +1 -0
  39. package/dist/components/ReagentList.vue.d.ts +29 -1
  40. package/dist/components/SampleHierarchyTree.vue.d.ts +29 -1
  41. package/dist/components/SampleLegend.vue.d.ts +1 -1
  42. package/dist/components/SampleSelector.drag.d.ts +13 -0
  43. package/dist/components/SampleSelector.tree.d.ts +2 -0
  44. package/dist/components/SampleSelector.vue.d.ts +35 -2
  45. package/dist/components/ScheduleCalendar.vue.d.ts +20 -0
  46. package/dist/components/SecretInput.vue.d.ts +28 -0
  47. package/dist/components/SettingsModal.vue.d.ts +1 -1
  48. package/dist/components/SmartGroupFieldRecipe.vue.d.ts +2 -1
  49. package/dist/components/TimePicker.vue.d.ts +1 -0
  50. package/dist/components/WellPlate.geometry.d.ts +15 -0
  51. package/dist/components/WellPlate.interaction.d.ts +13 -0
  52. package/dist/components/WellPlate.vue.d.ts +29 -0
  53. package/dist/components/index.d.ts +9 -0
  54. package/dist/components/index.js +8 -8
  55. package/dist/components/internal/AppTopBarPageSelectorInternal.vue.d.ts +2 -0
  56. package/dist/components/internal/DataStateInternal.vue.d.ts +43 -0
  57. package/dist/components/internal/WellEditPopupInternal.vue.d.ts +3 -1
  58. package/dist/components/internal/WorkspaceControlsInternal.vue.d.ts +23 -0
  59. package/dist/components/internal/WorkspaceShellInternal.vue.d.ts +70 -0
  60. package/dist/components/internal/WorkspaceSidebarInternal.vue.d.ts +43 -0
  61. package/dist/{components-DkHddRMl.js → components-CgAUzF8F.js} +2497 -2235
  62. package/dist/components-CgAUzF8F.js.map +1 -0
  63. package/dist/composables/controlSchemaTypes.d.ts +34 -0
  64. package/dist/composables/flattenWorkspaceBindings.d.ts +61 -0
  65. package/dist/composables/index.d.ts +9 -2
  66. package/dist/composables/index.js +10 -10
  67. package/dist/composables/pluginWorkspaceModel.d.ts +164 -0
  68. package/dist/composables/useAsync.d.ts +5 -1
  69. package/dist/composables/useBioTemplateWorkspace.d.ts +4 -20
  70. package/dist/composables/useCommandHistory.d.ts +5 -1
  71. package/dist/composables/useDropdownState.d.ts +18 -2
  72. package/dist/composables/useEventStream.d.ts +9 -0
  73. package/dist/composables/useFocusTrap.d.ts +21 -0
  74. package/dist/composables/useGeneratedAnalysis.d.ts +3 -1
  75. package/dist/composables/useJobsStatusTray.d.ts +25 -1
  76. package/dist/composables/useListReorder.d.ts +90 -0
  77. package/dist/composables/useMenuKeyboard.d.ts +29 -0
  78. package/dist/composables/useOptimisticMutation.d.ts +5 -1
  79. package/dist/composables/usePluginClient.d.ts +2 -0
  80. package/dist/composables/usePluginConfig.d.ts +27 -0
  81. package/dist/composables/usePluginWorkspace.d.ts +51 -0
  82. package/dist/composables/useRequestSyncState.d.ts +42 -2
  83. package/dist/composables/useResourceCrud.d.ts +5 -1
  84. package/dist/composables/useRovingFocus.d.ts +24 -0
  85. package/dist/composables/useScheduleDrag.d.ts +1 -0
  86. package/dist/composables/useWellPainting.d.ts +5 -1
  87. package/dist/composables/useWellPlateAdapter.d.ts +5 -1
  88. package/dist/composables/useWellPlateValidation.d.ts +5 -1
  89. package/dist/composables/workspaceRecipes.d.ts +188 -0
  90. package/dist/{composables-C_i90sGS.js → composables-B_pia3hO.js} +209 -82
  91. package/dist/composables-B_pia3hO.js.map +1 -0
  92. package/dist/{useApi-J6zFkHmn.js → errors-_W0-LbA6.js} +103 -3
  93. package/dist/errors-_W0-LbA6.js.map +1 -0
  94. package/dist/{experiment-Cq145oEW.js → experiment-Cwl9AYxw.js} +3 -8
  95. package/dist/experiment-Cwl9AYxw.js.map +1 -0
  96. package/dist/{experiment-utils-CLnzPPq5.js → experiment-utils-DV3DrvE_.js} +70 -51
  97. package/dist/experiment-utils-DV3DrvE_.js.map +1 -0
  98. package/dist/index.d.ts +1 -0
  99. package/dist/index.js +15 -15
  100. package/dist/install.js +2 -7
  101. package/dist/install.js.map +1 -1
  102. package/dist/permissions.d.ts +42 -1
  103. package/dist/permissions.js +20 -10
  104. package/dist/permissions.js.map +1 -1
  105. package/dist/stores/auth.d.ts +6 -0
  106. package/dist/stores/index.d.ts +1 -1
  107. package/dist/stores/index.js +3 -3
  108. package/dist/stores/settings.d.ts +31 -1
  109. package/dist/styles.css +11247 -29501
  110. package/dist/templates/builderReadUtils.d.ts +1 -1
  111. package/dist/templates/index.js +2 -4
  112. package/dist/{templates-DsP51i-S.js → templates-Qq113pyZ.js} +303 -106
  113. package/dist/templates-Qq113pyZ.js.map +1 -0
  114. package/dist/types/auth.d.ts +1 -0
  115. package/dist/types/form-builder.d.ts +1 -1
  116. package/dist/{useControlSchema-BDx2Olha.js → useControlSchema-aMZlb4Sc.js} +462 -1130
  117. package/dist/useControlSchema-aMZlb4Sc.js.map +1 -0
  118. package/dist/{useDropdownState-DSb3BC3N.js → useDropdownState-DitCtrTT.js} +22 -6
  119. package/dist/useDropdownState-DitCtrTT.js.map +1 -0
  120. package/dist/{useExperimentSelector-CV4iNfMS.js → useExperimentSelector-I8HC8hUu.js} +4 -4
  121. package/dist/{useExperimentSelector-CV4iNfMS.js.map → useExperimentSelector-I8HC8hUu.js.map} +1 -1
  122. package/dist/{useFormBuilder-BLxG3BOX.js → useFormBuilder-TCxNnqeb.js} +2 -2
  123. package/dist/{useFormBuilder-BLxG3BOX.js.map → useFormBuilder-TCxNnqeb.js.map} +1 -1
  124. package/dist/{useProtocolTemplates-CS_SQl6U.js → useProtocolTemplates-BmX_iVBR.js} +766 -212
  125. package/dist/useProtocolTemplates-BmX_iVBR.js.map +1 -0
  126. package/dist/utils/color.d.ts +13 -0
  127. package/dist/utils/errors.d.ts +9 -0
  128. package/dist/utils/pluginSecrets.d.ts +53 -0
  129. package/dist/utils/records.d.ts +4 -0
  130. package/package.json +1 -1
  131. package/src/__tests__/components/ActionMenu.test.ts +94 -0
  132. package/src/__tests__/components/AppAvatarMenu.test.ts +123 -0
  133. package/src/__tests__/components/BaseTabs.test.ts +67 -0
  134. package/src/__tests__/components/DataFrame.test.ts +183 -11
  135. package/src/__tests__/components/DataStates.test.ts +176 -0
  136. package/src/__tests__/components/DatePicker.test.ts +76 -0
  137. package/src/__tests__/components/DateTimePicker.test.ts +36 -0
  138. package/src/__tests__/components/DropdownButton.test.ts +134 -0
  139. package/src/__tests__/components/ExperimentTimeline.test.ts +63 -0
  140. package/src/__tests__/components/GroupAssigner.test.ts +53 -0
  141. package/src/__tests__/components/LcmsSequenceTable.test.ts +22 -0
  142. package/src/__tests__/components/PluginWorkspaceView.internal.test.ts +230 -0
  143. package/src/__tests__/components/RackEditor.test.ts +35 -0
  144. package/src/__tests__/components/ReagentList.test.ts +64 -2
  145. package/src/__tests__/components/RetiredStyles.test.ts +31 -0
  146. package/src/__tests__/components/SampleSelector.drag.test.ts +51 -1
  147. package/src/__tests__/components/ScheduleCalendar.test.ts +63 -0
  148. package/src/__tests__/components/SecretInput.test.ts +87 -0
  149. package/src/__tests__/components/SegmentedControl.test.ts +88 -0
  150. package/src/__tests__/components/TimePicker.test.ts +61 -0
  151. package/src/__tests__/components/WellEditPopupInternal.test.ts +108 -0
  152. package/src/__tests__/components/WellPlate.interaction.test.ts +59 -0
  153. package/src/__tests__/composables/useAuth.test.ts +2 -0
  154. package/src/__tests__/composables/useDropdownState.test.ts +58 -1
  155. package/src/__tests__/composables/useListReorder.test.ts +145 -0
  156. package/src/__tests__/composables/usePluginClient.test.ts +140 -0
  157. package/src/__tests__/composables/usePluginConfig.test.ts +497 -0
  158. package/src/__tests__/composables/useRequestSyncState.test.ts +140 -0
  159. package/src/__tests__/docs/frontendDocsCatalog.test.ts +39 -7
  160. package/src/__tests__/stores/settings.test.ts +71 -1
  161. package/src/__tests__/styles/cssTokens.test.ts +131 -0
  162. package/src/__tests__/utils/permissions.test.ts +68 -0
  163. package/src/components/ActionMenu.vue +45 -88
  164. package/src/components/AlertBox.vue +0 -4
  165. package/src/components/AppAvatarMenu.vue +26 -7
  166. package/src/components/AppLayout.vue +0 -4
  167. package/src/components/AppPluginSwitcher.story.vue +87 -0
  168. package/src/components/AppPluginSwitcher.vue +2 -5
  169. package/src/components/AppSidebar.vue +0 -4
  170. package/src/components/AppToastContainer.vue +6 -8
  171. package/src/components/AppTopBar.vue +0 -4
  172. package/src/components/ArtifactSaveDialog.vue +0 -4
  173. package/src/components/ArtifactSelectorModal.vue +0 -4
  174. package/src/components/AuditTrail.story.vue +18 -0
  175. package/src/components/AuditTrail.vue +27 -7
  176. package/src/components/AutoGroupModal.vue +0 -4
  177. package/src/components/Avatar.vue +0 -4
  178. package/src/components/BaseButton.vue +0 -4
  179. package/src/components/BaseCheckbox.vue +0 -4
  180. package/src/components/BaseInput.vue +0 -4
  181. package/src/components/BaseModal.vue +8 -60
  182. package/src/components/BasePill.vue +0 -4
  183. package/src/components/BaseRadioGroup.vue +0 -4
  184. package/src/components/BaseSelect.vue +0 -4
  185. package/src/components/BaseSlider.vue +0 -4
  186. package/src/components/BaseTabs.vue +26 -5
  187. package/src/components/BaseTextarea.vue +0 -4
  188. package/src/components/BaseToggle.vue +0 -4
  189. package/src/components/BatchProgressList.story.vue +18 -0
  190. package/src/components/BatchProgressList.vue +32 -4
  191. package/src/components/BioTemplateExperimentWorkspaceView.vue +10 -21
  192. package/src/components/BioTemplatePackWorkspaceView.vue +11 -15
  193. package/src/components/BioTemplatePresetWorkspaceView.vue +8 -13
  194. package/src/components/Breadcrumb.vue +0 -4
  195. package/src/components/Calendar.vue +0 -4
  196. package/src/components/ChartContainer.story.vue +1 -1
  197. package/src/components/ChartContainer.vue +0 -4
  198. package/src/components/ChemicalFormula.vue +0 -4
  199. package/src/components/CollapsibleCard.vue +0 -4
  200. package/src/components/ColorSlider.vue +0 -4
  201. package/src/components/ComponentBindingRenderer.vue +1 -3
  202. package/src/components/ConcentrationInput.vue +0 -4
  203. package/src/components/ConfirmDialog.vue +0 -4
  204. package/src/components/ControlWorkspaceView.vue +11 -22
  205. package/src/components/DataFrame.story.vue +14 -0
  206. package/src/components/DataFrame.vue +97 -23
  207. package/src/components/DatePicker.vue +73 -27
  208. package/src/components/DateTimePicker.vue +45 -17
  209. package/src/components/Divider.vue +0 -4
  210. package/src/components/DoseCalculator.vue +0 -4
  211. package/src/components/DoseDesignWorkspaceView.vue +6 -25
  212. package/src/components/DropdownButton.vue +24 -6
  213. package/src/components/EmptyState.vue +0 -4
  214. package/src/components/ExperimentCodeBadge.vue +0 -4
  215. package/src/components/ExperimentDataViewer.story.vue +3 -0
  216. package/src/components/ExperimentDataViewer.vue +33 -13
  217. package/src/components/ExperimentPopover.vue +2 -5
  218. package/src/components/ExperimentSelectorModal.vue +0 -4
  219. package/src/components/ExperimentTimeline.story.vue +18 -0
  220. package/src/components/ExperimentTimeline.vue +81 -75
  221. package/src/components/FileUploader.vue +0 -4
  222. package/src/components/FitPanel.vue +0 -4
  223. package/src/components/FormActions.story.vue +96 -0
  224. package/src/components/FormActions.vue +0 -4
  225. package/src/components/FormBuilder.vue +0 -4
  226. package/src/components/FormField.vue +0 -4
  227. package/src/components/FormulaInput.vue +0 -4
  228. package/src/components/GeneratedPathInput.story.vue +68 -0
  229. package/src/components/GeneratedPlotlyResult.story.vue +96 -0
  230. package/src/components/GeneratedPlotlyResult.vue +3 -3
  231. package/src/components/GeneratedPluginView.story.vue +145 -0
  232. package/src/components/GeneratedPluginView.vue +10 -10
  233. package/src/components/GeneratedResultRenderer.story.vue +117 -0
  234. package/src/components/GeneratedResultRenderer.vue +4 -4
  235. package/src/components/GroupAssigner.vue +67 -5
  236. package/src/components/IconButton.vue +0 -4
  237. package/src/components/InstrumentAlertLog.vue +0 -4
  238. package/src/components/InstrumentStateBadge.vue +0 -4
  239. package/src/components/InstrumentStatusCard.vue +0 -4
  240. package/src/components/JobsStatusTray.vue +16 -5
  241. package/src/components/LcmsSequenceTable.vue +81 -50
  242. package/src/components/LoadingSpinner.vue +0 -4
  243. package/src/components/MobileSupportGate.vue +0 -4
  244. package/src/components/MoleculeInput.vue +0 -4
  245. package/src/components/MultiSelect.vue +0 -4
  246. package/src/components/NumberInput.vue +0 -4
  247. package/src/components/PlateMapEditor.vue +3 -14
  248. package/src/components/PluginIcon.vue +0 -4
  249. package/src/components/PluginWorkspaceView.props.ts +38 -0
  250. package/src/components/PluginWorkspaceView.vue +53 -224
  251. package/src/components/ProgressBar.vue +0 -4
  252. package/src/components/ProtocolStepEditor.vue +2 -4
  253. package/src/components/RackEditor.vue +51 -70
  254. package/src/components/ReagentEditor.vue +0 -4
  255. package/src/components/ReagentList.story.vue +18 -0
  256. package/src/components/ReagentList.vue +127 -82
  257. package/src/components/ResourceCard.vue +0 -4
  258. package/src/components/RuntimeUpdateNotice.story.vue +49 -0
  259. package/src/components/RuntimeUpdateNotice.vue +4 -4
  260. package/src/components/SampleHierarchyTree.story.vue +18 -0
  261. package/src/components/SampleHierarchyTree.vue +32 -9
  262. package/src/components/SampleLegend.vue +2 -8
  263. package/src/components/SampleSelector.drag.ts +51 -0
  264. package/src/components/SampleSelector.story.vue +6 -0
  265. package/src/components/SampleSelector.tree.ts +2 -0
  266. package/src/components/SampleSelector.vue +49 -10
  267. package/src/components/SampleSelectorGroupNode.vue +19 -0
  268. package/src/components/ScheduleCalendar.story.vue +6 -0
  269. package/src/components/ScheduleCalendar.vue +82 -7
  270. package/src/components/ScientificNumber.vue +0 -4
  271. package/src/components/SecretInput.story.vue +79 -0
  272. package/src/components/SecretInput.vue +150 -0
  273. package/src/components/SectionCard.vue +0 -4
  274. package/src/components/SegmentedControl.vue +48 -5
  275. package/src/components/SequenceInput.vue +0 -4
  276. package/src/components/SequenceProgressBar.story.vue +110 -0
  277. package/src/components/SequenceProgressBar.vue +0 -4
  278. package/src/components/SettingsModal.vue +0 -4
  279. package/src/components/Skeleton.vue +0 -4
  280. package/src/components/SmartGroupFieldRecipe.vue +8 -6
  281. package/src/components/SmartGroupManual.vue +0 -4
  282. package/src/components/StatusIndicator.vue +0 -4
  283. package/src/components/StepWizard.vue +0 -4
  284. package/src/components/TagsInput.vue +4 -6
  285. package/src/components/ThemeToggle.vue +0 -4
  286. package/src/components/TimePicker.vue +36 -7
  287. package/src/components/TimeRangeInput.vue +0 -4
  288. package/src/components/Tooltip.story.vue +3 -3
  289. package/src/components/Tooltip.vue +0 -4
  290. package/src/components/UnitInput.vue +0 -4
  291. package/src/components/WellPlate.geometry.ts +60 -1
  292. package/src/components/WellPlate.interaction.ts +44 -0
  293. package/src/components/WellPlate.story.vue +8 -0
  294. package/src/components/WellPlate.vue +53 -7
  295. package/src/components/index.ts +9 -0
  296. package/src/components/internal/AppTopBarPageSelectorInternal.vue +2 -5
  297. package/src/components/internal/AppTopBarPillNavInternal.vue +0 -4
  298. package/src/components/internal/DataStateInternal.vue +74 -0
  299. package/src/components/internal/FormSectionRenderer.vue +0 -4
  300. package/src/components/internal/WellEditPopupInternal.vue +20 -5
  301. package/src/components/internal/WorkspaceControlsInternal.vue +20 -0
  302. package/src/components/internal/WorkspaceShellInternal.vue +125 -0
  303. package/src/components/internal/WorkspaceSidebarInternal.vue +82 -0
  304. package/src/composables/controlSchemaTypes.ts +34 -0
  305. package/src/composables/experimentDesignData.ts +1 -3
  306. package/src/composables/flattenWorkspaceBindings.ts +104 -0
  307. package/src/composables/formBuilderRegistry.ts +5 -0
  308. package/src/composables/index.ts +43 -0
  309. package/src/composables/pluginWorkspaceModel.ts +182 -0
  310. package/src/composables/useAsync.ts +5 -1
  311. package/src/composables/useAuth.ts +3 -0
  312. package/src/composables/useBioTemplatePackWorkspace.ts +15 -9
  313. package/src/composables/useBioTemplatePresetWorkspace.ts +14 -15
  314. package/src/composables/useBioTemplateWorkspace.ts +18 -43
  315. package/src/composables/useCommandHistory.ts +5 -1
  316. package/src/composables/useDropdownState.ts +35 -5
  317. package/src/composables/useEventStream.ts +14 -2
  318. package/src/composables/useFileImport.ts +2 -7
  319. package/src/composables/useFocusTrap.ts +91 -0
  320. package/src/composables/useGeneratedAnalysis.ts +22 -10
  321. package/src/composables/useJobsStatusTray.ts +184 -17
  322. package/src/composables/useListReorder.story.vue +143 -0
  323. package/src/composables/useListReorder.ts +242 -0
  324. package/src/composables/useMenuKeyboard.ts +90 -0
  325. package/src/composables/useOptimisticMutation.ts +6 -16
  326. package/src/composables/usePluginClient.ts +47 -4
  327. package/src/composables/usePluginConfig.ts +252 -0
  328. package/src/composables/usePluginWorkspace.ts +208 -0
  329. package/src/composables/useRackEditor.ts +2 -11
  330. package/src/composables/useRequestSyncState.ts +98 -28
  331. package/src/composables/useResourceCrud.ts +6 -16
  332. package/src/composables/useRovingFocus.ts +66 -0
  333. package/src/composables/useScheduleDrag.ts +37 -0
  334. package/src/composables/useWellPainting.ts +10 -30
  335. package/src/composables/useWellPlateAdapter.ts +5 -1
  336. package/src/composables/useWellPlateEditor.ts +1 -11
  337. package/src/composables/useWellPlateValidation.ts +5 -1
  338. package/src/composables/workspaceRecipes.ts +267 -0
  339. package/src/index.ts +16 -0
  340. package/src/permissions.ts +48 -9
  341. package/src/stores/auth.ts +1 -0
  342. package/src/stores/experiment.ts +2 -7
  343. package/src/stores/index.ts +9 -1
  344. package/src/stores/settings.ts +93 -1
  345. package/src/styles/components/audit-trail.css +5 -5
  346. package/src/styles/components/batch-progress-list.css +7 -0
  347. package/src/styles/components/color-slider.css +2 -2
  348. package/src/styles/components/data-state.css +30 -0
  349. package/src/styles/components/dataframe.css +29 -35
  350. package/src/styles/components/experiment-data-viewer.css +4 -4
  351. package/src/styles/components/experiment-timeline.css +3 -30
  352. package/src/styles/components/form-builder.css +5 -5
  353. package/src/styles/components/lcms-sequence-table.css +16 -1
  354. package/src/styles/components/multi-select.css +1 -1
  355. package/src/styles/components/reagent-list.css +38 -31
  356. package/src/styles/components/sample-hierarchy-tree.css +5 -19
  357. package/src/styles/components/sample-selector.css +9 -2
  358. package/src/styles/components/schedule-calendar.css +8 -0
  359. package/src/styles/components/scientific-number.css +1 -1
  360. package/src/styles/components/secret-input.css +60 -0
  361. package/src/styles/components/well-plate.css +8 -0
  362. package/src/styles/index.css +9 -0
  363. package/src/styles/variables.css +29 -0
  364. package/src/templates/builderPresetControls.ts +1 -1
  365. package/src/templates/builderReadUtils.ts +1 -3
  366. package/src/templates/componentPlateHelpers.ts +3 -1
  367. package/src/templates/componentTargetResolvers.ts +1 -3
  368. package/src/templates/controlSchemaTargets.ts +1 -3
  369. package/src/templates/doseResponseAdapters.ts +2 -13
  370. package/src/templates/elisaAssayCollectionBuilder.ts +2 -2
  371. package/src/templates/plateMapBuilder.ts +2 -2
  372. package/src/templates/qpcrPlateBuilder.ts +1 -1
  373. package/src/templates/templateValidators.ts +1 -1
  374. package/src/templates/timeCourseBuilder.ts +2 -2
  375. package/src/templates/wellPlateScreenCollectionBuilder.ts +2 -2
  376. package/src/types/auth.ts +1 -0
  377. package/src/types/form-builder.ts +1 -0
  378. package/src/utils/color.ts +51 -0
  379. package/src/utils/errors.ts +29 -0
  380. package/src/utils/formModelSync.ts +1 -3
  381. package/src/utils/pluginIcon.ts +1 -3
  382. package/src/utils/pluginSecrets.ts +102 -0
  383. package/src/utils/records.ts +9 -0
  384. package/dist/EmptyState-p90quq8Z.js.map +0 -1
  385. package/dist/ExperimentPopover-tLwJ7XF4.js.map +0 -1
  386. package/dist/ExperimentSelectorModal-DyPAUCLw.js.map +0 -1
  387. package/dist/SettingsModal-BgKY93zh.js.map +0 -1
  388. package/dist/components-DkHddRMl.js.map +0 -1
  389. package/dist/composables/autoGroupConstants.d.ts +0 -1
  390. package/dist/composables/autoGroupGrouping.d.ts +0 -3
  391. package/dist/composables/useAutoGroupInputSources.d.ts +0 -32
  392. package/dist/composables-C_i90sGS.js.map +0 -1
  393. package/dist/experiment-Cq145oEW.js.map +0 -1
  394. package/dist/experiment-utils-CLnzPPq5.js.map +0 -1
  395. package/dist/templates/builderDefaults.d.ts +0 -1
  396. package/dist/templates/plateGeometry.d.ts +0 -4
  397. package/dist/templates-DsP51i-S.js.map +0 -1
  398. package/dist/useApi-J6zFkHmn.js.map +0 -1
  399. package/dist/useControlSchema-BDx2Olha.js.map +0 -1
  400. package/dist/useDropdownState-DSb3BC3N.js.map +0 -1
  401. package/dist/useProtocolTemplates-CS_SQl6U.js.map +0 -1
  402. package/src/__tests__/composables/useAutoGroupInputSources.test.ts +0 -127
  403. package/src/composables/autoGroupConstants.ts +0 -4
  404. package/src/composables/autoGroupGrouping.ts +0 -148
  405. package/src/composables/useAutoGroupInputSources.ts +0 -147
  406. package/src/templates/builderDefaults.ts +0 -11
  407. package/src/templates/plateGeometry.ts +0 -62
  408. /package/dist/__tests__/{composables/useAutoGroupInputSources.test.d.ts → components/DataStates.test.d.ts} +0 -0
@@ -5,6 +5,7 @@ import {
5
5
  ref,
6
6
  shallowRef,
7
7
  toValue,
8
+ watch,
8
9
  type ComputedRef,
9
10
  type MaybeRefOrGetter,
10
11
  type Ref,
@@ -16,7 +17,12 @@ import type {
16
17
  JobListPayload,
17
18
  JobState,
18
19
  JobStateInput,
20
+ JobStreamData,
19
21
  } from '../types/jobs'
22
+ import type {
23
+ PluginEventStreamMessage,
24
+ UsePluginEventStreamReturn,
25
+ } from './usePluginClient'
20
26
 
21
27
  export type JobsStatusTrayTab = 'active' | 'history'
22
28
 
@@ -140,11 +146,32 @@ function duplicatePluginJobId(jobId: string): Error {
140
146
  return new Error(`Duplicate plugin job id across combined sources: ${jobId}`)
141
147
  }
142
148
 
149
+ /** @deprecated Prefer a {@link PluginJobCenterSource}. */
150
+ export interface JobsStatusTrayAdapter {
151
+ listJobs?: () => Promise<JobListPayload | readonly JobStateInput[]>
152
+ cancelJob?: (job: JobState) => Promise<JobStateInput | void>
153
+ deleteJob?: (job: JobState) => Promise<boolean | void>
154
+ clearFinishedJobs?: (jobs: readonly JobState[]) => Promise<number | void>
155
+ }
156
+
143
157
  export interface UsePluginJobCenterOptions {
144
158
  source?: MaybeRefOrGetter<PluginJobCenterSource | undefined>
159
+ /** @deprecated Pass a source with its canonical jobs ref. */
160
+ jobs?: MaybeRefOrGetter<readonly JobStateInput[] | undefined>
161
+ /** @deprecated Pass source actions instead. */
162
+ adapter?: MaybeRefOrGetter<JobsStatusTrayAdapter | undefined>
163
+ /** @deprecated Event handling belongs to the source runtime. */
164
+ eventStream?: MaybeRefOrGetter<UsePluginEventStreamReturn<JobStreamData> | undefined>
145
165
  loadOnMount?: boolean
146
166
  }
147
167
 
168
+ export interface UseJobsStatusTrayOptions extends UsePluginJobCenterOptions {}
169
+
170
+ export interface JobStreamMessage {
171
+ event: string
172
+ data: JobStreamData
173
+ }
174
+
148
175
  export interface UsePluginJobCenterReturn {
149
176
  jobs: ComputedRef<JobState[]>
150
177
  activeJobs: ComputedRef<JobState[]>
@@ -164,12 +191,30 @@ export interface UsePluginJobCenterReturn {
164
191
  close: () => void
165
192
  toggle: () => void
166
193
  refresh: () => Promise<boolean>
194
+ applyStreamMessage: (message: JobStreamMessage) => void
167
195
  cancelJob: (job: JobState) => Promise<boolean>
168
196
  deleteJob: (job: JobState) => Promise<boolean>
169
197
  clearFinished: () => Promise<boolean>
170
198
  isPending: (job: JobState) => boolean
171
199
  }
172
200
 
201
+ export type UseJobsStatusTrayReturn = UsePluginJobCenterReturn
202
+
203
+ interface LegacyJobsOverride {
204
+ readonly input: readonly JobStateInput[] | undefined
205
+ readonly jobs: JobState[]
206
+ }
207
+
208
+ function responseJobs(
209
+ response: JobListPayload | readonly JobStateInput[],
210
+ ): readonly JobStateInput[] {
211
+ return 'jobs' in response ? response.jobs : response
212
+ }
213
+
214
+ function isSnapshotPayload(data: JobStreamData): data is { jobs: JobStateInput[] } {
215
+ return 'jobs' in data && Array.isArray(data.jobs)
216
+ }
217
+
173
218
  function errorMessage(error: unknown, fallback: string): string {
174
219
  return error instanceof Error ? error.message : fallback
175
220
  }
@@ -183,30 +228,84 @@ function errorMessage(error: unknown, fallback: string): string {
183
228
  export function usePluginJobCenter(
184
229
  options: UsePluginJobCenterOptions = {},
185
230
  ): UsePluginJobCenterReturn {
231
+ const legacyOverride = shallowRef<LegacyJobsOverride | null>(null)
186
232
  const isOpen = ref(false)
187
233
  const activeTab = ref<JobsStatusTrayTab>('active')
188
234
  const isLoading = ref(false)
189
235
  const error = shallowRef<string | null>(null)
190
236
  const pendingJobIds = ref(new Set<string>())
237
+ const jobRevisions = new Map<string, number>()
238
+ let stateRevision = 0
191
239
  let requestGeneration = 0
192
240
  let active = true
193
241
  const source = computed(() => toValue(options.source))
242
+ const adapter = computed(() => toValue(options.adapter))
194
243
 
195
- const jobs = computed<JobState[]>(() => (
196
- source.value ? [...toValue(source.value.jobs)].map(normalizeJobState) : []
197
- ))
244
+ const jobs = computed<JobState[]>(() => {
245
+ const currentSource = source.value
246
+ if (currentSource) {
247
+ return [...toValue(currentSource.jobs)].map(normalizeJobState)
248
+ }
249
+ const input = toValue(options.jobs)
250
+ const override = legacyOverride.value
251
+ if (override && override.input === input) return override.jobs
252
+ return input ? [...input].map(normalizeJobState) : []
253
+ })
198
254
  const activeJobs = computed(() => jobs.value.filter(job => isActiveJobStatus(job.status)))
199
255
  const historyJobs = computed(() => jobs.value.filter(job => !isActiveJobStatus(job.status)))
200
256
  const deletableJobs = computed(() => historyJobs.value.filter(job => job.can_delete))
201
257
  const featuredJob = computed(() => activeJobs.value[0] ?? historyJobs.value[0] ?? null)
202
- const canRefresh = computed(() => Boolean(source.value?.refreshJobs))
203
- const canCancel = computed(() => Boolean(source.value?.cancelJob))
204
- const canDelete = computed(() => Boolean(source.value?.deleteJob))
258
+ const canRefresh = computed(() => Boolean(source.value?.refreshJobs || adapter.value?.listJobs))
259
+ const canCancel = computed(() => Boolean(source.value?.cancelJob || adapter.value?.cancelJob))
260
+ const canDelete = computed(() => Boolean(source.value?.deleteJob || adapter.value?.deleteJob))
205
261
  const canClearFinished = computed(() => Boolean(
206
262
  source.value?.clearFinishedJobs
207
263
  || source.value?.deleteJob
264
+ || adapter.value?.clearFinishedJobs
265
+ || adapter.value?.deleteJob,
208
266
  ))
209
267
 
268
+ function bumpJobRevision(jobId: string): void {
269
+ jobRevisions.set(jobId, (jobRevisions.get(jobId) ?? 0) + 1)
270
+ }
271
+
272
+ function replaceLegacyJobs(nextJobs: readonly JobStateInput[]): void {
273
+ const normalized = nextJobs.map(normalizeJobState)
274
+ const touchedJobIds = new Set([
275
+ ...jobs.value.map(job => job.job_id),
276
+ ...normalized.map(job => job.job_id),
277
+ ])
278
+ touchedJobIds.forEach(bumpJobRevision)
279
+ legacyOverride.value = {
280
+ input: toValue(options.jobs),
281
+ jobs: normalized,
282
+ }
283
+ stateRevision += 1
284
+ }
285
+
286
+ function upsertLegacyJob(nextJob: JobStateInput): void {
287
+ const normalized = normalizeJobState(nextJob)
288
+ const existingIndex = jobs.value.findIndex(job => job.job_id === normalized.job_id)
289
+ const nextJobs = [...jobs.value]
290
+ if (existingIndex === -1) nextJobs.unshift(normalized)
291
+ else nextJobs[existingIndex] = normalized
292
+ legacyOverride.value = {
293
+ input: toValue(options.jobs),
294
+ jobs: nextJobs,
295
+ }
296
+ bumpJobRevision(normalized.job_id)
297
+ stateRevision += 1
298
+ }
299
+
300
+ function removeLegacyJobs(jobIds: Set<string>): void {
301
+ legacyOverride.value = {
302
+ input: toValue(options.jobs),
303
+ jobs: jobs.value.filter(job => !jobIds.has(job.job_id)),
304
+ }
305
+ jobIds.forEach(bumpJobRevision)
306
+ stateRevision += 1
307
+ }
308
+
210
309
  function setPending(jobId: string, pending: boolean): void {
211
310
  const next = new Set(pendingJobIds.value)
212
311
  if (pending) next.add(jobId)
@@ -214,15 +313,35 @@ export function usePluginJobCenter(
214
313
  pendingJobIds.value = next
215
314
  }
216
315
 
316
+ function applyStreamMessage(message: JobStreamMessage): void {
317
+ if (!active || source.value) return
318
+ if (message.event === 'snapshot' && isSnapshotPayload(message.data)) {
319
+ replaceLegacyJobs(message.data.jobs)
320
+ return
321
+ }
322
+ if (
323
+ (message.event === 'job' || message.event === 'terminal')
324
+ && !isSnapshotPayload(message.data)
325
+ ) {
326
+ upsertLegacyJob(message.data)
327
+ }
328
+ }
329
+
217
330
  async function refresh(): Promise<boolean> {
218
- const refreshJobs = source.value?.refreshJobs
219
- if (!refreshJobs) return false
331
+ const currentSource = source.value
332
+ const listJobs = currentSource?.refreshJobs ?? adapter.value?.listJobs
333
+ if (!listJobs) return false
220
334
  const generation = ++requestGeneration
335
+ const revision = stateRevision
221
336
  isLoading.value = true
222
337
  error.value = null
223
338
  try {
224
- await refreshJobs()
225
- return active && generation === requestGeneration
339
+ const response = await listJobs()
340
+ if (!active || generation !== requestGeneration || revision !== stateRevision) {
341
+ return false
342
+ }
343
+ if (!currentSource && response) replaceLegacyJobs(responseJobs(response))
344
+ return true
226
345
  } catch (cause) {
227
346
  if (active && generation === requestGeneration) {
228
347
  error.value = errorMessage(cause, 'Failed to load jobs')
@@ -235,14 +354,23 @@ export function usePluginJobCenter(
235
354
 
236
355
  async function cancelJob(job: JobState): Promise<boolean> {
237
356
  const sourceCancel = source.value?.cancelJob
238
- if (!job.can_cancel || !sourceCancel || pendingJobIds.value.has(job.job_id)) {
357
+ const adapterCancel = adapter.value?.cancelJob
358
+ if (!job.can_cancel || (!sourceCancel && !adapterCancel) || pendingJobIds.value.has(job.job_id)) {
239
359
  return false
240
360
  }
361
+ const revision = jobRevisions.get(job.job_id) ?? 0
241
362
  setPending(job.job_id, true)
242
363
  error.value = null
243
364
  try {
244
- await sourceCancel(job.job_id)
245
- return active
365
+ const updated = sourceCancel
366
+ ? await sourceCancel(job.job_id)
367
+ : await adapterCancel!(job)
368
+ if (!active) return false
369
+ if (!sourceCancel && revision === (jobRevisions.get(job.job_id) ?? 0)) {
370
+ if (updated) upsertLegacyJob(updated)
371
+ else await refresh()
372
+ }
373
+ return true
246
374
  } catch (cause) {
247
375
  if (active) error.value = errorMessage(cause, 'Failed to cancel job')
248
376
  return false
@@ -253,14 +381,22 @@ export function usePluginJobCenter(
253
381
 
254
382
  async function deleteJob(job: JobState): Promise<boolean> {
255
383
  const sourceDelete = source.value?.deleteJob
256
- if (!job.can_delete || !sourceDelete || pendingJobIds.value.has(job.job_id)) {
384
+ const adapterDelete = adapter.value?.deleteJob
385
+ if (!job.can_delete || (!sourceDelete && !adapterDelete) || pendingJobIds.value.has(job.job_id)) {
257
386
  return false
258
387
  }
259
388
  setPending(job.job_id, true)
260
389
  error.value = null
261
390
  try {
262
- const deleted = await sourceDelete(job.job_id)
263
- return active && deleted !== false
391
+ const deleted = sourceDelete
392
+ ? await sourceDelete(job.job_id)
393
+ : await adapterDelete!(job)
394
+ if (!active) return false
395
+ if (!sourceDelete) {
396
+ if (deleted === false) await refresh()
397
+ else removeLegacyJobs(new Set([job.job_id]))
398
+ }
399
+ return deleted !== false
264
400
  } catch (cause) {
265
401
  if (active) error.value = errorMessage(cause, 'Failed to delete job')
266
402
  return false
@@ -284,13 +420,36 @@ export function usePluginJobCenter(
284
420
  const results = await Promise.all(targets.map(job => deleteJob(job)))
285
421
  return results.every(Boolean)
286
422
  }
287
- return false
423
+ const currentAdapter = adapter.value
424
+ if (currentAdapter?.clearFinishedJobs) {
425
+ const deleted = await currentAdapter.clearFinishedJobs(targets)
426
+ if (!active) return false
427
+ if (typeof deleted === 'number' && deleted !== targets.length) {
428
+ await refresh()
429
+ return false
430
+ }
431
+ removeLegacyJobs(new Set(targets.map(job => job.job_id)))
432
+ return true
433
+ }
434
+ if (!currentAdapter?.deleteJob) return false
435
+ const results = await Promise.all(targets.map(job => deleteJob(job)))
436
+ return results.every(Boolean)
288
437
  } catch (cause) {
289
438
  if (active) error.value = errorMessage(cause, 'Failed to clear jobs')
290
439
  return false
291
440
  }
292
441
  }
293
442
 
443
+ if (options.eventStream !== undefined) {
444
+ watch(
445
+ () => toValue(options.eventStream)?.lastMessage.value ?? null,
446
+ (message: PluginEventStreamMessage<JobStreamData> | null) => {
447
+ if (message) applyStreamMessage(message)
448
+ },
449
+ { immediate: true },
450
+ )
451
+ }
452
+
294
453
  onMounted(() => {
295
454
  if (options.loadOnMount !== false) void refresh()
296
455
  })
@@ -318,9 +477,17 @@ export function usePluginJobCenter(
318
477
  close: () => { isOpen.value = false },
319
478
  toggle: () => { isOpen.value = !isOpen.value },
320
479
  refresh,
480
+ applyStreamMessage,
321
481
  cancelJob,
322
482
  deleteJob,
323
483
  clearFinished,
324
484
  isPending: job => pendingJobIds.value.has(job.job_id),
325
485
  }
326
486
  }
487
+
488
+ /** @deprecated Use `usePluginJobCenter()` for the plugin job-center controller. */
489
+ export function useJobsStatusTray(
490
+ options: UseJobsStatusTrayOptions = {},
491
+ ): UseJobsStatusTrayReturn {
492
+ return usePluginJobCenter(options)
493
+ }
@@ -0,0 +1,143 @@
1
+ <script setup lang="ts">
2
+ /** Demonstrates `useListReorder`: drag a row, or focus a handle and press Alt with the arrow keys. */
3
+ import { ref } from 'vue'
4
+ import { useListReorder } from './useListReorder'
5
+
6
+ interface Step { id: string; name: string }
7
+
8
+ const steps = ref<Step[]>([
9
+ { id: 's1', name: 'Thaw samples' },
10
+ { id: 's2', name: 'Quench metabolism' },
11
+ { id: 's3', name: 'Extract metabolites' },
12
+ { id: 's4', name: 'Dry down' },
13
+ ])
14
+
15
+ const handles = new Map<string, HTMLElement>()
16
+
17
+ function setHandle(id: string, el: Element | null) {
18
+ if (el instanceof HTMLElement) handles.set(id, el)
19
+ else handles.delete(id)
20
+ }
21
+
22
+ const {
23
+ draggingId,
24
+ dragOverId,
25
+ announcement,
26
+ announcerStyle,
27
+ onDragStart,
28
+ onDragOver,
29
+ onDragLeave,
30
+ onDrop,
31
+ onDragEnd,
32
+ onKeydown,
33
+ } = useListReorder<Step>({
34
+ items: () => steps.value,
35
+ getId: (step) => step.id,
36
+ getLabel: (step) => step.name,
37
+ getElement: (id) => handles.get(id),
38
+ itemNoun: 'Step',
39
+ onReorder: ({ items }) => {
40
+ steps.value = items
41
+ },
42
+ })
43
+
44
+ function initState() {
45
+ return { showAnnouncement: true }
46
+ }
47
+ </script>
48
+
49
+ <template>
50
+ <Story title="Composables/useListReorder">
51
+ <Variant title="Playground" :init-state="initState">
52
+ <template #default="{ state }">
53
+ <div style="padding: 2rem; max-width: 600px;">
54
+ <p class="mint-story-hint">
55
+ Drag a row, or focus its handle and press Alt with the up/down arrow keys.
56
+ </p>
57
+ <ul class="mint-story-list">
58
+ <li
59
+ v-for="(step, index) in steps"
60
+ :key="step.id"
61
+ class="mint-story-row"
62
+ :class="{
63
+ 'mint-story-row--dragging': draggingId === step.id,
64
+ 'mint-story-row--over': dragOverId === step.id,
65
+ }"
66
+ draggable="true"
67
+ @dragstart="onDragStart($event, step, index)"
68
+ @dragover="onDragOver($event, step, index)"
69
+ @dragleave="onDragLeave"
70
+ @drop="onDrop($event, step, index)"
71
+ @dragend="onDragEnd"
72
+ >
73
+ <button
74
+ :ref="(el) => setHandle(step.id, el as Element | null)"
75
+ type="button"
76
+ class="mint-story-handle"
77
+ :aria-label="`Reorder ${step.name}. Press Alt with the arrow keys to move it.`"
78
+ @keydown="onKeydown($event, step, index)"
79
+ >
80
+ ⠿
81
+ </button>
82
+ <span>{{ index + 1 }}. {{ step.name }}</span>
83
+ </li>
84
+ </ul>
85
+
86
+ <p v-if="state.showAnnouncement" class="mint-story-hint">
87
+ Live region: <em>{{ announcement || '—' }}</em>
88
+ </p>
89
+ <div role="status" aria-live="polite" :style="announcerStyle">{{ announcement }}</div>
90
+ </div>
91
+ </template>
92
+
93
+ <template #controls="{ state }">
94
+ <HstCheckbox v-model="state.showAnnouncement" title="Show live-region text" />
95
+ </template>
96
+ </Variant>
97
+ </Story>
98
+ </template>
99
+
100
+ <style scoped>
101
+ .mint-story-list {
102
+ list-style: none;
103
+ margin: 0;
104
+ padding: 0;
105
+ display: flex;
106
+ flex-direction: column;
107
+ gap: 0.25rem;
108
+ }
109
+
110
+ .mint-story-row {
111
+ display: flex;
112
+ align-items: center;
113
+ gap: 0.5rem;
114
+ padding: 0.5rem 0.75rem;
115
+ border: 1px solid var(--border-color);
116
+ border-radius: 0.5rem;
117
+ background: var(--bg-primary);
118
+ color: var(--text-primary);
119
+ }
120
+
121
+ .mint-story-row--dragging {
122
+ opacity: 0.5;
123
+ }
124
+
125
+ .mint-story-row--over {
126
+ border-color: var(--color-primary);
127
+ }
128
+
129
+ .mint-story-handle {
130
+ padding: 0;
131
+ border: 0;
132
+ background: none;
133
+ color: var(--text-muted);
134
+ cursor: grab;
135
+ font-size: 1rem;
136
+ }
137
+
138
+ .mint-story-hint {
139
+ margin: 0 0 0.75rem;
140
+ color: var(--text-secondary);
141
+ font-size: 0.8125rem;
142
+ }
143
+ </style>