@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,13 +1,13 @@
1
- import { a as __exportAll, r as useEventListener } from "./BaseModal-DfRIuVoj.js";
2
- import { i as AuthenticationRequiredError, o as useApi } from "./experiment-43OJtH7R.js";
3
- import { D as useDropdownState, c as isTerminalJobStatus, d as normalizeJobState, f as resolveJobCapabilities, k as EmptyState_default, l as jobStatusLabel, o as resolveCurrentPluginId, s as isActiveJobStatus, t as isRecord, u as normalizeJobPercent, v as useAppExperiment } from "./records-BzTcxekG.js";
4
- import { A as createGeneratedAnalysisTransport, D as GeneratedPathInput_default, H as definePluginWorkspaceView, O as _plugin_vue_export_helper_default, _ as getFieldRegistryEntry, g as replaceRecord, j as useJobsEndpoint, k as GENERATED_JOBS_API_KEY, v as getTypeDefault } from "./useListReorder-CcbEYxX-.js";
5
- import { i as LoadingSpinner_default, n as AlertBox_default } from "./ActionMenu-CScINahU.js";
6
- import { D as DataFrame_default, T as WellPlate_default, a as GeneratedPlotlyResult_default, b as PlateEditor_default, c as downloadEndpoint, d as useEventStream, f as useSettingsEndpoint, i as GeneratedResultRenderer_default, l as pluginFormDataFromPayload, m as resolvePluginBaseUrl, n as ScheduleCalendar_default, o as createClient, p as buildEndpointUrl, t as useRackEditor, u as uploadEndpoint, v as DoseCalculator_default } from "./useRackEditor-BD5NIo5s.js";
7
- import { C as controlValuesToComponentBindings, E as controlsTo, S as controlBindings, T as controlValuesToComponentProps, _ as usePluginWorkspace, b as getControlDefaults, d as useForm, f as AppTopBar_default, g as AppLayout_default, k as getDefaultControlView, l as useFormBuilder, t as AppSidebar_default, u as evaluateCondition, v as defineControlComponentBindings, w as controlValuesToComponentBindingsById, x as useControlSchema, y as defineControls } from "./AppSidebar-BmiiPfz9.js";
8
- import { n as isControlModelBinding } from "./controlSchemaModel-CP5-_nAj.js";
9
- import { a as combinePluginJobSources, i as JobsStatusTray_default, n as subscribeRealtime, o as useJobCenter, r as useRealtime, t as currentPresence } from "./useRealtime-PalKue84.js";
10
- import { Fragment, Teleport, TransitionGroup, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createSlots, createTextVNode, createVNode, defineComponent, getCurrentScope, guardReactiveProps, mergeProps, normalizeClass, normalizeProps, normalizeStyle, onMounted, onScopeDispose, openBlock, provide, reactive, readonly, ref, renderList, renderSlot, resolveDynamicComponent, toDisplayString, toHandlers, toValue, unref, useId, useSlots, useTemplateRef, watch, withCtx, withModifiers } from "vue";
1
+ import { i as useEventListener, o as __exportAll, t as useDropdownState } from "./useDropdownState-uFIz6Yv8.js";
2
+ import { i as AuthenticationRequiredError, o as useApi } from "./experiment-DyO54FQB.js";
3
+ import { L as EmptyState_default, d as isActiveJobStatus, f as isTerminalJobStatus, g as resolveJobCapabilities, h as normalizeJobState, m as normalizeJobPercent, o as resolveCurrentPluginId, p as jobStatusLabel, t as isRecord, v as useAppExperiment } from "./records-D4aQXyZu.js";
4
+ import { A as useJobsEndpoint, D as _plugin_vue_export_helper_default, E as GeneratedPathInput_default, M as usePlatform, O as GENERATED_JOBS_API_KEY, R as definePluginWorkspaceView, _ as getTypeDefault, g as getFieldRegistryEntry, h as replaceRecord, k as createGeneratedAnalysisTransport } from "./useListReorder-DsuzwWGS.js";
5
+ import { r as LoadingSpinner_default, t as AlertBox_default } from "./AlertBox-DwgNTEqf.js";
6
+ import { D as DataFrame_default, T as WellPlate_default, a as GeneratedPlotlyResult_default, b as PlateEditor_default, c as downloadEndpoint, d as useEventStream, f as useSettingsEndpoint, i as GeneratedResultRenderer_default, l as pluginFormDataFromPayload, m as resolvePluginBaseUrl, n as ScheduleCalendar_default, o as createClient, p as buildEndpointUrl, t as useRackEditor, u as uploadEndpoint, v as DoseCalculator_default } from "./useRackEditor-KpZ4iJ6o.js";
7
+ import { A as controlValuesToComponentBindingsById, C as usePluginWorkspace, D as useControlSchema, E as getControlDefaults, F as getDefaultControlView, M as controlsTo, O as controlBindings, S as AppLayout_default, T as defineControls, d as useForm, f as AppTopBar_default, j as controlValuesToComponentProps, k as controlValuesToComponentBindings, l as useFormBuilder, p as providePluginIdentity, t as AppSidebar_default, u as evaluateCondition, w as defineControlComponentBindings } from "./AppSidebar-CZZaxni0.js";
8
+ import { n as isControlModelBinding } from "./controlSchemaModel-Bsg0t5Ab.js";
9
+ import { i as JobsStatusTray_default, n as subscribeRealtime, r as useRealtime, t as currentPresence } from "./useRealtime-B58Lo-Tm.js";
10
+ import { Fragment, Teleport, TransitionGroup, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createSlots, createTextVNode, createVNode, defineComponent, getCurrentScope, guardReactiveProps, mergeProps, normalizeClass, normalizeProps, normalizeStyle, onMounted, onScopeDispose, onUnmounted, openBlock, provide, reactive, readonly, ref, renderList, renderSlot, resolveDynamicComponent, shallowRef, toDisplayString, toHandlers, toValue, unref, useId, useSlots, useTemplateRef, watch, withCtx, withModifiers } from "vue";
11
11
  import { ChartColumn, Eye, FlaskConical, Pencil, RefreshCw } from "lucide-vue-next";
12
12
  //#region src/composables/useToast.ts
13
13
  var toasts = ref([]);
@@ -232,6 +232,333 @@ var AppToastContainer_default = /* @__PURE__ */ defineComponent({
232
232
  }
233
233
  });
234
234
  //#endregion
235
+ //#region src/composables/useJobCenter.ts
236
+ /** How long a job that just completed stays in the top-bar run slot. */
237
+ var FINISHED_HOLD_MS = 6e3;
238
+ /**
239
+ * Combines independent job runtimes without copying their reactive state.
240
+ *
241
+ * Job ids must be globally unique across the sources. A duplicate id throws
242
+ * when jobs are read or an id-routed action is requested, rather than silently
243
+ * dispatching a mutation to the wrong owner.
244
+ */
245
+ function combinePluginJobSources(sources) {
246
+ const jobs = computed(() => {
247
+ const combined = [];
248
+ const owners = /* @__PURE__ */ new Set();
249
+ for (const source of sources) for (const job of toValue(source.jobs)) {
250
+ if (owners.has(job.job_id)) throw duplicatePluginJobId(job.job_id);
251
+ owners.add(job.job_id);
252
+ combined.push(job);
253
+ }
254
+ return combined;
255
+ });
256
+ function ownerFor(jobId) {
257
+ let owner;
258
+ for (const source of sources) {
259
+ if (!toValue(source.jobs).some((job) => job.job_id === jobId)) continue;
260
+ if (owner) throw duplicatePluginJobId(jobId);
261
+ owner = source;
262
+ }
263
+ if (!owner) throw new Error(`Unknown plugin job id: ${jobId}`);
264
+ return owner;
265
+ }
266
+ const combined = { jobs };
267
+ if (sources.some((source) => source.refresh)) combined.refresh = async () => {
268
+ await Promise.all(sources.map((source) => source.refresh?.()));
269
+ return jobs.value;
270
+ };
271
+ if (sources.some((source) => source.cancel)) combined.cancel = async (jobId) => {
272
+ const owner = ownerFor(jobId);
273
+ if (!owner.cancel) throw new Error(`Job ${jobId} cannot be cancelled by its source`);
274
+ return owner.cancel(jobId);
275
+ };
276
+ if (sources.length > 0 && sources.every((source) => source.delete)) combined.delete = async (jobId) => {
277
+ const owner = ownerFor(jobId);
278
+ if (!owner.delete) throw new Error(`Job ${jobId} cannot be deleted by its source`);
279
+ return owner.delete(jobId);
280
+ };
281
+ if (sources.length > 0 && sources.every((source) => source.clear)) combined.clear = async () => {
282
+ const results = await Promise.all(sources.map((source) => source.clear()));
283
+ return results.every((result) => typeof result === "number") ? results.reduce((total, result) => total + result, 0) : void 0;
284
+ };
285
+ if (sources.some((source) => source.dispose)) combined.dispose = () => {
286
+ const errors = [];
287
+ for (const source of sources) try {
288
+ source.dispose?.();
289
+ } catch (cause) {
290
+ errors.push(cause);
291
+ }
292
+ if (errors.length === 1) throw errors[0];
293
+ if (errors.length > 1) throw new PluginJobSourceDisposeError(errors);
294
+ };
295
+ return combined;
296
+ }
297
+ var PluginJobSourceDisposeError = class extends Error {
298
+ cause;
299
+ errors;
300
+ constructor(errors) {
301
+ super("Failed to dispose plugin job sources");
302
+ this.name = "PluginJobSourceDisposeError";
303
+ this.cause = errors[0];
304
+ this.errors = Object.freeze([...errors]);
305
+ }
306
+ };
307
+ function duplicatePluginJobId(jobId) {
308
+ return /* @__PURE__ */ new Error(`Duplicate plugin job id across combined sources: ${jobId}`);
309
+ }
310
+ /** The stored seen failures, or null when nothing is stored or storage is blocked. */
311
+ function readSeenFailed(key) {
312
+ try {
313
+ const parsed = JSON.parse(globalThis.localStorage?.getItem(key) ?? "null");
314
+ return Array.isArray(parsed) ? new Set(parsed.filter((id) => typeof id === "string")) : null;
315
+ } catch {
316
+ return null;
317
+ }
318
+ }
319
+ function writeSeenFailed(key, seen) {
320
+ try {
321
+ globalThis.localStorage?.setItem(key, JSON.stringify([...seen]));
322
+ } catch {}
323
+ }
324
+ function jobMessage(job) {
325
+ if (job.error) return job.error;
326
+ if (job.status === "awaiting_input") return job.progress.message || "Waiting for external input";
327
+ if (job.status === "queued" && job.queue_position > 0) return `Queue position ${job.queue_position}`;
328
+ return job.progress.message || job.progress.stage || jobStatusLabel(job.status);
329
+ }
330
+ function errorMessage(error, fallback) {
331
+ return error instanceof Error ? error.message : fallback;
332
+ }
333
+ /**
334
+ * Headless controller for plugin job presentation and actions.
335
+ *
336
+ * Every job list is derived directly from the source. The controller never
337
+ * mirrors source jobs into another ref.
338
+ */
339
+ function useJobCenter(options = {}) {
340
+ const isOpen = ref(false);
341
+ const isLoading = ref(false);
342
+ const error = shallowRef(null);
343
+ const pendingJobIds = ref(/* @__PURE__ */ new Set());
344
+ let requestGeneration = 0;
345
+ let active = true;
346
+ const source = computed(() => toValue(options.source));
347
+ const jobs = computed(() => {
348
+ const currentSource = source.value;
349
+ return currentSource ? [...toValue(currentSource.jobs)].map(normalizeJobState) : [];
350
+ });
351
+ const activeJobs = computed(() => jobs.value.filter((job) => isActiveJobStatus(job.status)));
352
+ const historyJobs = computed(() => jobs.value.filter((job) => !isActiveJobStatus(job.status)));
353
+ const deletableJobs = computed(() => historyJobs.value.filter((job) => job.can_delete));
354
+ const featuredJob = computed(() => activeJobs.value[0] ?? historyJobs.value[0] ?? null);
355
+ const completedCount = computed(() => jobs.value.filter((job) => job.status === "completed").length);
356
+ const { integrated, user, plugin, isAdmin } = usePlatform();
357
+ const isOwnJob = (job) => {
358
+ if (!integrated.value) return true;
359
+ if (user.value == null) return isAdmin.value;
360
+ return (job.owner_user_id ?? job.user_id) === String(user.value.id);
361
+ };
362
+ const ownActiveJobs = computed(() => activeJobs.value.filter(isOwnJob));
363
+ const justFinished = shallowRef(null);
364
+ const heldJob = computed(() => {
365
+ const held = justFinished.value;
366
+ return held ? jobs.value.find((job) => job.job_id === held.job_id) ?? null : null;
367
+ });
368
+ let finishedTimer;
369
+ watch([source, ownActiveJobs], ([currentSource, now], [previousSource, before]) => {
370
+ if (currentSource !== previousSource) {
371
+ justFinished.value = null;
372
+ return;
373
+ }
374
+ const nowIds = new Set(now.map((job) => job.job_id));
375
+ const left = new Set(before.filter((job) => !nowIds.has(job.job_id)).map((job) => job.job_id));
376
+ const finished = jobs.value.find((job) => left.has(job.job_id) && job.status === "completed");
377
+ if (!finished) return;
378
+ justFinished.value = finished;
379
+ clearTimeout(finishedTimer);
380
+ finishedTimer = setTimeout(() => {
381
+ justFinished.value = null;
382
+ }, FINISHED_HOLD_MS);
383
+ });
384
+ const seenFailedKey = `mint.jobs.${plugin.value?.id ?? "standalone"}.seen-failed`;
385
+ const storedSeenFailed = readSeenFailed(seenFailedKey);
386
+ const seenFailed = shallowRef(storedSeenFailed ?? /* @__PURE__ */ new Set());
387
+ const unseenFailedJobs = computed(() => historyJobs.value.filter((job) => job.status === "failed" && isOwnJob(job) && !seenFailed.value.has(job.job_id)));
388
+ function markFailedSeen() {
389
+ seenFailed.value = /* @__PURE__ */ new Set([...seenFailed.value, ...unseenFailedJobs.value.map((job) => job.job_id)]);
390
+ writeSeenFailed(seenFailedKey, seenFailed.value);
391
+ }
392
+ let hasBaseline = storedSeenFailed !== null;
393
+ let awaitingLoad = options.loadOnMount !== false && Boolean(source.value?.refresh);
394
+ function takeBaseline() {
395
+ if (hasBaseline || !active) return;
396
+ hasBaseline = true;
397
+ markFailedSeen();
398
+ }
399
+ watch(jobs, (list) => {
400
+ if (!awaitingLoad && list.length > 0) takeBaseline();
401
+ }, { immediate: true });
402
+ watch([isOpen, unseenFailedJobs], ([open, unseen]) => {
403
+ if (open && unseen.length > 0) markFailedSeen();
404
+ });
405
+ const topBarJob = computed(() => {
406
+ const own = ownActiveJobs.value;
407
+ const shown = own.find((job) => job.status === "awaiting_input") ?? own[0];
408
+ if (shown) return options.topBarJob?.(shown) ?? {
409
+ status: shown.status,
410
+ label: shown.progress.message || `${shown.name} ${jobStatusLabel(shown.status).toLowerCase()}`,
411
+ percent: shown.status === "running" ? normalizeJobPercent(shown.progress.percent) : null
412
+ };
413
+ const held = heldJob.value;
414
+ if (held) return options.topBarJob?.(held) ?? {
415
+ status: "completed",
416
+ label: `${held.name} completed`
417
+ };
418
+ const failed = unseenFailedJobs.value.length;
419
+ return failed > 0 ? {
420
+ status: "failed",
421
+ label: `${failed} failed`
422
+ } : null;
423
+ });
424
+ function rowView(job) {
425
+ const override = options.rowJob?.(job) ?? {};
426
+ const status = override.status ?? job.status;
427
+ const percent = override.percent !== void 0 ? override.percent : job.status === "running" ? job.progress.percent : null;
428
+ return {
429
+ status,
430
+ percent: percent == null ? null : Math.round(normalizeJobPercent(percent)),
431
+ message: override.message ?? jobMessage(job)
432
+ };
433
+ }
434
+ function handleTopBarClick(onSelect) {
435
+ const finished = heldJob.value;
436
+ if (!isOpen.value && ownActiveJobs.value.length === 0 && finished) onSelect(finished);
437
+ else isOpen.value = !isOpen.value;
438
+ }
439
+ const canRefresh = computed(() => Boolean(source.value?.refresh));
440
+ const canCancel = computed(() => Boolean(source.value?.cancel));
441
+ const canDelete = computed(() => Boolean(source.value?.delete));
442
+ const canClearFinished = computed(() => Boolean(source.value?.clear || source.value?.delete));
443
+ function setPending(jobId, pending) {
444
+ const next = new Set(pendingJobIds.value);
445
+ if (pending) next.add(jobId);
446
+ else next.delete(jobId);
447
+ pendingJobIds.value = next;
448
+ }
449
+ async function refresh() {
450
+ const listJobs = source.value?.refresh;
451
+ if (!listJobs) return false;
452
+ const generation = ++requestGeneration;
453
+ isLoading.value = true;
454
+ error.value = null;
455
+ try {
456
+ await listJobs();
457
+ return active && generation === requestGeneration;
458
+ } catch (cause) {
459
+ if (active && generation === requestGeneration) error.value = errorMessage(cause, "Failed to load jobs");
460
+ return false;
461
+ } finally {
462
+ if (active && generation === requestGeneration) isLoading.value = false;
463
+ }
464
+ }
465
+ async function cancelJob(job) {
466
+ const sourceCancel = source.value?.cancel;
467
+ if (!job.can_cancel || !sourceCancel || pendingJobIds.value.has(job.job_id)) return false;
468
+ setPending(job.job_id, true);
469
+ error.value = null;
470
+ try {
471
+ await sourceCancel(job.job_id);
472
+ return active;
473
+ } catch (cause) {
474
+ if (active) error.value = errorMessage(cause, "Failed to cancel job");
475
+ return false;
476
+ } finally {
477
+ if (active) setPending(job.job_id, false);
478
+ }
479
+ }
480
+ async function deleteJob(job) {
481
+ const sourceDelete = source.value?.delete;
482
+ if (!job.can_delete || !sourceDelete || pendingJobIds.value.has(job.job_id)) return false;
483
+ setPending(job.job_id, true);
484
+ error.value = null;
485
+ try {
486
+ const deleted = await sourceDelete(job.job_id);
487
+ return active && deleted !== false;
488
+ } catch (cause) {
489
+ if (active) error.value = errorMessage(cause, "Failed to delete job");
490
+ return false;
491
+ } finally {
492
+ if (active) setPending(job.job_id, false);
493
+ }
494
+ }
495
+ async function clearFinished() {
496
+ const targets = deletableJobs.value;
497
+ if (targets.length === 0) return false;
498
+ error.value = null;
499
+ try {
500
+ const currentSource = source.value;
501
+ if (currentSource?.clear) {
502
+ const deleted = await currentSource.clear();
503
+ if (!active) return false;
504
+ return typeof deleted !== "number" || deleted === targets.length;
505
+ }
506
+ if (!currentSource?.delete) return false;
507
+ return (await Promise.all(targets.map((job) => deleteJob(job)))).every(Boolean);
508
+ } catch (cause) {
509
+ if (active) error.value = errorMessage(cause, "Failed to clear jobs");
510
+ return false;
511
+ }
512
+ }
513
+ onMounted(() => {
514
+ if (options.loadOnMount === false) return;
515
+ refresh().then((loaded) => {
516
+ awaitingLoad = false;
517
+ if (loaded || jobs.value.length > 0) takeBaseline();
518
+ });
519
+ });
520
+ onUnmounted(() => {
521
+ active = false;
522
+ requestGeneration += 1;
523
+ clearTimeout(finishedTimer);
524
+ });
525
+ return {
526
+ source,
527
+ jobs,
528
+ activeJobs,
529
+ historyJobs,
530
+ deletableJobs,
531
+ featuredJob,
532
+ canRefresh,
533
+ canCancel,
534
+ canDelete,
535
+ canClearFinished,
536
+ panelId: `mint-jobs-tray-${useId()}`,
537
+ rowView,
538
+ topBarJob,
539
+ completedCount,
540
+ isOpen,
541
+ isLoading,
542
+ error,
543
+ pendingJobIds,
544
+ open: () => {
545
+ isOpen.value = true;
546
+ },
547
+ close: () => {
548
+ isOpen.value = false;
549
+ },
550
+ toggle: () => {
551
+ isOpen.value = !isOpen.value;
552
+ },
553
+ handleTopBarClick,
554
+ refresh,
555
+ cancelJob,
556
+ deleteJob,
557
+ clearFinished,
558
+ isPending: (job) => pendingJobIds.value.has(job.job_id)
559
+ };
560
+ }
561
+ //#endregion
235
562
  //#region src/composables/controlWorkspaceOptions.ts
236
563
  function mergeControlWorkspaceOptions(base, override) {
237
564
  return {
@@ -396,11 +723,18 @@ var WorkspaceControlsInternal_default = /* @__PURE__ */ defineComponent({
396
723
  //#region src/components/internal/WorkspaceShellInternal.vue
397
724
  var WorkspaceShellInternal_default = /* @__PURE__ */ defineComponent({
398
725
  __name: "WorkspaceShellInternal",
399
- props: { shell: {} },
726
+ props: {
727
+ shell: {},
728
+ job: {},
729
+ jobsDone: {},
730
+ jobsOpen: { type: Boolean },
731
+ jobsPanelId: {}
732
+ },
400
733
  emits: [
401
734
  "pill-select",
402
735
  "pill-option-select",
403
- "settings-values-change"
736
+ "settings-values-change",
737
+ "job-click"
404
738
  ],
405
739
  setup(__props, { emit: __emit }) {
406
740
  /**
@@ -429,9 +763,14 @@ var WorkspaceShellInternal_default = /* @__PURE__ */ defineComponent({
429
763
  subtitle: __props.shell.subtitle,
430
764
  spec: __props.shell.topBar,
431
765
  pill: __props.shell.pill,
432
- onPillSelect: _cache[0] || (_cache[0] = ($event) => emit("pill-select", $event)),
766
+ job: __props.job,
767
+ "jobs-done": __props.jobsDone,
768
+ "jobs-open": __props.jobsOpen,
769
+ "jobs-panel-id": __props.jobsPanelId,
770
+ onJobClick: _cache[0] || (_cache[0] = ($event) => emit("job-click")),
771
+ onPillSelect: _cache[1] || (_cache[1] = ($event) => emit("pill-select", $event)),
433
772
  onPillOptionSelect: handlePillOptionSelect,
434
- onSettingsValuesChange: _cache[1] || (_cache[1] = ($event) => emit("settings-values-change", $event))
773
+ onSettingsValuesChange: _cache[2] || (_cache[2] = ($event) => emit("settings-values-change", $event))
435
774
  }, createSlots({ _: 2 }, [renderList(__props.shell.topBarSlotNames, (slotName) => {
436
775
  return {
437
776
  name: slotName,
@@ -441,7 +780,11 @@ var WorkspaceShellInternal_default = /* @__PURE__ */ defineComponent({
441
780
  "title",
442
781
  "subtitle",
443
782
  "spec",
444
- "pill"
783
+ "pill",
784
+ "job",
785
+ "jobs-done",
786
+ "jobs-open",
787
+ "jobs-panel-id"
445
788
  ])) : createCommentVNode("", true)])]),
446
789
  default: withCtx(() => [renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(__props.shell.controls)))]),
447
790
  _: 2
@@ -551,7 +894,8 @@ var PluginWorkspaceView_default = /* @__PURE__ */ defineComponent({
551
894
  "update:toggle",
552
895
  "section-action",
553
896
  "form-submit",
554
- "form-cancel"
897
+ "form-cancel",
898
+ "job-select"
555
899
  ],
556
900
  setup(__props, { emit: __emit }) {
557
901
  /**
@@ -583,6 +927,11 @@ var PluginWorkspaceView_default = /* @__PURE__ */ defineComponent({
583
927
  saveDisabledMessage: computed(() => toValue(save?.reason))
584
928
  });
585
929
  }
930
+ const jobs = props.spec.jobs;
931
+ const jobCenter = jobs ? useJobCenter({ source: jobs }) : null;
932
+ function handleJobSelect(job) {
933
+ emit("job-select", job);
934
+ }
586
935
  const { shell, sidebar, controls, handleControlValuesUpdate, handlePillSelect } = usePluginWorkspace({
587
936
  props,
588
937
  slots,
@@ -600,14 +949,27 @@ var PluginWorkspaceView_default = /* @__PURE__ */ defineComponent({
600
949
  return (_ctx, _cache) => {
601
950
  return openBlock(), createBlock(WorkspaceShellInternal_default, {
602
951
  shell: unref(shell),
952
+ job: unref(jobCenter) ? unref(jobCenter).topBarJob.value : void 0,
953
+ "jobs-done": unref(jobCenter)?.completedCount.value,
954
+ "jobs-open": unref(jobCenter)?.isOpen.value,
955
+ "jobs-panel-id": unref(jobCenter)?.panelId,
956
+ onJobClick: _cache[2] || (_cache[2] = ($event) => unref(jobCenter)?.handleTopBarClick(handleJobSelect)),
603
957
  onPillSelect: unref(handlePillSelect),
604
- onPillOptionSelect: _cache[2] || (_cache[2] = (option, item) => emit("pill-option-select", option, item)),
605
- onSettingsValuesChange: _cache[3] || (_cache[3] = ($event) => emit("settings-values-change", $event))
958
+ onPillOptionSelect: _cache[3] || (_cache[3] = (option, item) => emit("pill-option-select", option, item)),
959
+ onSettingsValuesChange: _cache[4] || (_cache[4] = ($event) => emit("settings-values-change", $event))
606
960
  }, createSlots({
607
- default: withCtx(() => [createVNode(WorkspaceControlsInternal_default, { controls: unref(controls) }, {
608
- default: withCtx((controlsScope) => [renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(controlsScope)))]),
609
- _: 3
610
- }, 8, ["controls"]), __props.spec.toasts !== false ? (openBlock(), createBlock(AppToastContainer_default, { key: 0 })) : createCommentVNode("", true)]),
961
+ default: withCtx(() => [
962
+ createVNode(WorkspaceControlsInternal_default, { controls: unref(controls) }, {
963
+ default: withCtx((controlsScope) => [renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(controlsScope)))]),
964
+ _: 3
965
+ }, 8, ["controls"]),
966
+ __props.spec.toasts !== false ? (openBlock(), createBlock(AppToastContainer_default, { key: 0 })) : createCommentVNode("", true),
967
+ unref(jobCenter) ? (openBlock(), createBlock(JobsStatusTray_default, {
968
+ key: 1,
969
+ center: unref(jobCenter),
970
+ onSelect: handleJobSelect
971
+ }, null, 8, ["center"])) : createCommentVNode("", true)
972
+ ]),
611
973
  _: 2
612
974
  }, [
613
975
  unref(slots).topbar ? {
@@ -639,7 +1001,14 @@ var PluginWorkspaceView_default = /* @__PURE__ */ defineComponent({
639
1001
  })]), 1032, ["sidebar", "onUpdate:values"])])]),
640
1002
  key: "1"
641
1003
  } : void 0
642
- ]), 1032, ["shell", "onPillSelect"]);
1004
+ ]), 1032, [
1005
+ "shell",
1006
+ "job",
1007
+ "jobs-done",
1008
+ "jobs-open",
1009
+ "jobs-panel-id",
1010
+ "onPillSelect"
1011
+ ]);
643
1012
  };
644
1013
  }
645
1014
  });
@@ -671,26 +1040,14 @@ var Avatar_default = /* @__PURE__ */ defineComponent({
671
1040
  status: {}
672
1041
  },
673
1042
  setup(__props) {
674
- /** Displays a user avatar as an image, a single derived initial, or a fallback icon, with a deterministic background color and optional status dot. */
1043
+ /** Displays a user avatar as an image, a single derived initial, or a fallback icon, on a quiet accent face (or an explicit `color`) with an optional status dot. */
675
1044
  const props = __props;
676
- const PALETTE = [
677
- "#3B82F6",
678
- "#8B5CF6",
679
- "#EC4899",
680
- "#F97316",
681
- "#10B981",
682
- "#F59E0B",
683
- "#06B6D4",
684
- "#6366F1"
685
- ];
686
1045
  const computedInitials = computed(() => props.initials || props.name?.charAt(0).toUpperCase() || "");
687
- const backgroundColor = computed(() => {
688
- if (props.color) return props.color;
689
- if (!props.name) return void 0;
690
- let hash = 0;
691
- for (let i = 0; i < props.name.length; i++) hash = props.name.charCodeAt(i) + ((hash << 5) - hash);
692
- return PALETTE[Math.abs(hash) % PALETTE.length];
693
- });
1046
+ const faceStyle = computed(() => props.color ? {
1047
+ backgroundColor: props.color,
1048
+ color: "#fff",
1049
+ boxShadow: "none"
1050
+ } : void 0);
694
1051
  return (_ctx, _cache) => {
695
1052
  return openBlock(), createElementBlock("span", {
696
1053
  class: normalizeClass(["mint-avatar", `mint-avatar--${__props.size}`]),
@@ -698,7 +1055,7 @@ var Avatar_default = /* @__PURE__ */ defineComponent({
698
1055
  "aria-label": __props.alt || __props.name || "User avatar"
699
1056
  }, [createElementVNode("span", {
700
1057
  class: "mint-avatar__face",
701
- style: normalizeStyle(backgroundColor.value ? { backgroundColor: backgroundColor.value } : void 0)
1058
+ style: normalizeStyle(faceStyle.value)
702
1059
  }, [__props.src ? (openBlock(), createElementBlock("img", {
703
1060
  key: 0,
704
1061
  src: __props.src,
@@ -902,7 +1259,7 @@ var GeneratedPluginView_default = /*#__PURE__*/ _plugin_vue_export_helper_defaul
902
1259
  const forms = computed(() => Object.fromEntries(definitions.value.map((definition) => [definition.id, generatedJobFormSchema(definition)])));
903
1260
  const workspace = computed(() => definePluginWorkspaceView({
904
1261
  title: generated.manifest.value?.ui.title ?? "Analysis",
905
- subtitle: generated.manifest.value?.ui.description,
1262
+ subtitle: generated.manifest.value?.ui.subtitle || generated.manifest.value?.ui.description,
906
1263
  toasts: false,
907
1264
  topBar: {
908
1265
  pills: pillNav.value,
@@ -913,8 +1270,17 @@ var GeneratedPluginView_default = /*#__PURE__*/ _plugin_vue_export_helper_defaul
913
1270
  title: "Parameters",
914
1271
  panels: panels.value,
915
1272
  forms: forms.value
916
- }
1273
+ },
1274
+ jobs: generated
917
1275
  }));
1276
+ watch(() => generated.manifest.value?.ui, (ui) => {
1277
+ if (ui) providePluginIdentity({ plugin: {
1278
+ name: ui.title,
1279
+ subtitle: ui.subtitle,
1280
+ description: ui.description,
1281
+ icon: ui.icon
1282
+ } });
1283
+ }, { immediate: true });
918
1284
  const currentValues = computed(() => valuesByDefinition[activeDefinitionId.value] ?? {});
919
1285
  const currentJob = computed(() => {
920
1286
  const currentSessionId = generated.session.value?.id;
@@ -960,7 +1326,8 @@ var GeneratedPluginView_default = /*#__PURE__*/ _plugin_vue_export_helper_defaul
960
1326
  "form-loading": unref(generated).isSubmitting.value,
961
1327
  "form-disabled": unref(generated).isSubmitting.value,
962
1328
  "onUpdate:values": updateValues,
963
- onFormSubmit: submitJob
1329
+ onFormSubmit: submitJob,
1330
+ onJobSelect: selectJob
964
1331
  }, {
965
1332
  default: withCtx(() => [createElementVNode("main", _hoisted_1$3, [unref(generated).isLoading.value ? (openBlock(), createElementBlock("div", _hoisted_2$2, [createVNode(LoadingSpinner_default, { size: "lg" }), _cache[1] || (_cache[1] = createElementVNode("span", null, "Loading analysis workspace", -1))])) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
966
1333
  unref(generated).error.value ? (openBlock(), createBlock(AlertBox_default, {
@@ -984,11 +1351,7 @@ var GeneratedPluginView_default = /*#__PURE__*/ _plugin_vue_export_helper_defaul
984
1351
  description: "Set the parameters and run the analysis. Jobs continue independently if you switch tabs.",
985
1352
  size: "md"
986
1353
  }))])
987
- ], 64)), createVNode(JobsStatusTray_default, {
988
- source: unref(generated),
989
- "teleport-to": false,
990
- onSelect: selectJob
991
- }, null, 8, ["source"])])]),
1354
+ ], 64))])]),
992
1355
  _: 1
993
1356
  }, 8, [
994
1357
  "view",
@@ -999,7 +1362,7 @@ var GeneratedPluginView_default = /*#__PURE__*/ _plugin_vue_export_helper_defaul
999
1362
  ]);
1000
1363
  };
1001
1364
  }
1002
- }), [["__scopeId", "data-v-b2adc285"]]);
1365
+ }), [["__scopeId", "data-v-c8ff991b"]]);
1003
1366
  //#endregion
1004
1367
  //#region src/components/internal/PlateEditorBindingInternal.vue
1005
1368
  var PlateEditorBindingInternal_default = /* @__PURE__ */ defineComponent({
@@ -1213,7 +1576,7 @@ var RuntimeUpdateNotice_default = /*#__PURE__*/ _plugin_vue_export_helper_defaul
1213
1576
  ])) : createCommentVNode("", true);
1214
1577
  };
1215
1578
  }
1216
- }), [["__scopeId", "data-v-9ca77e18"]]);
1579
+ }), [["__scopeId", "data-v-abbf8f18"]]);
1217
1580
  //#endregion
1218
1581
  //#region src/composables/usePresence.ts
1219
1582
  /**
@@ -1490,6 +1853,6 @@ var runtime_exports = /* @__PURE__ */ __exportAll({
1490
1853
  useSettingsEndpoint: () => useSettingsEndpoint
1491
1854
  });
1492
1855
  //#endregion
1493
- export { ComponentBindingRenderer_default as a, generatedJobFormSchema as c, PluginWorkspaceView_default as d, useControlWorkspace as f, RuntimeUpdateNotice_default as i, normalizeGeneratedJobInput as l, useToast as m, PresenceAvatars_default as n, GeneratedPluginView_default as o, AppToastContainer_default as p, usePresence as r, generatedJobDefaults as s, runtime_exports as t, Avatar_default as u };
1856
+ export { ComponentBindingRenderer_default as a, generatedJobFormSchema as c, PluginWorkspaceView_default as d, useControlWorkspace as f, useToast as g, AppToastContainer_default as h, RuntimeUpdateNotice_default as i, normalizeGeneratedJobInput as l, useJobCenter as m, PresenceAvatars_default as n, GeneratedPluginView_default as o, combinePluginJobSources as p, usePresence as r, generatedJobDefaults as s, runtime_exports as t, Avatar_default as u };
1494
1857
 
1495
- //# sourceMappingURL=runtime-D6gVat6r.js.map
1858
+ //# sourceMappingURL=runtime-q-R0CNLh.js.map