@morscherlab/mint-sdk 1.4.0-beta.2 → 1.4.0-beta.21

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 (353) hide show
  1. package/README.md +14 -3
  2. package/dist/{ActionMenu-CScINahU.js → AlertBox-DwgNTEqf.js} +40 -209
  3. package/dist/AlertBox-DwgNTEqf.js.map +1 -0
  4. package/dist/{AppSidebar-BmiiPfz9.js → AppSidebar-CZZaxni0.js} +1249 -239
  5. package/dist/AppSidebar-CZZaxni0.js.map +1 -0
  6. package/dist/{ConfirmDialog-CJ7hqYUP.js → ConfirmDialog-CjWoxAD1.js} +2 -2
  7. package/dist/{ConfirmDialog-CJ7hqYUP.js.map → ConfirmDialog-CjWoxAD1.js.map} +1 -1
  8. package/dist/ExperimentPopover-DujiuQIO.js +337 -0
  9. package/dist/ExperimentPopover-DujiuQIO.js.map +1 -0
  10. package/dist/{ExperimentSelectorModal-D-9z7cNx.js → ExperimentSelectorModal-B4j4eUOJ.js} +244 -211
  11. package/dist/ExperimentSelectorModal-B4j4eUOJ.js.map +1 -0
  12. package/dist/{SegmentedControl-DERBN-Xd.js → SegmentedControl-DyUPH3I5.js} +2 -2
  13. package/dist/{SegmentedControl-DERBN-Xd.js.map → SegmentedControl-DyUPH3I5.js.map} +1 -1
  14. package/dist/{SettingsModal-CSLE31yg.js → SettingsModal-D2MOOtuO.js} +28 -27
  15. package/dist/SettingsModal-D2MOOtuO.js.map +1 -0
  16. package/dist/__stories__/experiment-helpers.d.ts +10 -0
  17. package/dist/__tests__/components/AppTopBarOnboarding.test.d.ts +1 -0
  18. package/dist/__tests__/components/FloatingPanelsInModal.test.d.ts +1 -0
  19. package/dist/__tests__/composables/useFloatingPanel.test.d.ts +1 -0
  20. package/dist/__tests__/composables/useOnboarding.test.d.ts +1 -0
  21. package/dist/__tests__/styles/paletteTokens.test.d.ts +1 -0
  22. package/dist/__tests__/styles/v2AuditRules.test.d.ts +1 -0
  23. package/dist/components/AppSidebar.vue.d.ts +1 -1
  24. package/dist/components/AppTopBar.vue.d.ts +20 -5
  25. package/dist/components/ArtifactSaveDialog.vue.d.ts +9 -1
  26. package/dist/components/AuditTrail.vue.d.ts +1 -1
  27. package/dist/components/BaseButton.vue.d.ts +4 -2
  28. package/dist/components/BaseSelect.vue.d.ts +2 -2
  29. package/dist/components/ChartContainer.vue.d.ts +2 -0
  30. package/dist/components/DatePicker.vue.d.ts +1 -1
  31. package/dist/components/ExperimentPopover.vue.d.ts +18 -0
  32. package/dist/components/ExperimentSelectorModal.vue.d.ts +15 -5
  33. package/dist/components/FilePicker.vue.d.ts +1 -1
  34. package/dist/components/FileUploader.vue.d.ts +2 -2
  35. package/dist/components/JobsStatusTray.vue.d.ts +15 -4
  36. package/dist/components/PluginIcon.vue.d.ts +2 -2
  37. package/dist/components/PluginWorkspaceView.props.d.ts +3 -0
  38. package/dist/components/PluginWorkspaceView.vue.d.ts +3 -0
  39. package/dist/components/SampleSelector.vue.d.ts +6 -6
  40. package/dist/components/SequenceProgressBar.vue.d.ts +3 -0
  41. package/dist/components/SmartGroupFieldRecipe.vue.d.ts +3 -3
  42. package/dist/components/StepWizard.vue.d.ts +3 -0
  43. package/dist/components/internal/AppTopBarOnboardingInternal.vue.d.ts +7 -0
  44. package/dist/components/internal/AppTopBarPageSelectorInternal.vue.d.ts +2 -1
  45. package/dist/components/internal/AutoGroupModalInternal.vue.d.ts +3 -3
  46. package/dist/components/internal/DatePickerTimeInternal.vue.d.ts +1 -1
  47. package/dist/components/internal/OnboardingLayerInternal.vue.d.ts +7 -0
  48. package/dist/components/internal/ResourcePickerListInternal.vue.d.ts +2 -7
  49. package/dist/components/internal/SelectMultipleInternal.vue.d.ts +4 -0
  50. package/dist/components/internal/WorkspaceShellInternal.vue.d.ts +8 -0
  51. package/dist/composables/createClient.d.ts +2 -0
  52. package/dist/composables/index.d.ts +1 -0
  53. package/dist/composables/pluginIdentity.d.ts +24 -0
  54. package/dist/composables/pluginWorkspaceModel.d.ts +2 -2
  55. package/dist/composables/useAppExperiment.d.ts +8 -0
  56. package/dist/composables/useCalendarGrid.d.ts +1 -1
  57. package/dist/composables/useExperimentSelector.d.ts +6 -2
  58. package/dist/composables/useFileImport.d.ts +7 -0
  59. package/dist/composables/useFloatingPanel.d.ts +29 -0
  60. package/dist/composables/useJobCenter.d.ts +41 -3
  61. package/dist/composables/useOnboarding.d.ts +119 -0
  62. package/dist/composables/usePlatform.d.ts +1 -0
  63. package/dist/{controlSchemaModel-CP5-_nAj.js → controlSchemaModel-Bsg0t5Ab.js} +2 -2
  64. package/dist/{controlSchemaModel-CP5-_nAj.js.map → controlSchemaModel-Bsg0t5Ab.js.map} +1 -1
  65. package/dist/{data-C2PwI_dn.js → data-Boeh4uPI.js} +180 -125
  66. package/dist/data-Boeh4uPI.js.map +1 -0
  67. package/dist/data.d.ts +1 -1
  68. package/dist/data.js +9 -9
  69. package/dist/{experiment-43OJtH7R.js → experiment-DyO54FQB.js} +25 -61
  70. package/dist/experiment-DyO54FQB.js.map +1 -0
  71. package/dist/{experimentStatus-BZmU4czV.js → experimentStatus-DCn2QKG7.js} +3 -3
  72. package/dist/{experimentStatus-BZmU4czV.js.map → experimentStatus-DCn2QKG7.js.map} +1 -1
  73. package/dist/index.js +20 -20
  74. package/dist/{install-DAID6c2-.js → install-BEHp7Mo-.js} +15 -14
  75. package/dist/{install-DAID6c2-.js.map → install-BEHp7Mo-.js.map} +1 -1
  76. package/dist/install.js +1 -1
  77. package/dist/{lab-DLwRl_Ql.js → lab-D61eaX6f.js} +136 -148
  78. package/dist/lab-D61eaX6f.js.map +1 -0
  79. package/dist/lab.js +4 -3
  80. package/dist/{records-BzTcxekG.js → records-D4aQXyZu.js} +647 -389
  81. package/dist/records-D4aQXyZu.js.map +1 -0
  82. package/dist/{runtime-D6gVat6r.js → runtime-q-R0CNLh.js} +417 -54
  83. package/dist/runtime-q-R0CNLh.js.map +1 -0
  84. package/dist/runtime.d.ts +1 -1
  85. package/dist/runtime.js +7 -7
  86. package/dist/{shell-5ju97nOS.js → shell-6CGFvUUw.js} +10 -5
  87. package/dist/{shell-5ju97nOS.js.map → shell-6CGFvUUw.js.map} +1 -1
  88. package/dist/shell.d.ts +1 -0
  89. package/dist/shell.js +6 -6
  90. package/dist/stores/index.d.ts +1 -1
  91. package/dist/stores/index.js +2 -2
  92. package/dist/stores/settings.d.ts +4 -12
  93. package/dist/styles.css +2753 -2101
  94. package/dist/types/componentWorkflowTypes.d.ts +2 -0
  95. package/dist/types/components.d.ts +2 -0
  96. package/dist/types/generated/platformContext.d.ts +1 -0
  97. package/dist/types/generated-ui.d.ts +4 -0
  98. package/dist/types/index.d.ts +1 -1
  99. package/dist/types/jobs.d.ts +9 -0
  100. package/dist/types/platform.d.ts +1 -1
  101. package/dist/{BaseModal-DfRIuVoj.js → useDropdownState-uFIz6Yv8.js} +75 -5
  102. package/dist/useDropdownState-uFIz6Yv8.js.map +1 -0
  103. package/dist/{useExperimentSamples-CxcnxZ8h.js → useExperimentSamples-QEFoq4tf.js} +48 -6
  104. package/dist/useExperimentSamples-QEFoq4tf.js.map +1 -0
  105. package/dist/{useListReorder-CcbEYxX-.js → useListReorder-DsuzwWGS.js} +219 -437
  106. package/dist/useListReorder-DsuzwWGS.js.map +1 -0
  107. package/dist/{useRackEditor-BD5NIo5s.js → useRackEditor-KpZ4iJ6o.js} +85 -81
  108. package/dist/useRackEditor-KpZ4iJ6o.js.map +1 -0
  109. package/dist/useRealtime-B58Lo-Tm.js +508 -0
  110. package/dist/useRealtime-B58Lo-Tm.js.map +1 -0
  111. package/dist/useRequest-BuDmW8Jc.js +215 -0
  112. package/dist/useRequest-BuDmW8Jc.js.map +1 -0
  113. package/dist/utils/time.d.ts +7 -0
  114. package/package.json +3 -2
  115. package/src/__stories__/experiment-helpers.ts +3 -3
  116. package/src/__tests__/components/ActionMenu.test.ts +2 -2
  117. package/src/__tests__/components/AppTopBar.test.ts +257 -3
  118. package/src/__tests__/components/AppTopBarOnboarding.test.ts +160 -0
  119. package/src/__tests__/components/AppTopBarPageSelector.test.ts +125 -9
  120. package/src/__tests__/components/AppTopBarPillNav.test.ts +35 -0
  121. package/src/__tests__/components/ArtifactSaveDialog.test.ts +78 -0
  122. package/src/__tests__/components/BaseButton.test.ts +19 -0
  123. package/src/__tests__/components/BaseModal.test.ts +13 -0
  124. package/src/__tests__/components/BaseSelect.multiple.test.ts +87 -32
  125. package/src/__tests__/components/BaseSelect.test.ts +2 -1
  126. package/src/__tests__/components/BatchProgressList.test.ts +16 -0
  127. package/src/__tests__/components/CalendarGridPanel.test.ts +2 -2
  128. package/src/__tests__/components/ChartContainer.test.ts +11 -0
  129. package/src/__tests__/components/ChemicalFormula.test.ts +6 -3
  130. package/src/__tests__/components/DatePicker.datetime.test.ts +6 -0
  131. package/src/__tests__/components/DatePicker.test.ts +21 -0
  132. package/src/__tests__/components/DatePicker.time.test.ts +2 -2
  133. package/src/__tests__/components/EmptyState.test.ts +1 -1
  134. package/src/__tests__/components/ExperimentPopover.test.ts +125 -16
  135. package/src/__tests__/components/ExperimentSelectorModal.test.ts +153 -14
  136. package/src/__tests__/components/FloatingPanelsInModal.test.ts +94 -0
  137. package/src/__tests__/components/GeneratedPluginView.test.ts +23 -2
  138. package/src/__tests__/components/InstrumentStateBadge.test.ts +4 -4
  139. package/src/__tests__/components/JobsStatusTray.test.ts +373 -71
  140. package/src/__tests__/components/PluginWorkspaceView.test.ts +63 -1
  141. package/src/__tests__/components/ResourcePickerListInternal.test.ts +0 -20
  142. package/src/__tests__/components/SampleSelector.test.ts +33 -8
  143. package/src/__tests__/components/SequenceProgressBar.test.ts +12 -0
  144. package/src/__tests__/components/SettingsModal.test.ts +9 -2
  145. package/src/__tests__/components/StepWizard.test.ts +11 -0
  146. package/src/__tests__/components/WellPlate.decoration.test.ts +11 -4
  147. package/src/__tests__/components/deprecationTags.test.ts +1 -1
  148. package/src/__tests__/composables/useAppExperiment.test.ts +27 -1
  149. package/src/__tests__/composables/useCalendarGrid.test.ts +4 -2
  150. package/src/__tests__/composables/useExperimentSelector.test.ts +111 -0
  151. package/src/__tests__/composables/useFileImport.test.ts +36 -0
  152. package/src/__tests__/composables/useFloatingPanel.test.ts +68 -0
  153. package/src/__tests__/composables/useJobCenter.test.ts +262 -3
  154. package/src/__tests__/composables/useOnboarding.test.ts +317 -0
  155. package/src/__tests__/docs/frontendDocsCatalog.test.ts +4 -3
  156. package/src/__tests__/fixtures/table-import/cells.xlsx +0 -0
  157. package/src/__tests__/fixtures/table-import/samples.xlsx +0 -0
  158. package/src/__tests__/stores/settings.test.ts +21 -21
  159. package/src/__tests__/styles/baseControlsRules.test.ts +6 -2
  160. package/src/__tests__/styles/controlRefreshRules.test.ts +0 -6
  161. package/src/__tests__/styles/cssTokens.test.ts +6 -3
  162. package/src/__tests__/styles/menusShellRefresh.test.ts +22 -12
  163. package/src/__tests__/styles/paletteTokens.test.ts +44 -0
  164. package/src/__tests__/styles/v2AuditRules.test.ts +104 -0
  165. package/src/__tests__/utils/plotlyTemplate.test.ts +4 -4
  166. package/src/__tests__/utils/time.test.ts +18 -1
  167. package/src/components/ActionMenu.vue +6 -37
  168. package/src/components/AdductText.story.vue +7 -0
  169. package/src/components/AdductText.vue +1 -1
  170. package/src/components/AlertBox.story.vue +2 -2
  171. package/src/components/AlertBox.vue +18 -16
  172. package/src/components/AppSidebar.story.vue +0 -28
  173. package/src/components/AppTopBar.onboarding.story.vue +69 -0
  174. package/src/components/AppTopBar.story.vue +105 -15
  175. package/src/components/AppTopBar.vue +248 -122
  176. package/src/components/ArtifactSaveDialog.story.vue +23 -0
  177. package/src/components/ArtifactSaveDialog.vue +102 -12
  178. package/src/components/AuditTrail.story.vue +2 -1
  179. package/src/components/AuditTrail.vue +2 -21
  180. package/src/components/Avatar.vue +10 -14
  181. package/src/components/BaseButton.vue +16 -2
  182. package/src/components/BaseModal.vue +2 -1
  183. package/src/components/BaseSelect.multiple.story.vue +13 -2
  184. package/src/components/BaseSelect.vue +4 -3
  185. package/src/components/BatchProgressList.vue +35 -25
  186. package/src/components/ChartContainer.story.vue +2 -1
  187. package/src/components/ChartContainer.vue +8 -6
  188. package/src/components/ConfirmDialog.story.vue +1 -1
  189. package/src/components/EmptyState.vue +1 -1
  190. package/src/components/ExperimentPopover.story.vue +165 -53
  191. package/src/components/ExperimentPopover.vue +169 -187
  192. package/src/components/ExperimentSelectorModal.story.vue +73 -31
  193. package/src/components/ExperimentSelectorModal.vue +144 -111
  194. package/src/components/FormField.story.vue +8 -48
  195. package/src/components/GeneratedPluginView.vue +11 -10
  196. package/src/components/GeneratedResultRenderer.vue +3 -4
  197. package/src/components/InstrumentStateBadge.vue +1 -1
  198. package/src/components/JobsStatusTray.story.vue +97 -43
  199. package/src/components/JobsStatusTray.vue +287 -290
  200. package/src/components/LayoutResizeHandle.story.vue +65 -4
  201. package/src/components/LoadingSpinner.vue +1 -1
  202. package/src/components/NumberInput.vue +3 -6
  203. package/src/components/PluginIcon.story.vue +2 -10
  204. package/src/components/PluginIcon.vue +2 -2
  205. package/src/components/PluginWorkspaceView.props.ts +3 -0
  206. package/src/components/PluginWorkspaceView.story.vue +1 -1
  207. package/src/components/PluginWorkspaceView.vue +17 -0
  208. package/src/components/RuntimeUpdateNotice.vue +1 -1
  209. package/src/components/SampleSelector.story.vue +22 -7
  210. package/src/components/SampleSelector.vue +34 -37
  211. package/src/components/SampleSelectorGroupNode.vue +1 -1
  212. package/src/components/SectionCard.story.vue +35 -2
  213. package/src/components/SequenceProgressBar.story.vue +9 -0
  214. package/src/components/SequenceProgressBar.vue +6 -1
  215. package/src/components/SettingsModal.schema.ts +1 -1
  216. package/src/components/SettingsModal.vue +9 -14
  217. package/src/components/SmartGroupFieldRecipe.story.vue +1 -1
  218. package/src/components/SmartGroupManual.story.vue +1 -1
  219. package/src/components/StepWizard.story.vue +33 -0
  220. package/src/components/StepWizard.vue +8 -1
  221. package/src/components/Tooltip.vue +9 -32
  222. package/src/components/WellPlate.story.vue +3 -1
  223. package/src/components/WellPlate.vue +7 -0
  224. package/src/components/internal/AppTopBarOnboardingInternal.vue +172 -0
  225. package/src/components/internal/AppTopBarPageSelectorInternal.vue +140 -72
  226. package/src/components/internal/AppTopBarPillNavInternal.vue +33 -2
  227. package/src/components/internal/DatePickerDateInternal.vue +23 -85
  228. package/src/components/internal/DatePickerDateTimeInternal.vue +10 -14
  229. package/src/components/internal/DatePickerTimeInternal.vue +13 -9
  230. package/src/components/internal/NumberUnitInputInternal.vue +4 -18
  231. package/src/components/internal/OnboardingLayerInternal.vue +173 -0
  232. package/src/components/internal/ResourcePickerListInternal.vue +45 -85
  233. package/src/components/internal/SelectMultipleInternal.vue +187 -65
  234. package/src/components/internal/SelectSearchableInternal.vue +8 -4
  235. package/src/components/internal/WellEditPopupInternal.vue +11 -22
  236. package/src/components/internal/WorkspaceShellInternal.vue +12 -0
  237. package/src/composables/createClient.ts +2 -0
  238. package/src/composables/index.ts +1 -0
  239. package/src/composables/pluginIdentity.ts +31 -0
  240. package/src/composables/pluginWorkspaceModel.ts +2 -2
  241. package/src/composables/useAppExperiment.ts +20 -0
  242. package/src/composables/useCalendarGrid.ts +4 -3
  243. package/src/composables/useExperimentSelector.ts +77 -31
  244. package/src/composables/useFileImport.ts +51 -1
  245. package/src/composables/useFloatingPanel.ts +107 -0
  246. package/src/composables/useJobCenter.ts +188 -6
  247. package/src/composables/useOnboarding.ts +465 -0
  248. package/src/composables/usePluginWorkspace.ts +1 -1
  249. package/src/data.ts +1 -0
  250. package/src/runtime.ts +2 -1
  251. package/src/shell.ts +17 -0
  252. package/src/stores/index.ts +0 -2
  253. package/src/stores/settings.ts +20 -50
  254. package/src/styles/components/action-menu.css +1 -1
  255. package/src/styles/components/adduct-text.css +13 -5
  256. package/src/styles/components/alert-box.css +39 -58
  257. package/src/styles/components/app-layout.css +10 -6
  258. package/src/styles/components/app-page-selector.css +121 -44
  259. package/src/styles/components/app-pill-nav.css +11 -12
  260. package/src/styles/components/app-sidebar.css +9 -18
  261. package/src/styles/components/app-top-bar.css +219 -55
  262. package/src/styles/components/artifact-save-dialog.css +153 -2
  263. package/src/styles/components/audit-trail.css +16 -19
  264. package/src/styles/components/avatar.css +6 -4
  265. package/src/styles/components/batch-progress-list.css +38 -36
  266. package/src/styles/components/button.css +36 -59
  267. package/src/styles/components/calendar.css +12 -12
  268. package/src/styles/components/chart-container.css +34 -23
  269. package/src/styles/components/checkbox.css +2 -12
  270. package/src/styles/components/collapsible-card.css +27 -29
  271. package/src/styles/components/confirm-dialog.css +13 -14
  272. package/src/styles/components/dataframe.css +13 -5
  273. package/src/styles/components/date-picker.css +84 -94
  274. package/src/styles/components/datetime-picker.css +35 -47
  275. package/src/styles/components/divider.css +20 -20
  276. package/src/styles/components/dose-calculator.css +3 -3
  277. package/src/styles/components/empty-state.css +20 -17
  278. package/src/styles/components/experiment-code-badge.css +2 -0
  279. package/src/styles/components/experiment-popover.css +174 -329
  280. package/src/styles/components/experiment-selector-modal.css +88 -56
  281. package/src/styles/components/file-picker.css +3 -3
  282. package/src/styles/components/file-uploader.css +38 -49
  283. package/src/styles/components/form-builder.css +3 -3
  284. package/src/styles/components/formula-input.css +1 -1
  285. package/src/styles/components/icon-button.css +18 -24
  286. package/src/styles/components/input.css +5 -4
  287. package/src/styles/components/instrument-monitor.css +13 -15
  288. package/src/styles/components/jobs-status-tray.css +140 -296
  289. package/src/styles/components/layout-resize-handle.css +59 -16
  290. package/src/styles/components/modal.css +5 -7
  291. package/src/styles/components/molecule-input.css +2 -2
  292. package/src/styles/components/multi-select.css +65 -117
  293. package/src/styles/components/number-input.css +26 -19
  294. package/src/styles/components/onboarding.css +368 -0
  295. package/src/styles/components/pill.css +3 -2
  296. package/src/styles/components/plate-editor.css +0 -1
  297. package/src/styles/components/plugin-icon.css +26 -23
  298. package/src/styles/components/popover.css +2 -2
  299. package/src/styles/components/presence-avatars.css +1 -1
  300. package/src/styles/components/progress-bar.css +3 -3
  301. package/src/styles/components/protocol-step-editor.css +1 -3
  302. package/src/styles/components/resource-card.css +2 -2
  303. package/src/styles/components/resource-picker-list.css +6 -57
  304. package/src/styles/components/sample-hierarchy-tree.css +4 -4
  305. package/src/styles/components/sample-selector.css +138 -79
  306. package/src/styles/components/schedule-calendar.css +8 -8
  307. package/src/styles/components/searchable-select.css +15 -19
  308. package/src/styles/components/section-card.css +54 -49
  309. package/src/styles/components/segmented-control.css +18 -15
  310. package/src/styles/components/select.css +3 -3
  311. package/src/styles/components/sequence-input.css +2 -2
  312. package/src/styles/components/sequence-progress-bar.css +17 -8
  313. package/src/styles/components/settings-modal.css +7 -2
  314. package/src/styles/components/smart-group.css +18 -18
  315. package/src/styles/components/step-wizard.css +52 -16
  316. package/src/styles/components/tabs.css +2 -2
  317. package/src/styles/components/textarea.css +3 -3
  318. package/src/styles/components/time-picker.css +37 -25
  319. package/src/styles/components/toast.css +13 -11
  320. package/src/styles/components/toggle.css +1 -11
  321. package/src/styles/components/tooltip.css +12 -11
  322. package/src/styles/components/unit-input.css +9 -8
  323. package/src/styles/components/well-edit-popup.css +2 -2
  324. package/src/styles/components/well-plate.css +9 -2
  325. package/src/styles/index.css +1 -0
  326. package/src/styles/variables.css +247 -78
  327. package/src/types/componentWorkflowTypes.ts +2 -0
  328. package/src/types/components.ts +2 -0
  329. package/src/types/generated/platformContext.ts +1 -0
  330. package/src/types/generated-ui.ts +4 -0
  331. package/src/types/index.ts +1 -0
  332. package/src/types/jobs.ts +10 -0
  333. package/src/types/platform.ts +1 -1
  334. package/src/utils/time.ts +21 -0
  335. package/dist/ActionMenu-CScINahU.js.map +0 -1
  336. package/dist/AppSidebar-BmiiPfz9.js.map +0 -1
  337. package/dist/BaseModal-DfRIuVoj.js.map +0 -1
  338. package/dist/ExperimentPopover-C4sGw-is.js +0 -359
  339. package/dist/ExperimentPopover-C4sGw-is.js.map +0 -1
  340. package/dist/ExperimentSelectorModal-D-9z7cNx.js.map +0 -1
  341. package/dist/SettingsModal-CSLE31yg.js.map +0 -1
  342. package/dist/data-C2PwI_dn.js.map +0 -1
  343. package/dist/experiment-43OJtH7R.js.map +0 -1
  344. package/dist/lab-DLwRl_Ql.js.map +0 -1
  345. package/dist/records-BzTcxekG.js.map +0 -1
  346. package/dist/runtime-D6gVat6r.js.map +0 -1
  347. package/dist/useExperimentSamples-CxcnxZ8h.js.map +0 -1
  348. package/dist/useListReorder-CcbEYxX-.js.map +0 -1
  349. package/dist/useRackEditor-BD5NIo5s.js.map +0 -1
  350. package/dist/useRealtime-PalKue84.js +0 -696
  351. package/dist/useRealtime-PalKue84.js.map +0 -1
  352. package/dist/useRequest-D5JDfsgZ.js +0 -76
  353. package/dist/useRequest-D5JDfsgZ.js.map +0 -1
@@ -1,14 +1,22 @@
1
1
  <script setup lang="ts">
2
- /** Floating popover showing the active experiment with save, detach, and select actions. */
3
- import { ref, computed, watch, onUnmounted, useTemplateRef } from 'vue'
2
+ /** Top-bar control for the attached experiment: a trigger joined to an optional Save button, with a summary panel (change, open, detach). */
3
+ import { ref, computed, watch, nextTick, onUnmounted, useTemplateRef } from 'vue'
4
+ import { ArrowLeftRight, Check, ChevronDown, CircleAlert, CloudUpload, ExternalLink, Link, LoaderCircle, Unlink } from 'lucide-vue-next'
4
5
  import { useDropdownState } from '../composables/useDropdownState'
5
6
  import { format as formatStatus } from '../utils/experimentStatus'
7
+ import { formatRelativeTime } from '../utils/time'
6
8
  import ConfirmDialog from './ConfirmDialog.vue'
7
9
 
8
10
  interface Props {
9
11
  experimentName?: string
10
12
  experimentCode?: string
11
13
  experimentStatus?: string
14
+ /** Platform id of the bound experiment; enables "Open in MINT". */
15
+ experimentId?: number | null
16
+ experimentProject?: string
17
+ experimentOwner?: string
18
+ /** ISO timestamp of the last update, shown as relative time. */
19
+ experimentUpdatedAt?: string
12
20
  /** An experiment is bound but the platform has not returned its record yet. */
13
21
  isResolving?: boolean
14
22
  /** Message explaining why the bound experiment could not be resolved. */
@@ -19,18 +27,30 @@ interface Props {
19
27
  saveLoading?: boolean
20
28
  saveSuccessMessage?: string
21
29
  saveDisabledMessage?: string
30
+ saveLabel?: string
31
+ /** Unsaved changes: marks the Save button with a dot. */
32
+ dirty?: boolean
22
33
  confirmSave?: boolean
23
34
  confirmTitle?: string
24
35
  confirmMessage?: string
36
+ /** Empty-state trigger label. */
37
+ placeholder?: string
38
+ /** The trigger name truncates at this width (px); its title shows code and name in full. */
39
+ maxNameWidth?: number
25
40
  }
26
41
 
27
42
  const props = withDefaults(defineProps<Props>(), {
43
+ experimentId: null,
28
44
  isResolving: false,
29
45
  showSave: false,
30
46
  showDetach: false,
31
47
  saveDisabled: false,
32
48
  saveLoading: false,
49
+ saveLabel: 'Save',
50
+ dirty: false,
33
51
  confirmSave: true,
52
+ placeholder: 'Attach experiment',
53
+ maxNameWidth: 200,
34
54
  })
35
55
 
36
56
  // An experiment is bound but has no name to show — either still resolving or
@@ -38,17 +58,13 @@ const props = withDefaults(defineProps<Props>(), {
38
58
  // platform, so these states say what is happening instead of inventing a label.
39
59
  const isUnresolved = computed(() => props.isResolving || !!props.error)
40
60
  const hasExperiment = computed(() => !!props.experimentName || !!props.experimentCode)
41
-
42
- const panelSubtitle = computed(() => {
43
- if (props.isResolving) return 'Loading experiment…'
44
- if (props.error) return 'Could not load this experiment'
45
- return hasExperiment.value ? 'Linked experiment context' : 'Link to an MINT experiment'
46
- })
61
+ const isEmpty = computed(() => !isUnresolved.value && !hasExperiment.value)
62
+ const hasSave = computed(() => props.showSave && !isUnresolved.value && hasExperiment.value)
47
63
 
48
64
  const triggerLabel = computed(() => {
49
65
  if (props.isResolving) return 'Loading experiment'
50
66
  if (props.error) return 'Experiment unavailable'
51
- return props.experimentName || props.experimentCode || 'No experiment'
67
+ return [props.experimentCode, props.experimentName].filter(Boolean).join(' · ') || props.placeholder
52
68
  })
53
69
 
54
70
  const emit = defineEmits<{
@@ -65,9 +81,38 @@ const { isOpen, close, toggle } = useDropdownState({
65
81
  const showSuccess = ref(false)
66
82
  const showConfirm = ref(false)
67
83
 
84
+ // The panel hangs from the group's left edge; when that would cross the
85
+ // viewport's right edge (a control at the end of the top bar) it hangs from the right.
86
+ const panel = useTemplateRef<HTMLElement>('panel')
87
+ const panelAlignEnd = ref(false)
88
+ watch(isOpen, async (open) => {
89
+ if (!open) return
90
+ panelAlignEnd.value = false
91
+ await nextTick()
92
+ const right = panel.value?.getBoundingClientRect().right ?? 0
93
+ panelAlignEnd.value = right > document.documentElement.clientWidth
94
+ })
95
+
96
+ const saveTitle = computed(() => {
97
+ if (props.saveDisabled && props.saveDisabledMessage) return props.saveDisabledMessage
98
+ if (showSuccess.value && props.saveSuccessMessage) return props.saveSuccessMessage
99
+ return `${props.saveLabel} to experiment`
100
+ })
101
+
102
+ // A function, not a computed: "Updated" is relative to now, so it is
103
+ // re-evaluated each time the panel renders.
104
+ function metaRows(): [string, string][] {
105
+ return ([
106
+ ['Project', props.experimentProject],
107
+ ['Status', props.experimentStatus && formatStatus(props.experimentStatus)],
108
+ ['Owner', props.experimentOwner],
109
+ ['Updated', props.experimentUpdatedAt && formatRelativeTime(props.experimentUpdatedAt)],
110
+ ] as [string, string | undefined][]).filter((row): row is [string, string] => !!row[1])
111
+ }
112
+
68
113
  function handleTriggerClick() {
69
- if (!hasExperiment.value && !isUnresolved.value) {
70
- handleSelect()
114
+ if (isEmpty.value) {
115
+ emit('select')
71
116
  return
72
117
  }
73
118
  toggle()
@@ -80,6 +125,7 @@ function handleSelect() {
80
125
 
81
126
  function handleSave() {
82
127
  if (props.saveDisabled || props.saveLoading) return
128
+ close()
83
129
  if (props.confirmSave) {
84
130
  showConfirm.value = true
85
131
  } else {
@@ -117,201 +163,137 @@ onUnmounted(() => {
117
163
  </script>
118
164
 
119
165
  <template>
120
- <div ref="popover" class="mint-experiment-popover">
121
- <!-- Split trigger: experiment pill + inline save -->
122
- <div
166
+ <div ref="popover" :class="['mint-experiment-popover', { 'mint-experiment-popover--save': hasSave }]">
167
+ <!-- Trigger: code + name when attached, opens the panel; the empty state selects directly. -->
168
+ <button
169
+ ref="trigger"
170
+ type="button"
123
171
  :class="[
124
- 'mint-experiment-popover__split',
125
- { 'mint-experiment-popover__split--with-save': showSave && experimentName },
172
+ 'mint-experiment-popover__trigger',
173
+ { 'mint-experiment-popover__trigger--active': isOpen },
174
+ { 'mint-experiment-popover__trigger--empty': isEmpty },
175
+ { 'mint-experiment-popover__trigger--loading': isResolving },
176
+ { 'mint-experiment-popover__trigger--error': !isResolving && !!error },
126
177
  ]"
178
+ :title="triggerLabel"
179
+ :aria-label="isUnresolved ? triggerLabel : undefined"
180
+ :aria-busy="isResolving || undefined"
181
+ :aria-expanded="isEmpty ? undefined : isOpen"
182
+ @click.stop="handleTriggerClick"
127
183
  >
128
- <!-- Left: experiment trigger (selects when empty, otherwise opens popover). Prefer the human-readable
129
- name; the formal code, when present, stays in the detail panel. -->
130
- <button
131
- ref="trigger"
132
- type="button"
133
- :class="[
134
- 'mint-experiment-popover__trigger',
135
- { 'mint-experiment-popover__trigger--active': isOpen },
136
- { 'mint-experiment-popover__trigger--empty': !isUnresolved && !hasExperiment },
137
- { 'mint-experiment-popover__trigger--loading': isResolving },
138
- { 'mint-experiment-popover__trigger--error': !isResolving && !!error },
139
- ]"
140
- :title="isUnresolved ? triggerLabel : experimentName || experimentCode || undefined"
141
- :aria-label="isUnresolved ? triggerLabel : undefined"
142
- :aria-busy="isResolving || undefined"
143
- :aria-expanded="isOpen"
144
- @click.stop="handleTriggerClick"
145
- >
146
- <!-- Flask icon -->
147
- <svg class="mint-experiment-popover__trigger-icon" aria-hidden="true" fill="none" stroke="currentColor" viewBox="0 0 24 24">
148
- <path
149
- stroke-linecap="round"
150
- stroke-linejoin="round"
151
- stroke-width="1.75"
152
- d="M19.428 15.428a2 2 0 00-1.022-.547l-2.387-.477a6 6 0 00-3.86.517l-.318.158a6 6 0 01-3.86.517L6.05 15.21a2 2 0 00-1.806.547M8 4h8l-1 1v5.172a2 2 0 00.586 1.414l5 5c1.26 1.26.367 3.414-1.415 3.414H4.828c-1.782 0-2.674-2.154-1.414-3.414l5-5A2 2 0 009 10.172V5L8 4z"
153
- />
154
- </svg>
155
- <!-- Resolving and error come first: with an experiment bound but no name
156
- yet, "No experiment" would be a lie. -->
157
- <span v-if="isResolving" class="mint-experiment-popover__trigger-skeleton" aria-hidden="true" />
158
- <span v-else-if="error" class="mint-experiment-popover__trigger-text">Experiment unavailable</span>
159
- <!-- Name preferred, code as fallback, "No experiment" as empty state -->
160
- <span v-else-if="experimentName" class="mint-experiment-popover__trigger-text">{{ experimentName }}</span>
161
- <span v-else-if="experimentCode" class="mint-experiment-popover__trigger-code">{{ experimentCode }}</span>
162
- <span v-else class="mint-experiment-popover__trigger-text">No experiment</span>
163
- <!-- Chevron -->
164
- <svg class="mint-experiment-popover__trigger-chevron" aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
165
- <path d="m6 9 6 6 6-6" />
166
- </svg>
167
- </button>
184
+ <!-- Resolving and error come first: with an experiment bound but no name
185
+ yet, the empty placeholder would be a lie. -->
186
+ <span v-if="isResolving" class="mint-experiment-popover__trigger-skeleton" aria-hidden="true" />
187
+ <template v-else-if="error">
188
+ <CircleAlert class="mint-experiment-popover__trigger-icon" :size="14" aria-hidden="true" />
189
+ <span class="mint-experiment-popover__trigger-text">Experiment unavailable</span>
190
+ </template>
191
+ <template v-else-if="hasExperiment">
192
+ <span v-if="experimentCode" class="mint-exp-code mint-exp-code--sm">{{ experimentCode }}</span>
193
+ <span
194
+ v-if="experimentName"
195
+ class="mint-experiment-popover__trigger-text"
196
+ :style="{ maxWidth: `${maxNameWidth}px` }"
197
+ >{{ experimentName }}</span>
198
+ </template>
199
+ <template v-else>
200
+ <Link class="mint-experiment-popover__trigger-icon" :size="14" aria-hidden="true" />
201
+ <span class="mint-experiment-popover__trigger-text">{{ placeholder }}</span>
202
+ </template>
203
+ <ChevronDown v-if="!isEmpty" class="mint-experiment-popover__trigger-chevron" :size="13" aria-hidden="true" />
204
+ </button>
168
205
 
169
- <!-- Right: inline save button (direct action) -->
170
- <button
171
- v-if="showSave && experimentName"
172
- type="button"
173
- :class="[
174
- 'mint-experiment-popover__save-trigger',
175
- { 'mint-experiment-popover__save-trigger--loading': saveLoading },
176
- { 'mint-experiment-popover__save-trigger--success': showSuccess },
177
- { 'mint-experiment-popover__save-trigger--disabled': saveDisabled && !showSuccess },
178
- ]"
179
- :disabled="saveDisabled && !showSuccess"
180
- :title="saveDisabled && saveDisabledMessage ? saveDisabledMessage : showSuccess && saveSuccessMessage ? saveSuccessMessage : 'Save to Experiment'"
181
- aria-label="Save to experiment"
182
- @click.stop="handleSave"
183
- >
184
- <!-- Loading spinner -->
185
- <span v-if="saveLoading" class="mint-experiment-popover__spinner--inline" />
186
- <!-- Success check -->
187
- <svg v-else-if="showSuccess" class="mint-experiment-popover__save-trigger-icon" aria-hidden="true" fill="none" stroke="currentColor" viewBox="0 0 24 24">
188
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M5 13l4 4L19 7" />
189
- </svg>
190
- <!-- Save icon -->
191
- <svg v-else class="mint-experiment-popover__save-trigger-icon" aria-hidden="true" fill="none" stroke="currentColor" viewBox="0 0 24 24">
192
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7H5a2 2 0 00-2 2v9a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-3m-1 4l-3 3m0 0l-3-3m3 3V4" />
193
- </svg>
194
- </button>
195
- </div>
206
+ <!-- Save: joined to the trigger at top-bar level, never inside the panel. -->
207
+ <button
208
+ v-if="hasSave"
209
+ type="button"
210
+ :class="[
211
+ 'mint-experiment-popover__save',
212
+ { 'mint-experiment-popover__save--loading': saveLoading },
213
+ { 'mint-experiment-popover__save--success': showSuccess },
214
+ { 'mint-experiment-popover__save--disabled': saveDisabled && !showSuccess },
215
+ ]"
216
+ :disabled="saveLoading || (saveDisabled && !showSuccess)"
217
+ :title="saveTitle"
218
+ :aria-label="dirty ? `${saveTitle} (unsaved changes)` : saveTitle"
219
+ @click.stop="handleSave"
220
+ >
221
+ <LoaderCircle v-if="saveLoading" class="mint-experiment-popover__save-spinner" :size="14" aria-hidden="true" />
222
+ <Check v-else-if="showSuccess" :size="14" aria-hidden="true" />
223
+ <CloudUpload v-else :size="14" aria-hidden="true" />
224
+ <span>{{ saveLoading ? 'Saving…' : saveLabel }}</span>
225
+ <span v-if="dirty && !saveLoading" class="mint-experiment-popover__dirty" aria-hidden="true" />
226
+ </button>
196
227
 
197
- <!-- Popover panel -->
198
- <div v-if="isOpen" class="mint-experiment-popover__panel">
199
- <!-- Header -->
200
- <div class="mint-experiment-popover__header">
201
- <div class="mint-experiment-popover__title">Experiment</div>
202
- <div class="mint-experiment-popover__subtitle">
203
- {{ panelSubtitle }}
204
- </div>
228
+ <!-- Summary panel: header, meta, then menu rows. No buttons inside. -->
229
+ <div
230
+ v-if="isOpen"
231
+ ref="panel"
232
+ :class="['mint-experiment-popover__panel', { 'mint-experiment-popover__panel--end': panelAlignEnd }]"
233
+ >
234
+ <!-- Bound, still resolving — placeholders stand in for the record. -->
235
+ <div v-if="isResolving" class="mint-experiment-popover__head" aria-busy="true">
236
+ <span class="mint-experiment-popover__skeleton-line mint-experiment-popover__skeleton-line--code" />
237
+ <span class="mint-experiment-popover__skeleton-line mint-experiment-popover__skeleton-line--name" />
205
238
  </div>
206
239
 
207
- <!-- Bound, still resolving — placeholders stand in for the record the
208
- platform has not returned yet. -->
209
- <div v-if="isResolving" class="mint-experiment-popover__body">
210
- <div class="mint-experiment-popover__card" aria-busy="true">
211
- <div class="mint-experiment-popover__card-icon">
212
- <svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
213
- <path
214
- stroke-linecap="round"
215
- stroke-linejoin="round"
216
- stroke-width="1.75"
217
- d="M19.428 15.428a2 2 0 00-1.022-.547l-2.387-.477a6 6 0 00-3.86.517l-.318.158a6 6 0 01-3.86.517L6.05 15.21a2 2 0 00-1.806.547M8 4h8l-1 1v5.172a2 2 0 00.586 1.414l5 5c1.26 1.26.367 3.414-1.415 3.414H4.828c-1.782 0-2.674-2.154-1.414-3.414l5-5A2 2 0 009 10.172V5L8 4z"
218
- />
219
- </svg>
220
- </div>
221
- <div class="mint-experiment-popover__card-info">
222
- <span class="mint-experiment-popover__skeleton-line mint-experiment-popover__skeleton-line--code" />
223
- <span class="mint-experiment-popover__skeleton-line mint-experiment-popover__skeleton-line--name" />
224
- <span class="mint-experiment-popover__skeleton-line mint-experiment-popover__skeleton-line--status" />
225
- </div>
226
- </div>
227
- <div class="mint-experiment-popover__card-actions">
228
- <button type="button" class="mint-experiment-popover__change-btn" @click="handleSelect">
229
- Change
230
- </button>
231
- <button v-if="showDetach" type="button" class="mint-experiment-popover__detach-btn" @click="handleDetach">
232
- Detach
233
- </button>
234
- </div>
240
+ <!-- Bound, resolution failed — Detach stays reachable below. -->
241
+ <div v-else-if="error" class="mint-experiment-popover__head mint-experiment-popover__head--error" role="alert">
242
+ <b class="mint-experiment-popover__name">
243
+ <CircleAlert :size="14" aria-hidden="true" />
244
+ Experiment unavailable
245
+ </b>
246
+ <span class="mint-experiment-popover__message">{{ error }}</span>
235
247
  </div>
236
248
 
237
- <!-- Bound, resolution failed — Detach stays reachable so the user is not
238
- stuck on an experiment the platform cannot describe. -->
239
- <div v-else-if="error" class="mint-experiment-popover__body">
240
- <div class="mint-experiment-popover__card mint-experiment-popover__card--error" role="alert">
241
- <div class="mint-experiment-popover__card-icon mint-experiment-popover__card-icon--error">
242
- <svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
243
- <path
244
- stroke-linecap="round"
245
- stroke-linejoin="round"
246
- stroke-width="1.75"
247
- d="M12 9v3.75m9-.75a9 9 0 11-18 0 9 9 0 0118 0zm-9 3.75h.008v.008H12v-.008z"
248
- />
249
- </svg>
250
- </div>
251
- <div class="mint-experiment-popover__card-info">
252
- <div class="mint-experiment-popover__card-name">Experiment unavailable</div>
253
- <div class="mint-experiment-popover__card-message">{{ error }}</div>
254
- </div>
255
- </div>
256
- <div class="mint-experiment-popover__card-actions">
257
- <button type="button" class="mint-experiment-popover__change-btn" @click="handleSelect">
258
- Change
259
- </button>
260
- <button v-if="showDetach" type="button" class="mint-experiment-popover__detach-btn" @click="handleDetach">
261
- Detach
262
- </button>
249
+ <template v-else>
250
+ <div class="mint-experiment-popover__head">
251
+ <span v-if="experimentCode" class="mint-exp-code mint-exp-code--sm">{{ experimentCode }}</span>
252
+ <b v-if="experimentName" class="mint-experiment-popover__name">{{ experimentName }}</b>
263
253
  </div>
264
- </div>
254
+ <dl v-if="metaRows().length" class="mint-experiment-popover__meta">
255
+ <template v-for="[label, value] in metaRows()" :key="label">
256
+ <dt>{{ label }}</dt>
257
+ <dd>{{ value }}</dd>
258
+ </template>
259
+ </dl>
260
+ </template>
265
261
 
266
- <!-- No experiment selected -->
267
- <div v-else-if="!experimentName" class="mint-experiment-popover__body">
268
- <button type="button" class="mint-experiment-popover__select-btn" @click="handleSelect">
269
- <svg width="14" height="14" fill="none" stroke="currentColor" viewBox="0 0 24 24">
270
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4" />
271
- </svg>
272
- Select Experiment
273
- </button>
274
- </div>
262
+ <div class="mint-experiment-popover__separator" role="separator" />
275
263
 
276
- <!-- Experiment selected -->
277
- <div v-else class="mint-experiment-popover__body">
278
- <div class="mint-experiment-popover__card">
279
- <div class="mint-experiment-popover__card-icon">
280
- <svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
281
- <path
282
- stroke-linecap="round"
283
- stroke-linejoin="round"
284
- stroke-width="1.75"
285
- d="M19.428 15.428a2 2 0 00-1.022-.547l-2.387-.477a6 6 0 00-3.86.517l-.318.158a6 6 0 01-3.86.517L6.05 15.21a2 2 0 00-1.806.547M8 4h8l-1 1v5.172a2 2 0 00.586 1.414l5 5c1.26 1.26.367 3.414-1.415 3.414H4.828c-1.782 0-2.674-2.154-1.414-3.414l5-5A2 2 0 009 10.172V5L8 4z"
286
- />
287
- </svg>
288
- </div>
289
- <div class="mint-experiment-popover__card-info">
290
- <span v-if="experimentCode" class="mint-experiment-popover__card-code">{{ experimentCode }}</span>
291
- <div class="mint-experiment-popover__card-name">{{ experimentName }}</div>
292
- <div v-if="experimentStatus" class="mint-experiment-popover__card-status">
293
- {{ formatStatus(experimentStatus) }}
294
- </div>
295
- </div>
296
- </div>
297
- <div class="mint-experiment-popover__card-actions">
298
- <button type="button" class="mint-experiment-popover__change-btn" @click="handleSelect">
299
- Change
300
- </button>
301
- <button v-if="showDetach" type="button" class="mint-experiment-popover__detach-btn" @click="handleDetach">
302
- Detach
303
- </button>
304
- </div>
305
- </div>
264
+ <button type="button" class="mint-experiment-popover__option" @click="handleSelect">
265
+ <ArrowLeftRight class="mint-experiment-popover__option-icon" :size="14" aria-hidden="true" />
266
+ Change experiment…
267
+ </button>
268
+ <a
269
+ v-if="experimentId != null"
270
+ class="mint-experiment-popover__option"
271
+ :href="`/experiments/${experimentId}`"
272
+ target="_blank"
273
+ rel="noopener"
274
+ @click="close()"
275
+ >
276
+ <ExternalLink class="mint-experiment-popover__option-icon" :size="14" aria-hidden="true" />
277
+ Open in MINT
278
+ </a>
279
+ <button
280
+ v-if="showDetach"
281
+ type="button"
282
+ class="mint-experiment-popover__option mint-experiment-popover__option--danger"
283
+ @click="handleDetach"
284
+ >
285
+ <Unlink class="mint-experiment-popover__option-icon" :size="14" aria-hidden="true" />
286
+ Detach
287
+ </button>
306
288
  </div>
307
289
 
308
290
  <!-- Save confirmation dialog -->
309
291
  <ConfirmDialog
310
292
  v-model:open="showConfirm"
311
293
  :title="confirmTitle ?? 'Save to Experiment'"
312
- :message="confirmMessage ?? `Save current data to ${experimentName}?`"
294
+ :message="confirmMessage ?? `Save current data to ${experimentName ?? experimentCode}?`"
313
295
  tone="info"
314
- confirm-label="Save"
296
+ :confirm-label="saveLabel"
315
297
  :loading="saveLoading"
316
298
  @confirm="handleConfirmSave"
317
299
  />