@morscherlab/mint-sdk 1.2.0-beta.7 → 1.2.0-beta.9

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 (307) hide show
  1. package/README.md +30 -0
  2. package/dist/{ExperimentPopover-CfOdh5Rm.js → ExperimentPopover-oL0fg_A0.js} +5 -3
  3. package/dist/ExperimentPopover-oL0fg_A0.js.map +1 -0
  4. package/dist/{ExperimentSelectorModal-DvIagrxY.js → ExperimentSelectorModal-BeEOomw_.js} +4 -4
  5. package/dist/ExperimentSelectorModal-BeEOomw_.js.map +1 -0
  6. package/dist/{SettingsModal-W3TYfnP9.js → SettingsModal-Dphh3RrI.js} +4 -4
  7. package/dist/SettingsModal-Dphh3RrI.js.map +1 -0
  8. package/dist/{EmptyState-NBqf2_8z.js → Skeleton-DxtwJ5gt.js} +110 -92
  9. package/dist/Skeleton-DxtwJ5gt.js.map +1 -0
  10. package/dist/__tests__/components/ExperimentTimeline.test.d.ts +1 -0
  11. package/dist/__tests__/composables/useListReorder.test.d.ts +1 -0
  12. package/dist/__tests__/styles/cssTokens.test.d.ts +1 -0
  13. package/dist/components/ActionMenu.vue.d.ts +1 -1
  14. package/dist/components/AppPluginSwitcher.vue.d.ts +2 -0
  15. package/dist/components/AuditTrail.vue.d.ts +13 -0
  16. package/dist/components/BatchProgressList.vue.d.ts +17 -0
  17. package/dist/components/DataFrame.vue.d.ts +14 -2
  18. package/dist/components/DatePicker.vue.d.ts +1 -1
  19. package/dist/components/DateTimePicker.vue.d.ts +2 -0
  20. package/dist/components/ExperimentDataViewer.vue.d.ts +26 -1
  21. package/dist/components/ExperimentPopover.vue.d.ts +1 -0
  22. package/dist/components/ExperimentTimeline.vue.d.ts +29 -1
  23. package/dist/components/LcmsSequenceTable.vue.d.ts +29 -1
  24. package/dist/components/ProgressBar.vue.d.ts +1 -1
  25. package/dist/components/ProtocolStepEditor.vue.d.ts +1 -0
  26. package/dist/components/ReagentList.vue.d.ts +29 -1
  27. package/dist/components/SampleHierarchyTree.vue.d.ts +29 -1
  28. package/dist/components/SampleSelector.drag.d.ts +13 -0
  29. package/dist/components/SampleSelector.tree.d.ts +2 -0
  30. package/dist/components/SampleSelector.vue.d.ts +34 -1
  31. package/dist/components/ScheduleCalendar.vue.d.ts +20 -0
  32. package/dist/components/SmartGroupFieldRecipe.vue.d.ts +1 -0
  33. package/dist/components/TimePicker.vue.d.ts +1 -0
  34. package/dist/components/WellPlate.geometry.d.ts +15 -0
  35. package/dist/components/WellPlate.interaction.d.ts +13 -0
  36. package/dist/components/WellPlate.vue.d.ts +29 -0
  37. package/dist/components/index.js +6 -6
  38. package/dist/components/internal/AppTopBarPageSelectorInternal.vue.d.ts +2 -0
  39. package/dist/components/internal/DataStateInternal.vue.d.ts +43 -0
  40. package/dist/{components-B80gV0P6.js → components-CgAUzF8F.js} +1930 -1688
  41. package/dist/components-CgAUzF8F.js.map +1 -0
  42. package/dist/composables/controlSchemaTypes.d.ts +34 -0
  43. package/dist/composables/index.d.ts +1 -0
  44. package/dist/composables/index.js +9 -9
  45. package/dist/composables/useDropdownState.d.ts +18 -2
  46. package/dist/composables/useEventStream.d.ts +9 -0
  47. package/dist/composables/useListReorder.d.ts +90 -0
  48. package/dist/composables/useMenuKeyboard.d.ts +2 -2
  49. package/dist/composables/usePluginConfig.d.ts +3 -1
  50. package/dist/composables/useRequestSyncState.d.ts +42 -2
  51. package/dist/composables/useScheduleDrag.d.ts +1 -0
  52. package/dist/{composables-C8mmD5ta.js → composables-B_pia3hO.js} +13 -69
  53. package/dist/composables-B_pia3hO.js.map +1 -0
  54. package/dist/{useApi-CDBq6z23.js → errors-_W0-LbA6.js} +102 -3
  55. package/dist/errors-_W0-LbA6.js.map +1 -0
  56. package/dist/{experiment-Y9Iz7KYi.js → experiment-Cwl9AYxw.js} +3 -8
  57. package/dist/experiment-Cwl9AYxw.js.map +1 -0
  58. package/dist/experiment-utils-DV3DrvE_.js.map +1 -1
  59. package/dist/index.js +14 -14
  60. package/dist/install.js +2 -7
  61. package/dist/install.js.map +1 -1
  62. package/dist/permissions.d.ts +42 -1
  63. package/dist/permissions.js +20 -10
  64. package/dist/permissions.js.map +1 -1
  65. package/dist/stores/index.d.ts +1 -1
  66. package/dist/stores/index.js +3 -3
  67. package/dist/stores/settings.d.ts +31 -1
  68. package/dist/styles.css +9572 -27877
  69. package/dist/templates/index.js +2 -4
  70. package/dist/{templates-CK72aKO1.js → templates-Qq113pyZ.js} +291 -85
  71. package/dist/templates-Qq113pyZ.js.map +1 -0
  72. package/dist/{useControlSchema-_OVhavKq.js → useControlSchema-aMZlb4Sc.js} +197 -1089
  73. package/dist/useControlSchema-aMZlb4Sc.js.map +1 -0
  74. package/dist/{useDropdownState-D5G4UvWd.js → useDropdownState-DitCtrTT.js} +21 -5
  75. package/dist/useDropdownState-DitCtrTT.js.map +1 -0
  76. package/dist/{useExperimentSelector-DSEckf_g.js → useExperimentSelector-I8HC8hUu.js} +3 -3
  77. package/dist/{useExperimentSelector-DSEckf_g.js.map → useExperimentSelector-I8HC8hUu.js.map} +1 -1
  78. package/dist/{useFormBuilder-Bd714C7y.js → useFormBuilder-TCxNnqeb.js} +2 -2
  79. package/dist/{useFormBuilder-Bd714C7y.js.map → useFormBuilder-TCxNnqeb.js.map} +1 -1
  80. package/dist/{useProtocolTemplates-Dq5Pzwyd.js → useProtocolTemplates-BmX_iVBR.js} +185 -157
  81. package/dist/useProtocolTemplates-BmX_iVBR.js.map +1 -0
  82. package/dist/utils/color.d.ts +13 -0
  83. package/dist/utils/errors.d.ts +9 -0
  84. package/package.json +1 -1
  85. package/src/__tests__/components/ActionMenu.test.ts +94 -0
  86. package/src/__tests__/components/DataFrame.test.ts +183 -11
  87. package/src/__tests__/components/DataStates.test.ts +176 -0
  88. package/src/__tests__/components/DatePicker.test.ts +76 -0
  89. package/src/__tests__/components/DateTimePicker.test.ts +36 -0
  90. package/src/__tests__/components/ExperimentTimeline.test.ts +63 -0
  91. package/src/__tests__/components/GroupAssigner.test.ts +53 -0
  92. package/src/__tests__/components/LcmsSequenceTable.test.ts +22 -0
  93. package/src/__tests__/components/RackEditor.test.ts +35 -0
  94. package/src/__tests__/components/ReagentList.test.ts +64 -2
  95. package/src/__tests__/components/RetiredStyles.test.ts +31 -0
  96. package/src/__tests__/components/SampleSelector.drag.test.ts +51 -1
  97. package/src/__tests__/components/ScheduleCalendar.test.ts +63 -0
  98. package/src/__tests__/components/SegmentedControl.test.ts +88 -0
  99. package/src/__tests__/components/TimePicker.test.ts +61 -0
  100. package/src/__tests__/components/WellPlate.interaction.test.ts +59 -0
  101. package/src/__tests__/composables/useDropdownState.test.ts +58 -1
  102. package/src/__tests__/composables/useListReorder.test.ts +145 -0
  103. package/src/__tests__/composables/useRequestSyncState.test.ts +140 -0
  104. package/src/__tests__/stores/settings.test.ts +71 -1
  105. package/src/__tests__/styles/cssTokens.test.ts +131 -0
  106. package/src/__tests__/utils/permissions.test.ts +68 -0
  107. package/src/components/ActionMenu.vue +45 -88
  108. package/src/components/AlertBox.vue +0 -4
  109. package/src/components/AppAvatarMenu.vue +2 -14
  110. package/src/components/AppLayout.vue +0 -4
  111. package/src/components/AppPluginSwitcher.story.vue +87 -0
  112. package/src/components/AppPluginSwitcher.vue +2 -5
  113. package/src/components/AppSidebar.vue +0 -4
  114. package/src/components/AppToastContainer.vue +6 -8
  115. package/src/components/AppTopBar.vue +0 -4
  116. package/src/components/ArtifactSaveDialog.vue +0 -4
  117. package/src/components/ArtifactSelectorModal.vue +0 -4
  118. package/src/components/AuditTrail.story.vue +18 -0
  119. package/src/components/AuditTrail.vue +27 -7
  120. package/src/components/AutoGroupModal.vue +0 -4
  121. package/src/components/Avatar.vue +0 -4
  122. package/src/components/BaseButton.vue +0 -4
  123. package/src/components/BaseCheckbox.vue +0 -4
  124. package/src/components/BaseInput.vue +0 -4
  125. package/src/components/BaseModal.vue +0 -4
  126. package/src/components/BasePill.vue +0 -4
  127. package/src/components/BaseRadioGroup.vue +0 -4
  128. package/src/components/BaseSelect.vue +0 -4
  129. package/src/components/BaseSlider.vue +0 -4
  130. package/src/components/BaseTabs.vue +0 -4
  131. package/src/components/BaseTextarea.vue +0 -4
  132. package/src/components/BaseToggle.vue +0 -4
  133. package/src/components/BatchProgressList.story.vue +18 -0
  134. package/src/components/BatchProgressList.vue +32 -4
  135. package/src/components/Breadcrumb.vue +0 -4
  136. package/src/components/Calendar.vue +0 -4
  137. package/src/components/ChartContainer.story.vue +1 -1
  138. package/src/components/ChartContainer.vue +0 -4
  139. package/src/components/ChemicalFormula.vue +0 -4
  140. package/src/components/CollapsibleCard.vue +0 -4
  141. package/src/components/ColorSlider.vue +0 -4
  142. package/src/components/ConcentrationInput.vue +0 -4
  143. package/src/components/ConfirmDialog.vue +0 -4
  144. package/src/components/DataFrame.story.vue +14 -0
  145. package/src/components/DataFrame.vue +97 -23
  146. package/src/components/DatePicker.vue +73 -27
  147. package/src/components/DateTimePicker.vue +45 -17
  148. package/src/components/Divider.vue +0 -4
  149. package/src/components/DoseCalculator.vue +0 -4
  150. package/src/components/DropdownButton.vue +2 -14
  151. package/src/components/EmptyState.vue +0 -4
  152. package/src/components/ExperimentCodeBadge.vue +0 -4
  153. package/src/components/ExperimentDataViewer.story.vue +3 -0
  154. package/src/components/ExperimentDataViewer.vue +33 -13
  155. package/src/components/ExperimentPopover.vue +2 -5
  156. package/src/components/ExperimentSelectorModal.vue +0 -4
  157. package/src/components/ExperimentTimeline.story.vue +18 -0
  158. package/src/components/ExperimentTimeline.vue +81 -75
  159. package/src/components/FileUploader.vue +0 -4
  160. package/src/components/FitPanel.vue +0 -4
  161. package/src/components/FormActions.story.vue +96 -0
  162. package/src/components/FormActions.vue +0 -4
  163. package/src/components/FormBuilder.vue +0 -4
  164. package/src/components/FormField.vue +0 -4
  165. package/src/components/FormulaInput.vue +0 -4
  166. package/src/components/GeneratedPathInput.story.vue +68 -0
  167. package/src/components/GeneratedPlotlyResult.story.vue +96 -0
  168. package/src/components/GeneratedPlotlyResult.vue +3 -3
  169. package/src/components/GeneratedPluginView.story.vue +145 -0
  170. package/src/components/GeneratedPluginView.vue +10 -10
  171. package/src/components/GeneratedResultRenderer.story.vue +117 -0
  172. package/src/components/GeneratedResultRenderer.vue +4 -4
  173. package/src/components/GroupAssigner.vue +67 -5
  174. package/src/components/IconButton.vue +0 -4
  175. package/src/components/InstrumentAlertLog.vue +0 -4
  176. package/src/components/InstrumentStateBadge.vue +0 -4
  177. package/src/components/InstrumentStatusCard.vue +0 -4
  178. package/src/components/JobsStatusTray.vue +0 -4
  179. package/src/components/LcmsSequenceTable.vue +81 -50
  180. package/src/components/LoadingSpinner.vue +0 -4
  181. package/src/components/MobileSupportGate.vue +0 -4
  182. package/src/components/MoleculeInput.vue +0 -4
  183. package/src/components/MultiSelect.vue +0 -4
  184. package/src/components/NumberInput.vue +0 -4
  185. package/src/components/PlateMapEditor.vue +3 -14
  186. package/src/components/PluginIcon.vue +0 -4
  187. package/src/components/ProgressBar.vue +0 -4
  188. package/src/components/ProtocolStepEditor.vue +2 -4
  189. package/src/components/RackEditor.vue +51 -70
  190. package/src/components/ReagentEditor.vue +0 -4
  191. package/src/components/ReagentList.story.vue +18 -0
  192. package/src/components/ReagentList.vue +127 -82
  193. package/src/components/ResourceCard.vue +0 -4
  194. package/src/components/RuntimeUpdateNotice.story.vue +49 -0
  195. package/src/components/RuntimeUpdateNotice.vue +4 -4
  196. package/src/components/SampleHierarchyTree.story.vue +18 -0
  197. package/src/components/SampleHierarchyTree.vue +32 -9
  198. package/src/components/SampleLegend.vue +2 -8
  199. package/src/components/SampleSelector.drag.ts +51 -0
  200. package/src/components/SampleSelector.story.vue +6 -0
  201. package/src/components/SampleSelector.tree.ts +2 -0
  202. package/src/components/SampleSelector.vue +49 -10
  203. package/src/components/SampleSelectorGroupNode.vue +19 -0
  204. package/src/components/ScheduleCalendar.story.vue +6 -0
  205. package/src/components/ScheduleCalendar.vue +82 -7
  206. package/src/components/ScientificNumber.vue +0 -4
  207. package/src/components/SectionCard.vue +0 -4
  208. package/src/components/SegmentedControl.vue +48 -5
  209. package/src/components/SequenceInput.vue +0 -4
  210. package/src/components/SequenceProgressBar.story.vue +110 -0
  211. package/src/components/SequenceProgressBar.vue +0 -4
  212. package/src/components/SettingsModal.vue +0 -4
  213. package/src/components/Skeleton.vue +0 -4
  214. package/src/components/SmartGroupFieldRecipe.vue +8 -6
  215. package/src/components/SmartGroupManual.vue +0 -4
  216. package/src/components/StatusIndicator.vue +0 -4
  217. package/src/components/StepWizard.vue +0 -4
  218. package/src/components/TagsInput.vue +4 -6
  219. package/src/components/ThemeToggle.vue +0 -4
  220. package/src/components/TimePicker.vue +36 -7
  221. package/src/components/TimeRangeInput.vue +0 -4
  222. package/src/components/Tooltip.story.vue +3 -3
  223. package/src/components/Tooltip.vue +0 -4
  224. package/src/components/UnitInput.vue +0 -4
  225. package/src/components/WellPlate.geometry.ts +60 -1
  226. package/src/components/WellPlate.interaction.ts +44 -0
  227. package/src/components/WellPlate.story.vue +8 -0
  228. package/src/components/WellPlate.vue +53 -7
  229. package/src/components/internal/AppTopBarPageSelectorInternal.vue +2 -5
  230. package/src/components/internal/AppTopBarPillNavInternal.vue +0 -4
  231. package/src/components/internal/DataStateInternal.vue +74 -0
  232. package/src/components/internal/FormSectionRenderer.vue +0 -4
  233. package/src/components/internal/WellEditPopupInternal.vue +0 -4
  234. package/src/composables/controlSchemaTypes.ts +34 -0
  235. package/src/composables/index.ts +10 -0
  236. package/src/composables/useDropdownState.ts +35 -5
  237. package/src/composables/useEventStream.ts +14 -2
  238. package/src/composables/useFileImport.ts +2 -7
  239. package/src/composables/useGeneratedAnalysis.ts +8 -9
  240. package/src/composables/useListReorder.story.vue +143 -0
  241. package/src/composables/useListReorder.ts +242 -0
  242. package/src/composables/useMenuKeyboard.ts +2 -2
  243. package/src/composables/useOptimisticMutation.ts +1 -15
  244. package/src/composables/usePluginConfig.ts +3 -1
  245. package/src/composables/useRackEditor.ts +2 -11
  246. package/src/composables/useRequestSyncState.ts +98 -28
  247. package/src/composables/useResourceCrud.ts +1 -15
  248. package/src/composables/useScheduleDrag.ts +37 -0
  249. package/src/composables/useWellPainting.ts +5 -29
  250. package/src/composables/useWellPlateEditor.ts +1 -11
  251. package/src/permissions.ts +48 -9
  252. package/src/stores/experiment.ts +2 -7
  253. package/src/stores/index.ts +9 -1
  254. package/src/stores/settings.ts +93 -1
  255. package/src/styles/components/audit-trail.css +5 -5
  256. package/src/styles/components/batch-progress-list.css +7 -0
  257. package/src/styles/components/color-slider.css +2 -2
  258. package/src/styles/components/data-state.css +30 -0
  259. package/src/styles/components/dataframe.css +29 -35
  260. package/src/styles/components/experiment-data-viewer.css +4 -4
  261. package/src/styles/components/experiment-timeline.css +3 -30
  262. package/src/styles/components/form-builder.css +5 -5
  263. package/src/styles/components/lcms-sequence-table.css +16 -1
  264. package/src/styles/components/multi-select.css +1 -1
  265. package/src/styles/components/reagent-list.css +38 -31
  266. package/src/styles/components/sample-hierarchy-tree.css +5 -19
  267. package/src/styles/components/sample-selector.css +9 -2
  268. package/src/styles/components/schedule-calendar.css +8 -0
  269. package/src/styles/components/scientific-number.css +1 -1
  270. package/src/styles/components/well-plate.css +8 -0
  271. package/src/styles/index.css +8 -0
  272. package/src/styles/variables.css +29 -0
  273. package/src/templates/builderPresetControls.ts +1 -1
  274. package/src/templates/componentPlateHelpers.ts +3 -1
  275. package/src/templates/doseResponseAdapters.ts +2 -13
  276. package/src/templates/elisaAssayCollectionBuilder.ts +2 -2
  277. package/src/templates/plateMapBuilder.ts +2 -2
  278. package/src/templates/qpcrPlateBuilder.ts +1 -1
  279. package/src/templates/templateValidators.ts +1 -1
  280. package/src/templates/timeCourseBuilder.ts +2 -2
  281. package/src/templates/wellPlateScreenCollectionBuilder.ts +2 -2
  282. package/src/utils/color.ts +51 -0
  283. package/src/utils/errors.ts +29 -0
  284. package/dist/EmptyState-NBqf2_8z.js.map +0 -1
  285. package/dist/ExperimentPopover-CfOdh5Rm.js.map +0 -1
  286. package/dist/ExperimentSelectorModal-DvIagrxY.js.map +0 -1
  287. package/dist/SettingsModal-W3TYfnP9.js.map +0 -1
  288. package/dist/components-B80gV0P6.js.map +0 -1
  289. package/dist/composables/autoGroupConstants.d.ts +0 -1
  290. package/dist/composables/autoGroupGrouping.d.ts +0 -3
  291. package/dist/composables/useAutoGroupInputSources.d.ts +0 -32
  292. package/dist/composables-C8mmD5ta.js.map +0 -1
  293. package/dist/experiment-Y9Iz7KYi.js.map +0 -1
  294. package/dist/templates/builderDefaults.d.ts +0 -1
  295. package/dist/templates/plateGeometry.d.ts +0 -4
  296. package/dist/templates-CK72aKO1.js.map +0 -1
  297. package/dist/useApi-CDBq6z23.js.map +0 -1
  298. package/dist/useControlSchema-_OVhavKq.js.map +0 -1
  299. package/dist/useDropdownState-D5G4UvWd.js.map +0 -1
  300. package/dist/useProtocolTemplates-Dq5Pzwyd.js.map +0 -1
  301. package/src/__tests__/composables/useAutoGroupInputSources.test.ts +0 -127
  302. package/src/composables/autoGroupConstants.ts +0 -4
  303. package/src/composables/autoGroupGrouping.ts +0 -148
  304. package/src/composables/useAutoGroupInputSources.ts +0 -147
  305. package/src/templates/builderDefaults.ts +0 -11
  306. package/src/templates/plateGeometry.ts +0 -62
  307. /package/dist/__tests__/{composables/useAutoGroupInputSources.test.d.ts → components/DataStates.test.d.ts} +0 -0
@@ -0,0 +1,96 @@
1
+ <script setup lang="ts">
2
+ import FormActions from './FormActions.vue'
3
+
4
+ function log(event: string) {
5
+ return () => console.log(event)
6
+ }
7
+
8
+ function initState() {
9
+ return {
10
+ isWizard: false,
11
+ isFirst: true,
12
+ isLast: true,
13
+ canProceed: true,
14
+ loading: false,
15
+ disabled: false,
16
+ showCancel: true,
17
+ submitLabel: 'Submit',
18
+ cancelLabel: 'Cancel',
19
+ }
20
+ }
21
+ </script>
22
+
23
+ <template>
24
+ <Story title="Forms/FormActions">
25
+ <Variant title="Playground" :init-state="initState">
26
+ <template #default="{ state }">
27
+ <div style="padding: 2rem; max-width: 600px;">
28
+ <FormActions
29
+ :is-wizard="state.isWizard"
30
+ :is-first="state.isFirst"
31
+ :is-last="state.isLast"
32
+ :can-proceed="state.canProceed"
33
+ :loading="state.loading"
34
+ :disabled="state.disabled"
35
+ :show-cancel="state.showCancel"
36
+ :submit-label="state.submitLabel"
37
+ :cancel-label="state.cancelLabel"
38
+ @submit="log('submit')()"
39
+ @cancel="log('cancel')()"
40
+ @back="log('back')()"
41
+ @next="log('next')()"
42
+ />
43
+ </div>
44
+ </template>
45
+
46
+ <template #controls="{ state }">
47
+ <HstCheckbox v-model="state.isWizard" title="Wizard mode" />
48
+ <HstCheckbox v-model="state.isFirst" title="First step" />
49
+ <HstCheckbox v-model="state.isLast" title="Last step" />
50
+ <HstCheckbox v-model="state.canProceed" title="Can proceed" />
51
+ <HstCheckbox v-model="state.loading" title="Loading" />
52
+ <HstCheckbox v-model="state.disabled" title="Disabled" />
53
+ <HstCheckbox v-model="state.showCancel" title="Show cancel" />
54
+ <HstText v-model="state.submitLabel" title="Submit label" />
55
+ <HstText v-model="state.cancelLabel" title="Cancel label" />
56
+ </template>
57
+ </Variant>
58
+
59
+ <Variant title="Flat form">
60
+ <div style="padding: 2rem; max-width: 600px;">
61
+ <FormActions show-cancel submit-label="Save design" />
62
+ </div>
63
+ </Variant>
64
+
65
+ <Variant title="Wizard — first step">
66
+ <!-- Back is hidden on the first step; Next gates on `canProceed`. -->
67
+ <div style="padding: 2rem; max-width: 600px;">
68
+ <FormActions is-wizard :is-first="true" :is-last="false" />
69
+ </div>
70
+ </Variant>
71
+
72
+ <Variant title="Wizard — middle step">
73
+ <div style="padding: 2rem; max-width: 600px;">
74
+ <FormActions is-wizard :is-first="false" :is-last="false" />
75
+ </div>
76
+ </Variant>
77
+
78
+ <Variant title="Wizard — last step">
79
+ <div style="padding: 2rem; max-width: 600px;">
80
+ <FormActions is-wizard :is-first="false" :is-last="true" submit-label="Create experiment" />
81
+ </div>
82
+ </Variant>
83
+
84
+ <Variant title="Blocked by validation">
85
+ <div style="padding: 2rem; max-width: 600px;">
86
+ <FormActions is-wizard :is-first="false" :is-last="false" :can-proceed="false" />
87
+ </div>
88
+ </Variant>
89
+
90
+ <Variant title="Loading">
91
+ <div style="padding: 2rem; max-width: 600px;">
92
+ <FormActions show-cancel loading submit-label="Saving…" />
93
+ </div>
94
+ </Variant>
95
+ </Story>
96
+ </template>
@@ -86,7 +86,3 @@ const emit = defineEmits<{
86
86
  </BaseButton>
87
87
  </div>
88
88
  </template>
89
-
90
- <style>
91
- @import '../styles/components/form-builder.css';
92
- </style>
@@ -305,7 +305,3 @@ defineExpose({
305
305
  </template>
306
306
  </div>
307
307
  </template>
308
-
309
- <style>
310
- @import '../styles/components/form-builder.css';
311
- </style>
@@ -53,7 +53,3 @@ const describedBy = computed(() => errorId.value ?? hintId.value)
53
53
  </p>
54
54
  </div>
55
55
  </template>
56
-
57
- <style>
58
- @import '../styles/components/form-field.css';
59
- </style>
@@ -119,7 +119,3 @@ function handleInput(event: Event) {
119
119
  </div>
120
120
  </div>
121
121
  </template>
122
-
123
- <style>
124
- @import '../styles/components/formula-input.css';
125
- </style>
@@ -0,0 +1,68 @@
1
+ <script setup lang="ts">
2
+ import { ref } from 'vue'
3
+ import GeneratedPathInput from './GeneratedPathInput.vue'
4
+ import type { PluginJobPathInput } from '../types/generated-ui'
5
+
6
+ const single = ref<PluginJobPathInput | PluginJobPathInput[] | null>(null)
7
+ const multiple = ref<PluginJobPathInput | PluginJobPathInput[] | null>([])
8
+
9
+ function describe(value: PluginJobPathInput | PluginJobPathInput[] | null): string {
10
+ if (!value) return 'nothing selected'
11
+ const selections = Array.isArray(value) ? value : [value]
12
+ if (!selections.length) return 'nothing selected'
13
+ return selections
14
+ .map(selection => selection.rootName ?? selection.relativePaths.join(', '))
15
+ .join(' · ')
16
+ }
17
+
18
+ function initState() {
19
+ return {
20
+ multiple: false,
21
+ disabled: false,
22
+ }
23
+ }
24
+ </script>
25
+
26
+ <template>
27
+ <Story title="Forms/GeneratedPathInput">
28
+ <Variant title="Playground" :init-state="initState">
29
+ <template #default="{ state }">
30
+ <!-- Outside an integrated plugin the "Existing artifact" button is
31
+ hidden, so the story shows the file/folder modes only. -->
32
+ <div style="padding: 2rem; max-width: 600px;">
33
+ <GeneratedPathInput
34
+ v-model="single"
35
+ :multiple="state.multiple"
36
+ :disabled="state.disabled"
37
+ />
38
+ <p style="margin-top: 1rem; font-size: 0.8125rem; color: var(--text-secondary);">
39
+ Selection: <code>{{ describe(single) }}</code>
40
+ </p>
41
+ </div>
42
+ </template>
43
+
44
+ <template #controls="{ state }">
45
+ <HstCheckbox v-model="state.multiple" title="Allow multiple" />
46
+ <HstCheckbox v-model="state.disabled" title="Disabled" />
47
+ </template>
48
+ </Variant>
49
+
50
+ <Variant title="Single path">
51
+ <div style="padding: 2rem; max-width: 600px;">
52
+ <GeneratedPathInput v-model="single" />
53
+ </div>
54
+ </Variant>
55
+
56
+ <Variant title="Multiple paths">
57
+ <div style="padding: 2rem; max-width: 600px;">
58
+ <GeneratedPathInput v-model="multiple" multiple />
59
+ </div>
60
+ </Variant>
61
+
62
+ <Variant title="Disabled">
63
+ <div style="padding: 2rem; max-width: 600px;">
64
+ <GeneratedPathInput v-model="single" disabled />
65
+ </div>
66
+ </Variant>
67
+ </Story>
68
+ </template>
@@ -0,0 +1,96 @@
1
+ <script setup lang="ts">
2
+ import GeneratedPlotlyResult from './GeneratedPlotlyResult.vue'
3
+
4
+ const scatterSpec: Record<string, unknown> = {
5
+ data: [
6
+ {
7
+ type: 'scatter',
8
+ mode: 'markers',
9
+ name: 'Control',
10
+ x: [1.2, 2.4, 3.1, 4.8, 5.5, 6.9],
11
+ y: [0.9, 1.8, 2.6, 3.9, 4.4, 5.8],
12
+ marker: { size: 9 },
13
+ },
14
+ {
15
+ type: 'scatter',
16
+ mode: 'markers',
17
+ name: 'Treated',
18
+ x: [1.1, 2.2, 3.4, 4.5, 5.9, 6.4],
19
+ y: [2.1, 3.4, 3.9, 5.2, 6.4, 7.1],
20
+ marker: { size: 9 },
21
+ },
22
+ ],
23
+ layout: {
24
+ margin: { t: 24, r: 16, b: 40, l: 48 },
25
+ xaxis: { title: 'log2 intensity (control)' },
26
+ yaxis: { title: 'log2 intensity (treated)' },
27
+ },
28
+ }
29
+
30
+ const barSpec: Record<string, unknown> = {
31
+ data: [
32
+ {
33
+ type: 'bar',
34
+ x: ['Glycolysis', 'TCA', 'PPP', 'Urea cycle'],
35
+ y: [12, 27, 8, 4],
36
+ },
37
+ ],
38
+ layout: { margin: { t: 24, r: 16, b: 40, l: 48 } },
39
+ }
40
+
41
+ // Not a valid Plotly spec — exercises the static-image fallback branch.
42
+ const brokenSpec: Record<string, unknown> = { data: 'not-an-array' }
43
+
44
+ const PIXEL_PNG
45
+ = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg=='
46
+
47
+ function initState() {
48
+ return { chart: 'scatter' as 'scatter' | 'bar' }
49
+ }
50
+ </script>
51
+
52
+ <template>
53
+ <Story title="Workflow/GeneratedPlotlyResult">
54
+ <Variant title="Playground" :init-state="initState">
55
+ <template #default="{ state }">
56
+ <div style="padding: 2rem; max-width: 720px;">
57
+ <GeneratedPlotlyResult :spec="state.chart === 'bar' ? barSpec : scatterSpec" />
58
+ </div>
59
+ </template>
60
+
61
+ <template #controls="{ state }">
62
+ <HstSelect
63
+ v-model="state.chart"
64
+ title="Chart"
65
+ :options="[
66
+ { label: 'scatter', value: 'scatter' },
67
+ { label: 'bar', value: 'bar' },
68
+ ]"
69
+ />
70
+ </template>
71
+ </Variant>
72
+
73
+ <Variant title="Scatter">
74
+ <div style="padding: 2rem; max-width: 720px;">
75
+ <GeneratedPlotlyResult :spec="scatterSpec" />
76
+ </div>
77
+ </Variant>
78
+
79
+ <Variant title="Bar">
80
+ <div style="padding: 2rem; max-width: 720px;">
81
+ <GeneratedPlotlyResult :spec="barSpec" />
82
+ </div>
83
+ </Variant>
84
+
85
+ <Variant title="Render failure → PNG fallback">
86
+ <!-- When Plotly cannot render the spec the component swaps in the
87
+ server-rendered static image, if the job supplied one. -->
88
+ <div style="padding: 2rem; max-width: 720px;">
89
+ <GeneratedPlotlyResult
90
+ :spec="brokenSpec"
91
+ :fallback="{ media_type: 'image/png', data: PIXEL_PNG }"
92
+ />
93
+ </div>
94
+ </Variant>
95
+ </Story>
96
+ </template>
@@ -79,9 +79,9 @@ onBeforeUnmount(() => {
79
79
  .mint-generated-result__plotly-error {
80
80
  margin: 0;
81
81
  padding: 1rem;
82
- border: 1px solid var(--color-danger-border, var(--color-border));
82
+ border: 1px solid var(--mint-error-border);
83
83
  border-radius: 0.75rem;
84
- background: var(--color-danger-bg, var(--color-bg-secondary));
85
- color: var(--color-danger-text, var(--color-text-primary));
84
+ background: var(--mint-error-bg);
85
+ color: var(--mint-error);
86
86
  }
87
87
  </style>
@@ -0,0 +1,145 @@
1
+ <script setup lang="ts">
2
+ import GeneratedPluginView from './GeneratedPluginView.vue'
3
+ import type { GeneratedAnalysisTransport } from '../composables/useGeneratedAnalysis'
4
+ import type { GeneratedAnalysisManifest } from '../types/generated-ui'
5
+
6
+ const manifest: GeneratedAnalysisManifest = {
7
+ schema_version: '1',
8
+ plugin: {
9
+ name: 'peak-qc',
10
+ version: '1.2.0',
11
+ description: 'Peak-picking quality control',
12
+ routes_prefix: '/api/peak-qc',
13
+ },
14
+ ui: {
15
+ title: 'Peak QC',
16
+ description: 'Score peak-picking output and flag features that need review.',
17
+ },
18
+ jobs: [
19
+ {
20
+ id: 'score-features',
21
+ title: 'Score features',
22
+ description: 'Compute RSD, blank ratio and detection rate for every feature.',
23
+ cpu: 4,
24
+ input_schema: {
25
+ type: 'object',
26
+ title: 'Scoring parameters',
27
+ properties: {
28
+ rsd_threshold: {
29
+ type: 'number',
30
+ title: 'QC RSD threshold',
31
+ description: 'Features above this relative standard deviation are flagged.',
32
+ default: 0.3,
33
+ minimum: 0,
34
+ maximum: 1,
35
+ },
36
+ blank_ratio: {
37
+ type: 'number',
38
+ title: 'Minimum blank ratio',
39
+ default: 3,
40
+ minimum: 1,
41
+ },
42
+ drop_flagged: {
43
+ type: 'boolean',
44
+ title: 'Drop flagged features',
45
+ default: false,
46
+ },
47
+ },
48
+ required: ['rsd_threshold'],
49
+ },
50
+ output_schema: { type: 'object' },
51
+ },
52
+ {
53
+ id: 'align-batches',
54
+ title: 'Align batches',
55
+ description: 'Retention-time align acquisition batches before merging.',
56
+ cpu: 8,
57
+ input_schema: {
58
+ type: 'object',
59
+ properties: {
60
+ tolerance_seconds: { type: 'number', title: 'RT tolerance (s)', default: 6 },
61
+ reference_batch: { type: 'string', title: 'Reference batch', default: 'batch-1' },
62
+ },
63
+ },
64
+ output_schema: { type: 'object' },
65
+ },
66
+ ],
67
+ }
68
+
69
+ const session = {
70
+ id: 'sess_story',
71
+ tab_id: 'tab_story',
72
+ created_at: new Date().toISOString(),
73
+ last_seen_at: new Date().toISOString(),
74
+ active_job_ids: [],
75
+ }
76
+
77
+ function json(body: unknown): Response {
78
+ return new Response(JSON.stringify(body), {
79
+ status: 200,
80
+ headers: { 'Content-Type': 'application/json' },
81
+ })
82
+ }
83
+
84
+ /** Serves the manifest, one session and an empty job list — no network. */
85
+ const readyTransport: GeneratedAnalysisTransport = async (input) => {
86
+ const url = String(input)
87
+ if (url.includes('/generated/manifest')) return json(manifest)
88
+ if (url.includes('/jobs/sessions')) return json({ sessions: [session] })
89
+ if (url.includes('/jobs')) return json({ jobs: [] })
90
+ return json({})
91
+ }
92
+
93
+ /** Never settles, so the workspace stays in its loading state. */
94
+ const loadingTransport: GeneratedAnalysisTransport = () => new Promise<Response>(() => {})
95
+
96
+ /** Fails the manifest request, so the workspace surfaces its error banner. */
97
+ const failingTransport: GeneratedAnalysisTransport = async () => (
98
+ new Response(JSON.stringify({ detail: 'Plugin runtime is not reachable' }), {
99
+ status: 503,
100
+ headers: { 'Content-Type': 'application/json' },
101
+ })
102
+ )
103
+
104
+ function initState() {
105
+ return { showStandaloneLabel: false }
106
+ }
107
+ </script>
108
+
109
+ <template>
110
+ <Story title="Workflow/GeneratedPluginView">
111
+ <Variant title="Playground" :init-state="initState">
112
+ <template #default="{ state }">
113
+ <div style="height: 42rem;">
114
+ <GeneratedPluginView
115
+ base-url="/story/peak-qc"
116
+ :transport="readyTransport"
117
+ :show-standalone-label="state.showStandaloneLabel"
118
+ />
119
+ </div>
120
+ </template>
121
+
122
+ <template #controls="{ state }">
123
+ <HstCheckbox v-model="state.showStandaloneLabel" title="Standalone label" />
124
+ </template>
125
+ </Variant>
126
+
127
+ <Variant title="Ready — two job definitions">
128
+ <div style="height: 42rem;">
129
+ <GeneratedPluginView base-url="/story/peak-qc" :transport="readyTransport" />
130
+ </div>
131
+ </Variant>
132
+
133
+ <Variant title="Loading">
134
+ <div style="height: 42rem;">
135
+ <GeneratedPluginView base-url="/story/loading" :transport="loadingTransport" />
136
+ </div>
137
+ </Variant>
138
+
139
+ <Variant title="Runtime unreachable">
140
+ <div style="height: 42rem;">
141
+ <GeneratedPluginView base-url="/story/failing" :transport="failingTransport" />
142
+ </div>
143
+ </Variant>
144
+ </Story>
145
+ </template>
@@ -207,7 +207,7 @@ onMounted(() => {
207
207
  min-width: 0;
208
208
  min-height: calc(100vh - 5rem);
209
209
  padding: clamp(1rem, 2.5vw, 2.5rem);
210
- background: var(--color-bg-primary);
210
+ background: var(--bg-primary);
211
211
  }
212
212
 
213
213
  .mint-generated-workspace__loading {
@@ -216,7 +216,7 @@ onMounted(() => {
216
216
  align-items: center;
217
217
  justify-content: center;
218
218
  gap: 0.75rem;
219
- color: var(--color-text-secondary);
219
+ color: var(--text-secondary);
220
220
  }
221
221
 
222
222
  .mint-generated-workspace__header {
@@ -230,19 +230,19 @@ onMounted(() => {
230
230
 
231
231
  .mint-generated-workspace__header h1 {
232
232
  margin: 0;
233
- color: var(--color-text-primary);
233
+ color: var(--text-primary);
234
234
  font-size: clamp(1.35rem, 2vw, 1.8rem);
235
235
  line-height: 1.2;
236
236
  }
237
237
 
238
238
  .mint-generated-workspace__header p:not(.mint-generated-workspace__eyebrow) {
239
239
  margin: 0.4rem 0 0;
240
- color: var(--color-text-secondary);
240
+ color: var(--text-secondary);
241
241
  }
242
242
 
243
243
  .mint-generated-workspace__eyebrow {
244
244
  margin: 0 0 0.35rem;
245
- color: var(--color-text-muted);
245
+ color: var(--text-muted);
246
246
  font-size: 0.72rem;
247
247
  font-weight: 700;
248
248
  letter-spacing: 0.08em;
@@ -258,10 +258,10 @@ onMounted(() => {
258
258
 
259
259
  .mint-generated-workspace__resources span {
260
260
  padding: 0.3rem 0.55rem;
261
- border: 1px solid var(--color-border);
261
+ border: 1px solid var(--border-color);
262
262
  border-radius: 999px;
263
- background: var(--color-bg-secondary);
264
- color: var(--color-text-secondary);
263
+ background: var(--bg-secondary);
264
+ color: var(--text-secondary);
265
265
  font-size: 0.75rem;
266
266
  font-weight: 600;
267
267
  }
@@ -271,9 +271,9 @@ onMounted(() => {
271
271
  min-height: 24rem;
272
272
  margin: 0 auto;
273
273
  padding: clamp(1rem, 2vw, 1.75rem);
274
- border: 1px solid var(--color-border);
274
+ border: 1px solid var(--border-color);
275
275
  border-radius: 1rem;
276
- background: var(--color-bg-secondary);
276
+ background: var(--bg-secondary);
277
277
  box-shadow: var(--shadow-sm);
278
278
  }
279
279
 
@@ -0,0 +1,117 @@
1
+ <script setup lang="ts">
2
+ import GeneratedResultRenderer from './GeneratedResultRenderer.vue'
3
+ import type { GeneratedAnalysisResult } from '../types/generated-ui'
4
+
5
+ const textResult: GeneratedAnalysisResult = {
6
+ kind: 'text',
7
+ text: 'Peak integration finished: 1,284 features across 96 samples, 12 flagged for manual review.',
8
+ }
9
+
10
+ const jsonResult: GeneratedAnalysisResult = {
11
+ kind: 'json',
12
+ value: {
13
+ method: 'HILIC_neg_12min',
14
+ features: 1284,
15
+ qc: { rsd_median: 0.041, blanks_removed: 37 },
16
+ flagged: ['M241T118', 'M317T204'],
17
+ },
18
+ }
19
+
20
+ const tableResult: GeneratedAnalysisResult = {
21
+ kind: 'table',
22
+ columns: ['feature_id', 'mz', 'retention_time', 'fold_change', 'p_value'],
23
+ rows: [
24
+ { feature_id: 'M180T204', mz: 180.0634, retention_time: 3.42, fold_change: 2.14, p_value: 0.0012 },
25
+ { feature_id: 'M241T118', mz: 241.0311, retention_time: 1.97, fold_change: -1.83, p_value: 0.0044 },
26
+ { feature_id: 'M317T204', mz: 317.0521, retention_time: 3.41, fold_change: 1.07, p_value: 0.2310 },
27
+ { feature_id: 'M146T092', mz: 146.0453, retention_time: 1.53, fold_change: -3.02, p_value: 0.0001 },
28
+ ],
29
+ }
30
+
31
+ // 1x1 transparent PNG — enough to exercise the image branch without a fixture.
32
+ const PIXEL_PNG
33
+ = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg=='
34
+
35
+ const imageResult: GeneratedAnalysisResult = {
36
+ kind: 'image',
37
+ media_type: 'image/png',
38
+ data: PIXEL_PNG,
39
+ alt: 'Static QC overview rendered by the plugin',
40
+ }
41
+
42
+ const artifactResult: GeneratedAnalysisResult = {
43
+ kind: 'artifact',
44
+ id: 'art_01J9',
45
+ name: 'peak_table.parquet',
46
+ media_type: 'application/vnd.apache.parquet',
47
+ size: 4_812_390,
48
+ download_url: '#download',
49
+ managed: true,
50
+ }
51
+
52
+ type ResultKind = 'text' | 'json' | 'table' | 'image' | 'artifact'
53
+
54
+ const kinds: ResultKind[] = ['text', 'json', 'table', 'image', 'artifact']
55
+
56
+ const byKind: Record<ResultKind, GeneratedAnalysisResult> = {
57
+ text: textResult,
58
+ json: jsonResult,
59
+ table: tableResult,
60
+ image: imageResult,
61
+ artifact: artifactResult,
62
+ }
63
+
64
+ function initState() {
65
+ return { kind: 'table' as ResultKind }
66
+ }
67
+ </script>
68
+
69
+ <template>
70
+ <Story title="Workflow/GeneratedResultRenderer">
71
+ <Variant title="Playground" :init-state="initState">
72
+ <template #default="{ state }">
73
+ <div style="padding: 2rem; max-width: 720px;">
74
+ <GeneratedResultRenderer :result="byKind[state.kind as ResultKind]" />
75
+ </div>
76
+ </template>
77
+
78
+ <template #controls="{ state }">
79
+ <HstSelect
80
+ v-model="state.kind"
81
+ title="Result kind"
82
+ :options="kinds.map(k => ({ label: k, value: k }))"
83
+ />
84
+ </template>
85
+ </Variant>
86
+
87
+ <Variant title="Text">
88
+ <div style="padding: 2rem; max-width: 720px;">
89
+ <GeneratedResultRenderer :result="textResult" />
90
+ </div>
91
+ </Variant>
92
+
93
+ <Variant title="Table">
94
+ <div style="padding: 2rem; max-width: 720px;">
95
+ <GeneratedResultRenderer :result="tableResult" />
96
+ </div>
97
+ </Variant>
98
+
99
+ <Variant title="JSON">
100
+ <div style="padding: 2rem; max-width: 720px;">
101
+ <GeneratedResultRenderer :result="jsonResult" />
102
+ </div>
103
+ </Variant>
104
+
105
+ <Variant title="Image">
106
+ <div style="padding: 2rem; max-width: 720px;">
107
+ <GeneratedResultRenderer :result="imageResult" />
108
+ </div>
109
+ </Variant>
110
+
111
+ <Variant title="Artifact download">
112
+ <div style="padding: 2rem; max-width: 720px;">
113
+ <GeneratedResultRenderer :result="artifactResult" />
114
+ </div>
115
+ </Variant>
116
+ </Story>
117
+ </template>
@@ -101,7 +101,7 @@ function humanize(value: string): string {
101
101
  .mint-generated-result__text,
102
102
  .mint-generated-result__json {
103
103
  margin: 0;
104
- color: var(--color-text-primary);
104
+ color: var(--text-primary);
105
105
  }
106
106
 
107
107
  .mint-generated-result__text {
@@ -113,9 +113,9 @@ function humanize(value: string): string {
113
113
  .mint-generated-result__json {
114
114
  overflow: auto;
115
115
  padding: 1rem;
116
- border: 1px solid var(--color-border);
116
+ border: 1px solid var(--border-color);
117
117
  border-radius: 0.75rem;
118
- background: var(--color-bg-secondary);
118
+ background: var(--bg-secondary);
119
119
  font-size: 0.8125rem;
120
120
  line-height: 1.55;
121
121
  white-space: pre-wrap;
@@ -139,7 +139,7 @@ function humanize(value: string): string {
139
139
  justify-content: space-between;
140
140
  gap: 1rem;
141
141
  padding: 1rem;
142
- border: 1px solid var(--color-border);
142
+ border: 1px solid var(--border-color);
143
143
  border-radius: 0.75rem;
144
144
  color: var(--color-primary);
145
145
  text-decoration: none;