@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
@@ -96,6 +96,7 @@ const views = ['summary', 'tree', 'table'] as const
96
96
  <template #default="{ state }">
97
97
  <div style="padding: 1rem; max-width: 800px; margin: 0 auto;">
98
98
  <ExperimentDataViewer
99
+ :error="state.error || null"
99
100
  :tree-data="treeData"
100
101
  :table-data="tableData"
101
102
  :summary-data="state.showSummary ? summaryData : null"
@@ -107,6 +108,8 @@ const views = ['summary', 'tree', 'table'] as const
107
108
  </template>
108
109
 
109
110
  <template #controls="{ state }">
111
+
112
+ <HstText v-model="state.error" title="Error Message" />
110
113
  <HstSelect
111
114
  v-model="state.defaultView"
112
115
  title="Default View"
@@ -8,6 +8,7 @@ import DataFrame from './DataFrame.vue'
8
8
  import SegmentedControl from './SegmentedControl.vue'
9
9
  import BaseButton from './BaseButton.vue'
10
10
  import Skeleton from './Skeleton.vue'
11
+ import DataStateInternal from './internal/DataStateInternal.vue'
11
12
 
12
13
  interface Props {
13
14
  treeData?: TreeNode[]
@@ -20,6 +21,11 @@ interface Props {
20
21
  pluginRoutePrefix?: string
21
22
  experimentId?: number
22
23
  loading?: boolean
24
+ /**
25
+ * Error message. When set (or when the auto-fetch fails), the content area
26
+ * renders an error state instead of the data views.
27
+ */
28
+ error?: string | null
23
29
  downloadJsonUrl?: string
24
30
  downloadCsvUrl?: string
25
31
  autoFetch?: boolean
@@ -29,6 +35,7 @@ const props = withDefaults(defineProps<Props>(), {
29
35
  title: 'Data',
30
36
  defaultView: 'summary',
31
37
  loading: false,
38
+ error: null,
32
39
  autoFetch: true,
33
40
  })
34
41
 
@@ -61,6 +68,9 @@ const mergedSummaryData = computed(() =>
61
68
  const isLoading = computed(() =>
62
69
  props.loading || expData.isLoading.value,
63
70
  )
71
+ const activeError = computed<string | null>(() =>
72
+ props.error ?? expData.error.value,
73
+ )
64
74
 
65
75
  const emit = defineEmits<{
66
76
  'open-plugin': []
@@ -179,13 +189,20 @@ function handleDownloadCsv() {
179
189
  </div>
180
190
 
181
191
  <div class="mint-data-viewer__content">
182
- <div v-if="isLoading" class="mint-data-viewer__loading">
183
- <div class="mint-data-viewer__skeleton">
184
- <Skeleton width="40%" height="16px" />
185
- <Skeleton width="100%" height="12px" />
186
- <Skeleton width="100%" height="12px" />
187
- <Skeleton width="75%" height="12px" />
188
- </div>
192
+ <div v-if="activeError" class="mint-data-viewer__state">
193
+ <slot name="error" :error="activeError">
194
+ <DataStateInternal state="error" :title="activeError" />
195
+ </slot>
196
+ </div>
197
+ <div v-else-if="isLoading" class="mint-data-viewer__loading">
198
+ <slot name="loading">
199
+ <div class="mint-data-viewer__skeleton">
200
+ <Skeleton width="40%" height="16px" />
201
+ <Skeleton width="100%" height="12px" />
202
+ <Skeleton width="100%" height="12px" />
203
+ <Skeleton width="75%" height="12px" />
204
+ </div>
205
+ </slot>
189
206
  </div>
190
207
  <template v-else>
191
208
  <!-- Summary View -->
@@ -280,14 +297,17 @@ function handleDownloadCsv() {
280
297
  :searchable="true"
281
298
  :sortable="true"
282
299
  />
283
- <div v-else-if="viewMode === 'table'" class="mint-data-viewer__empty">
284
- No tabular data available. Use tree view.
300
+ <div v-else-if="viewMode === 'table'" class="mint-data-viewer__state">
301
+ <slot name="empty">
302
+ <DataStateInternal
303
+ state="empty"
304
+ title="No tabular data available"
305
+ description="Switch to the tree view to inspect this experiment."
306
+ size="sm"
307
+ />
308
+ </slot>
285
309
  </div>
286
310
  </template>
287
311
  </div>
288
312
  </div>
289
313
  </template>
290
-
291
- <style>
292
- @import '../styles/components/experiment-data-viewer.css';
293
- </style>
@@ -57,7 +57,7 @@ const emit = defineEmits<{
57
57
  detach: []
58
58
  }>()
59
59
 
60
- const { isOpen, rootRef: popoverRef, close, toggle } = useDropdownState({
60
+ const { isOpen, rootRef: popoverRef, triggerRef, close, toggle } = useDropdownState({
61
61
  closeOnEscape: false,
62
62
  })
63
63
  const showSuccess = ref(false)
@@ -118,6 +118,7 @@ onUnmounted(() => {
118
118
  <!-- Left: experiment trigger (opens popover). Prefer the human-readable
119
119
  name; the formal code, when present, stays in the detail panel. -->
120
120
  <button
121
+ ref="triggerRef"
121
122
  type="button"
122
123
  :class="[
123
124
  'mint-experiment-popover__trigger',
@@ -306,7 +307,3 @@ onUnmounted(() => {
306
307
  />
307
308
  </div>
308
309
  </template>
309
-
310
- <style>
311
- @import '../styles/components/experiment-popover.css';
312
- </style>
@@ -426,7 +426,3 @@ watch(
426
426
  </div>
427
427
  </BaseModal>
428
428
  </template>
429
-
430
- <style>
431
- @import '../styles/components/experiment-selector-modal.css';
432
- </style>
@@ -57,6 +57,8 @@ const mockSteps: ProtocolStep[] = [
57
57
 
58
58
  function initState() {
59
59
  return {
60
+ loading: false,
61
+ error: '',
60
62
  modelValue: mockSteps,
61
63
  orientation: 'vertical' as const,
62
64
  showDuration: true,
@@ -76,6 +78,8 @@ function initState() {
76
78
  <template #default="{ state }">
77
79
  <div style="padding: 2rem; max-width: 600px;">
78
80
  <ExperimentTimeline
81
+ :loading="state.loading"
82
+ :error="state.error || null"
79
83
  v-model="state.modelValue"
80
84
  :orientation="state.orientation"
81
85
  :show-duration="state.showDuration"
@@ -89,6 +93,8 @@ function initState() {
89
93
  </div>
90
94
  </template>
91
95
  <template #controls="{ state }">
96
+ <HstCheckbox v-model="state.loading" title="Loading" />
97
+ <HstText v-model="state.error" title="Error Message" />
92
98
  <HstSelect
93
99
  v-model="state.orientation"
94
100
  title="Orientation"
@@ -157,5 +163,17 @@ function initState() {
157
163
  <ExperimentTimeline :model-value="[]" editable />
158
164
  </div>
159
165
  </Variant>
166
+
167
+ <Variant title="Loading">
168
+ <div style="padding: 2rem; max-width: 600px;">
169
+ <ExperimentTimeline :model-value="[]" loading />
170
+ </div>
171
+ </Variant>
172
+
173
+ <Variant title="Error">
174
+ <div style="padding: 2rem; max-width: 600px;">
175
+ <ExperimentTimeline :model-value="[]" error="Could not load the protocol." />
176
+ </div>
177
+ </Variant>
160
178
  </Story>
161
179
  </template>
@@ -1,12 +1,14 @@
1
1
  <script setup lang="ts">
2
2
  /** Horizontal or vertical timeline of ordered protocol steps with status indicators, drag-to-reorder, and step-type iconography. */
3
- import { ref, computed } from 'vue'
3
+ import { ref, computed, type ComponentPublicInstance } from 'vue'
4
4
  import type { ProtocolStep, ProtocolStepStatus } from '../types'
5
+ import { useListReorder } from '../composables/useListReorder'
5
6
  import {
6
7
  PROTOCOL_STEP_TYPE_COLORS as stepTypeColors,
7
8
  PROTOCOL_STEP_TYPE_ICONS as stepTypeIcons,
8
9
  formatProtocolDuration as formatDuration,
9
10
  } from './ProtocolStep.presentation'
11
+ import DataStateInternal from './internal/DataStateInternal.vue'
10
12
 
11
13
  interface Props {
12
14
  modelValue?: ProtocolStep[]
@@ -19,6 +21,13 @@ interface Props {
19
21
  size?: 'sm' | 'md' | 'lg'
20
22
  colorByStatus?: boolean
21
23
  colorByType?: boolean
24
+ /** Replace the timeline with a loading placeholder. */
25
+ loading?: boolean
26
+ /**
27
+ * Error message. When set, the timeline is replaced by an error state.
28
+ * `null`/`undefined` renders normally.
29
+ */
30
+ error?: string | null
22
31
  }
23
32
 
24
33
  const props = withDefaults(defineProps<Props>(), {
@@ -32,6 +41,8 @@ const props = withDefaults(defineProps<Props>(), {
32
41
  size: 'md',
33
42
  colorByStatus: true,
34
43
  colorByType: false,
44
+ loading: false,
45
+ error: null,
35
46
  })
36
47
 
37
48
  const emit = defineEmits<{
@@ -46,8 +57,7 @@ const emit = defineEmits<{
46
57
  }>()
47
58
 
48
59
  const localExpandedId = ref<string | undefined>(props.expandedStepId)
49
- const draggedStepId = ref<string | null>(null)
50
- const dragOverStepId = ref<string | null>(null)
60
+ const stepRefs = new Map<string, HTMLElement>()
51
61
 
52
62
  const expandedId = computed({
53
63
  get: () => props.expandedStepId ?? localExpandedId.value,
@@ -123,54 +133,38 @@ function handleAddStep(afterStepId?: string) {
123
133
  emit('step-add', afterStepId)
124
134
  }
125
135
 
126
- function handleDragStart(event: DragEvent, step: ProtocolStep) {
127
- if (!props.editable) return
128
- draggedStepId.value = step.id
129
- if (event.dataTransfer) {
130
- event.dataTransfer.effectAllowed = 'move'
131
- event.dataTransfer.setData('text/plain', step.id)
132
- }
133
- }
134
-
135
- function handleDragOver(event: DragEvent, step: ProtocolStep) {
136
- if (!props.editable || !draggedStepId.value) return
137
- event.preventDefault()
138
- dragOverStepId.value = step.id
139
- }
140
-
141
- function handleDragLeave() {
142
- dragOverStepId.value = null
143
- }
144
-
145
- function handleDrop(event: DragEvent, targetStep: ProtocolStep) {
146
- if (!props.editable || !draggedStepId.value) return
147
- event.preventDefault()
136
+ // Steps are a plain ordered list, so pointer drag and the Alt+Arrow keyboard
137
+ // alternative both come from the shared reorder composable.
138
+ const {
139
+ draggingId: draggedStepId,
140
+ dragOverId: dragOverStepId,
141
+ announcement: reorderAnnouncement,
142
+ announcerStyle,
143
+ onDragStart: onStepDragStart,
144
+ onDragOver: onStepDragOver,
145
+ onDragLeave: onStepDragLeave,
146
+ onDrop: onStepDrop,
147
+ onDragEnd: onStepDragEnd,
148
+ onKeydown: onStepReorderKeydown,
149
+ } = useListReorder<ProtocolStep>({
150
+ items: () => sortedSteps.value,
151
+ getId: (step) => step.id,
152
+ getLabel: (step) => step.name,
153
+ disabled: () => !props.editable,
154
+ getElement: (id) => stepRefs.get(id),
155
+ itemNoun: 'Step',
156
+ onReorder: ({ toIndex, items }) => {
157
+ emit('step-reorder', items[toIndex].id, toIndex)
158
+ emit('update:modelValue', items.map((step, index) => ({ ...step, order: index })))
159
+ },
160
+ })
148
161
 
149
- const draggedStep = props.modelValue.find(s => s.id === draggedStepId.value)
150
- if (!draggedStep || draggedStep.id === targetStep.id) {
151
- draggedStepId.value = null
152
- dragOverStepId.value = null
153
- return
162
+ function setStepRef(id: string, el: Element | ComponentPublicInstance | null) {
163
+ if (el instanceof HTMLElement) {
164
+ stepRefs.set(id, el)
165
+ } else {
166
+ stepRefs.delete(id)
154
167
  }
155
-
156
- const steps = [...props.modelValue]
157
- const draggedIndex = steps.findIndex(s => s.id === draggedStepId.value)
158
- const targetIndex = steps.findIndex(s => s.id === targetStep.id)
159
-
160
- steps.splice(draggedIndex, 1)
161
- steps.splice(targetIndex, 0, draggedStep)
162
-
163
- const reordered = steps.map((s, i) => ({ ...s, order: i }))
164
- emit('step-reorder', draggedStepId.value, targetIndex)
165
- emit('update:modelValue', reordered)
166
-
167
- draggedStepId.value = null
168
- dragOverStepId.value = null
169
- }
170
-
171
- function handleDragEnd() {
172
- draggedStepId.value = null
173
- dragOverStepId.value = null
174
168
  }
175
169
 
176
170
  </script>
@@ -182,16 +176,22 @@ function handleDragEnd() {
182
176
  :aria-label="`Protocol timeline with ${sortedSteps.length} steps`"
183
177
  >
184
178
  <div
185
- v-for="(step, index) in sortedSteps"
179
+ v-for="(step, index) in (loading || error ? [] : sortedSteps)"
186
180
  :key="step.id"
181
+ :ref="(el) => setStepRef(step.id, el)"
187
182
  class="mint-timeline__step"
188
183
  role="listitem"
189
184
  :draggable="editable"
190
- @dragstart="handleDragStart($event, step)"
191
- @dragover="handleDragOver($event, step)"
192
- @dragleave="handleDragLeave"
193
- @drop="handleDrop($event, step)"
194
- @dragend="handleDragEnd"
185
+ :tabindex="editable ? 0 : undefined"
186
+ :aria-label="editable
187
+ ? `${step.name}, step ${index + 1} of ${sortedSteps.length}. Press Alt with the arrow keys to reorder.`
188
+ : undefined"
189
+ @dragstart="onStepDragStart($event, step, index)"
190
+ @dragover="onStepDragOver($event, step, index)"
191
+ @dragleave="onStepDragLeave"
192
+ @drop="onStepDrop($event, step, index)"
193
+ @dragend="onStepDragEnd"
194
+ @keydown="onStepReorderKeydown($event, step, index)"
195
195
  >
196
196
  <div
197
197
  v-if="index < sortedSteps.length - 1"
@@ -321,25 +321,32 @@ function handleDragEnd() {
321
321
  <div v-if="orientation === 'horizontal' && index < sortedSteps.length - 1" class="mint-timeline__spacer--horizontal" />
322
322
  </div>
323
323
 
324
- <div
325
- v-if="sortedSteps.length === 0"
326
- class="mint-timeline__empty"
327
- >
328
- <div class="mint-timeline__empty-content">
329
- <p class="mint-timeline__empty-text">No protocol steps defined</p>
330
- <button
331
- v-if="editable"
332
- type="button"
333
- class="mint-timeline__empty-btn"
334
- @click="handleAddStep()"
335
- >
336
- Add First Step
337
- </button>
338
- </div>
324
+ <div v-if="error" class="mint-timeline__state">
325
+ <slot name="error" :error="error">
326
+ <DataStateInternal state="error" size="sm" :title="error" />
327
+ </slot>
328
+ </div>
329
+
330
+ <div v-else-if="loading" class="mint-timeline__state">
331
+ <slot name="loading">
332
+ <DataStateInternal state="loading" size="sm" loading-label="Loading protocol" />
333
+ </slot>
334
+ </div>
335
+
336
+ <div v-else-if="sortedSteps.length === 0" class="mint-timeline__state">
337
+ <slot name="empty">
338
+ <DataStateInternal
339
+ state="empty"
340
+ size="sm"
341
+ title="No protocol steps defined"
342
+ :action-label="editable ? 'Add First Step' : undefined"
343
+ @action="handleAddStep()"
344
+ />
345
+ </slot>
339
346
  </div>
340
347
 
341
348
  <button
342
- v-if="editable && sortedSteps.length > 0"
349
+ v-if="editable && !loading && !error && sortedSteps.length > 0"
343
350
  type="button"
344
351
  :class="['mint-timeline__add-end', `mint-timeline__add-end--${size}`]"
345
352
  @click="handleAddStep()"
@@ -349,9 +356,8 @@ function handleDragEnd() {
349
356
  </svg>
350
357
  <span :class="`mint-timeline__add-end-text--${size}`">Add Step</span>
351
358
  </button>
359
+
360
+ <!-- Reorder announcements for screen readers -->
361
+ <div role="status" aria-live="polite" :style="announcerStyle">{{ reorderAnnouncement }}</div>
352
362
  </div>
353
363
  </template>
354
-
355
- <style>
356
- @import '../styles/components/experiment-timeline.css';
357
- </style>
@@ -418,7 +418,3 @@ function formatFileSize(bytes: number): string {
418
418
  </TransitionGroup>
419
419
  </div>
420
420
  </template>
421
-
422
- <style>
423
- @import '../styles/components/file-uploader.css';
424
- </style>
@@ -114,7 +114,3 @@ function variantClass(variant?: string): string {
114
114
  <slot name="footer" />
115
115
  </div>
116
116
  </template>
117
-
118
- <style>
119
- @import '../styles/components/fit-panel.css';
120
- </style>
@@ -0,0 +1,96 @@
1
+ <script setup lang="ts">
2
+ import FormActions from './FormActions.vue'
3
+
4
+ function log(event: string) {
5
+ return () => console.log(event)
6
+ }
7
+
8
+ function initState() {
9
+ return {
10
+ isWizard: false,
11
+ isFirst: true,
12
+ isLast: true,
13
+ canProceed: true,
14
+ loading: false,
15
+ disabled: false,
16
+ showCancel: true,
17
+ submitLabel: 'Submit',
18
+ cancelLabel: 'Cancel',
19
+ }
20
+ }
21
+ </script>
22
+
23
+ <template>
24
+ <Story title="Forms/FormActions">
25
+ <Variant title="Playground" :init-state="initState">
26
+ <template #default="{ state }">
27
+ <div style="padding: 2rem; max-width: 600px;">
28
+ <FormActions
29
+ :is-wizard="state.isWizard"
30
+ :is-first="state.isFirst"
31
+ :is-last="state.isLast"
32
+ :can-proceed="state.canProceed"
33
+ :loading="state.loading"
34
+ :disabled="state.disabled"
35
+ :show-cancel="state.showCancel"
36
+ :submit-label="state.submitLabel"
37
+ :cancel-label="state.cancelLabel"
38
+ @submit="log('submit')()"
39
+ @cancel="log('cancel')()"
40
+ @back="log('back')()"
41
+ @next="log('next')()"
42
+ />
43
+ </div>
44
+ </template>
45
+
46
+ <template #controls="{ state }">
47
+ <HstCheckbox v-model="state.isWizard" title="Wizard mode" />
48
+ <HstCheckbox v-model="state.isFirst" title="First step" />
49
+ <HstCheckbox v-model="state.isLast" title="Last step" />
50
+ <HstCheckbox v-model="state.canProceed" title="Can proceed" />
51
+ <HstCheckbox v-model="state.loading" title="Loading" />
52
+ <HstCheckbox v-model="state.disabled" title="Disabled" />
53
+ <HstCheckbox v-model="state.showCancel" title="Show cancel" />
54
+ <HstText v-model="state.submitLabel" title="Submit label" />
55
+ <HstText v-model="state.cancelLabel" title="Cancel label" />
56
+ </template>
57
+ </Variant>
58
+
59
+ <Variant title="Flat form">
60
+ <div style="padding: 2rem; max-width: 600px;">
61
+ <FormActions show-cancel submit-label="Save design" />
62
+ </div>
63
+ </Variant>
64
+
65
+ <Variant title="Wizard — first step">
66
+ <!-- Back is hidden on the first step; Next gates on `canProceed`. -->
67
+ <div style="padding: 2rem; max-width: 600px;">
68
+ <FormActions is-wizard :is-first="true" :is-last="false" />
69
+ </div>
70
+ </Variant>
71
+
72
+ <Variant title="Wizard — middle step">
73
+ <div style="padding: 2rem; max-width: 600px;">
74
+ <FormActions is-wizard :is-first="false" :is-last="false" />
75
+ </div>
76
+ </Variant>
77
+
78
+ <Variant title="Wizard — last step">
79
+ <div style="padding: 2rem; max-width: 600px;">
80
+ <FormActions is-wizard :is-first="false" :is-last="true" submit-label="Create experiment" />
81
+ </div>
82
+ </Variant>
83
+
84
+ <Variant title="Blocked by validation">
85
+ <div style="padding: 2rem; max-width: 600px;">
86
+ <FormActions is-wizard :is-first="false" :is-last="false" :can-proceed="false" />
87
+ </div>
88
+ </Variant>
89
+
90
+ <Variant title="Loading">
91
+ <div style="padding: 2rem; max-width: 600px;">
92
+ <FormActions show-cancel loading submit-label="Saving…" />
93
+ </div>
94
+ </Variant>
95
+ </Story>
96
+ </template>
@@ -86,7 +86,3 @@ const emit = defineEmits<{
86
86
  </BaseButton>
87
87
  </div>
88
88
  </template>
89
-
90
- <style>
91
- @import '../styles/components/form-builder.css';
92
- </style>
@@ -305,7 +305,3 @@ defineExpose({
305
305
  </template>
306
306
  </div>
307
307
  </template>
308
-
309
- <style>
310
- @import '../styles/components/form-builder.css';
311
- </style>
@@ -53,7 +53,3 @@ const describedBy = computed(() => errorId.value ?? hintId.value)
53
53
  </p>
54
54
  </div>
55
55
  </template>
56
-
57
- <style>
58
- @import '../styles/components/form-field.css';
59
- </style>
@@ -119,7 +119,3 @@ function handleInput(event: Event) {
119
119
  </div>
120
120
  </div>
121
121
  </template>
122
-
123
- <style>
124
- @import '../styles/components/formula-input.css';
125
- </style>
@@ -0,0 +1,68 @@
1
+ <script setup lang="ts">
2
+ import { ref } from 'vue'
3
+ import GeneratedPathInput from './GeneratedPathInput.vue'
4
+ import type { PluginJobPathInput } from '../types/generated-ui'
5
+
6
+ const single = ref<PluginJobPathInput | PluginJobPathInput[] | null>(null)
7
+ const multiple = ref<PluginJobPathInput | PluginJobPathInput[] | null>([])
8
+
9
+ function describe(value: PluginJobPathInput | PluginJobPathInput[] | null): string {
10
+ if (!value) return 'nothing selected'
11
+ const selections = Array.isArray(value) ? value : [value]
12
+ if (!selections.length) return 'nothing selected'
13
+ return selections
14
+ .map(selection => selection.rootName ?? selection.relativePaths.join(', '))
15
+ .join(' · ')
16
+ }
17
+
18
+ function initState() {
19
+ return {
20
+ multiple: false,
21
+ disabled: false,
22
+ }
23
+ }
24
+ </script>
25
+
26
+ <template>
27
+ <Story title="Forms/GeneratedPathInput">
28
+ <Variant title="Playground" :init-state="initState">
29
+ <template #default="{ state }">
30
+ <!-- Outside an integrated plugin the "Existing artifact" button is
31
+ hidden, so the story shows the file/folder modes only. -->
32
+ <div style="padding: 2rem; max-width: 600px;">
33
+ <GeneratedPathInput
34
+ v-model="single"
35
+ :multiple="state.multiple"
36
+ :disabled="state.disabled"
37
+ />
38
+ <p style="margin-top: 1rem; font-size: 0.8125rem; color: var(--text-secondary);">
39
+ Selection: <code>{{ describe(single) }}</code>
40
+ </p>
41
+ </div>
42
+ </template>
43
+
44
+ <template #controls="{ state }">
45
+ <HstCheckbox v-model="state.multiple" title="Allow multiple" />
46
+ <HstCheckbox v-model="state.disabled" title="Disabled" />
47
+ </template>
48
+ </Variant>
49
+
50
+ <Variant title="Single path">
51
+ <div style="padding: 2rem; max-width: 600px;">
52
+ <GeneratedPathInput v-model="single" />
53
+ </div>
54
+ </Variant>
55
+
56
+ <Variant title="Multiple paths">
57
+ <div style="padding: 2rem; max-width: 600px;">
58
+ <GeneratedPathInput v-model="multiple" multiple />
59
+ </div>
60
+ </Variant>
61
+
62
+ <Variant title="Disabled">
63
+ <div style="padding: 2rem; max-width: 600px;">
64
+ <GeneratedPathInput v-model="single" disabled />
65
+ </div>
66
+ </Variant>
67
+ </Story>
68
+ </template>