@morscherlab/mint-sdk 1.2.10 → 1.3.0-beta.10

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 (841) hide show
  1. package/README.md +45 -137
  2. package/dist/ResourcePickerListInternal-CFAw4vTZ.js +605 -0
  3. package/dist/ResourcePickerListInternal-CFAw4vTZ.js.map +1 -0
  4. package/dist/__stories__/experiment-helpers.d.ts +12 -1
  5. package/dist/__tests__/components/ScientificNumber.test.d.ts +1 -0
  6. package/dist/__tests__/components/SequenceInput.test.d.ts +1 -0
  7. package/dist/__tests__/components/Skeleton.test.d.ts +1 -0
  8. package/dist/__tests__/components/SmartGroupFieldRecipe.test.d.ts +1 -0
  9. package/dist/__tests__/components/SmartGroupModal.test.d.ts +1 -0
  10. package/dist/__tests__/components/StepWizard.test.d.ts +1 -0
  11. package/dist/__tests__/components/TimeRangeInput.test.d.ts +1 -0
  12. package/dist/__tests__/components/UnitInput.test.d.ts +1 -0
  13. package/dist/__tests__/components/WellPlate.keyboard.test.d.ts +1 -0
  14. package/dist/__tests__/components/WellPlate.sampleTypeIndicator.test.d.ts +1 -0
  15. package/dist/__tests__/composables/useChemicalFormula.test.d.ts +1 -0
  16. package/dist/__tests__/composables/useRackEditor.test.d.ts +1 -0
  17. package/dist/__tests__/composables/useSequenceUtils.test.d.ts +1 -0
  18. package/dist/__tests__/styles/baseControlsRules.test.d.ts +1 -0
  19. package/dist/__tests__/styles/controlRefreshRules.test.d.ts +1 -0
  20. package/dist/__tests__/styles/darkModeRules.test.d.ts +1 -0
  21. package/dist/__tests__/styles/menusShellRefresh.test.d.ts +1 -0
  22. package/dist/__tests__/templates/templatesDeprecation.test.d.ts +1 -0
  23. package/dist/__tests__/utils/plotlyTemplate.test.d.ts +1 -0
  24. package/dist/__tests__/utils/sampleTypeMarker.test.d.ts +1 -0
  25. package/dist/{analysisArtifactTypes-DQ0MjwHZ.js → analysisArtifactTypes-Cy3D0Ipg.js} +1 -1
  26. package/dist/{analysisArtifactTypes-DQ0MjwHZ.js.map → analysisArtifactTypes-Cy3D0Ipg.js.map} +1 -1
  27. package/dist/components/ActionMenu.vue.d.ts +17 -5
  28. package/dist/components/AdductText.vue.d.ts +3 -2
  29. package/dist/components/AlertBox.vue.d.ts +11 -14
  30. package/dist/components/AppAvatarMenu.vue.d.ts +18 -28
  31. package/dist/components/AppContainer.vue.d.ts +7 -11
  32. package/dist/components/AppLayout.vue.d.ts +11 -13
  33. package/dist/components/AppSidebar.vue.d.ts +30 -28
  34. package/dist/components/AppToastContainer.vue.d.ts +2 -1
  35. package/dist/components/AppTopBar.vue.d.ts +45 -44
  36. package/dist/components/ArtifactSaveDialog.vue.d.ts +3 -2
  37. package/dist/components/ArtifactSelectorModal.vue.d.ts +5 -6
  38. package/dist/components/AuditTrail.vue.d.ts +17 -18
  39. package/dist/components/AutoGroupModal.vue.d.ts +4 -3
  40. package/dist/components/Avatar.vue.d.ts +2 -1
  41. package/dist/components/BaseButton.vue.d.ts +11 -13
  42. package/dist/components/BaseCheckbox.vue.d.ts +7 -1
  43. package/dist/components/BaseInput.vue.d.ts +15 -2
  44. package/dist/components/BaseModal.vue.d.ts +20 -23
  45. package/dist/components/BasePill.vue.d.ts +10 -13
  46. package/dist/components/BaseRadioGroup.vue.d.ts +2 -1
  47. package/dist/components/BaseSelect.vue.d.ts +3 -2
  48. package/dist/components/BaseSlider.vue.d.ts +18 -1
  49. package/dist/components/BaseTabs.vue.d.ts +2 -1
  50. package/dist/components/BaseTextarea.vue.d.ts +2 -1
  51. package/dist/components/BaseToggle.vue.d.ts +2 -1
  52. package/dist/components/BatchProgressList.vue.d.ts +22 -26
  53. package/dist/components/BioTemplateExperimentWorkspaceView.vue.d.ts +7 -14
  54. package/dist/components/BioTemplatePackWorkspaceView.vue.d.ts +6 -13
  55. package/dist/components/BioTemplatePresetWorkspaceView.vue.d.ts +7 -14
  56. package/dist/components/BioTemplateRenderer.vue.d.ts +2 -1
  57. package/dist/components/Breadcrumb.vue.d.ts +13 -16
  58. package/dist/components/Calendar.vue.d.ts +21 -23
  59. package/dist/components/ChartContainer.vue.d.ts +19 -25
  60. package/dist/components/ChemicalFormula.vue.d.ts +7 -11
  61. package/dist/components/CollapsibleCard.vue.d.ts +7 -11
  62. package/dist/components/ComponentBindingRenderer.vue.d.ts +2 -1
  63. package/dist/components/ConcentrationInput.vue.d.ts +2 -1
  64. package/dist/components/ConfirmDialog.vue.d.ts +10 -13
  65. package/dist/components/ControlWorkspaceView.vue.d.ts +9 -18
  66. package/dist/components/DataFrame.vue.d.ts +27 -24
  67. package/dist/components/DatePicker.vue.d.ts +3 -6
  68. package/dist/components/DateTimePicker.vue.d.ts +3 -6
  69. package/dist/components/Divider.vue.d.ts +3 -2
  70. package/dist/components/DoseCalculator.vue.d.ts +2 -1
  71. package/dist/components/DoseCalculatorVolumeField.vue.d.ts +2 -1
  72. package/dist/components/DoseDesignWorkspaceView.vue.d.ts +9 -18
  73. package/dist/components/EmptyState.vue.d.ts +9 -12
  74. package/dist/components/ExperimentCodeBadge.vue.d.ts +2 -1
  75. package/dist/components/ExperimentDataViewer.vue.d.ts +13 -15
  76. package/dist/components/ExperimentPopover.vue.d.ts +3 -5
  77. package/dist/components/ExperimentSelectorModal.vue.d.ts +3 -4
  78. package/dist/components/ExperimentTimeline.vue.d.ts +13 -15
  79. package/dist/components/FilePicker.vue.d.ts +10 -5
  80. package/dist/components/FileUploader.vue.d.ts +8 -16
  81. package/dist/components/FitPanel.vue.d.ts +26 -16
  82. package/dist/components/FormActions.vue.d.ts +2 -1
  83. package/dist/components/FormBuilder.vue.d.ts +54 -250
  84. package/dist/components/FormField.vue.d.ts +14 -16
  85. package/dist/components/FormulaInput.vue.d.ts +2 -1
  86. package/dist/components/GeneratedPathInput.vue.d.ts +6 -5
  87. package/dist/components/GeneratedPlotlyResult.vue.d.ts +2 -1
  88. package/dist/components/GeneratedPluginView.vue.d.ts +2 -1
  89. package/dist/components/GeneratedResultRenderer.vue.d.ts +2 -1
  90. package/dist/components/GroupAssigner.vue.d.ts +2 -1
  91. package/dist/components/IconButton.vue.d.ts +7 -11
  92. package/dist/components/InstrumentStateBadge.vue.d.ts +4 -3
  93. package/dist/components/JobsStatusTray.vue.d.ts +13 -29
  94. package/dist/components/LayoutResizeHandle.vue.d.ts +2 -1
  95. package/dist/components/LoadingSpinner.vue.d.ts +2 -1
  96. package/dist/components/MobileSupportGate.vue.d.ts +5 -13
  97. package/dist/components/MoleculeInput.vue.d.ts +3 -4
  98. package/dist/components/MultiSelect.vue.d.ts +2 -1
  99. package/dist/components/NumberInput.vue.d.ts +2 -1
  100. package/dist/components/PlateEditor.vue.d.ts +147 -0
  101. package/dist/components/PlotlyChart.vue.d.ts +21 -31
  102. package/dist/components/PluginIcon.vue.d.ts +2 -1
  103. package/dist/components/PluginWorkspaceView.props.d.ts +2 -6
  104. package/dist/components/PluginWorkspaceView.vue.d.ts +23 -51
  105. package/dist/components/ProgressBar.vue.d.ts +4 -9
  106. package/dist/components/ProtocolStepEditor.vue.d.ts +7 -5
  107. package/dist/components/ProtocolStepParameterField.vue.d.ts +2 -1
  108. package/dist/components/ReagentEditor.vue.d.ts +2 -1
  109. package/dist/components/ReagentList.presentation.d.ts +2 -1
  110. package/dist/components/ReagentList.vue.d.ts +15 -17
  111. package/dist/components/ResourceCard.vue.d.ts +18 -17
  112. package/dist/components/RuntimeUpdateNotice.vue.d.ts +3 -2
  113. package/dist/components/SampleHierarchyTree.vue.d.ts +21 -15
  114. package/dist/components/SampleLegend.vue.d.ts +2 -1
  115. package/dist/components/SampleSelector.vue.d.ts +15 -21
  116. package/dist/components/SampleSelectorGroupNode.vue.d.ts +2 -1
  117. package/dist/components/SampleSelectorSampleRow.vue.d.ts +2 -5
  118. package/dist/components/ScheduleCalendar.vue.d.ts +34 -36
  119. package/dist/components/ScientificNumber.vue.d.ts +3 -2
  120. package/dist/components/SearchableSelect.vue.d.ts +14 -32
  121. package/dist/components/SecretInput.vue.d.ts +2 -1
  122. package/dist/components/SectionCard.vue.d.ts +13 -14
  123. package/dist/components/SegmentedControl.vue.d.ts +2 -1
  124. package/dist/components/SequenceInput.vue.d.ts +10 -21
  125. package/dist/components/SequenceProgressBar.vue.d.ts +2 -1
  126. package/dist/components/SettingsModal.schema.d.ts +1 -1
  127. package/dist/components/SettingsModal.vue.d.ts +28 -25
  128. package/dist/components/Skeleton.vue.d.ts +2 -1
  129. package/dist/components/SmartGroup.types.d.ts +2 -2
  130. package/dist/components/SmartGroupFieldRecipe.groups.d.ts +2 -0
  131. package/dist/components/SmartGroupFieldRecipe.vue.d.ts +4 -7
  132. package/dist/components/SmartGroupManual.vue.d.ts +3 -2
  133. package/dist/components/SmartGroupModal.vue.d.ts +6 -4
  134. package/dist/components/StatusIndicator.vue.d.ts +2 -1
  135. package/dist/components/StepWizard.vue.d.ts +26 -27
  136. package/dist/components/TagsInput.vue.d.ts +3 -5
  137. package/dist/components/ThemeToggle.vue.d.ts +2 -1
  138. package/dist/components/TimePicker.vue.d.ts +6 -6
  139. package/dist/components/TimeRangeInput.vue.d.ts +9 -2
  140. package/dist/components/Tooltip.vue.d.ts +8 -18
  141. package/dist/components/UnitInput.vue.d.ts +2 -1
  142. package/dist/components/WellPlate.colors.d.ts +2 -4
  143. package/dist/components/WellPlate.rendering.d.ts +7 -1
  144. package/dist/components/WellPlate.sampleDrop.d.ts +2 -0
  145. package/dist/components/WellPlate.vue.d.ts +22 -39
  146. package/dist/components/index.d.ts +34 -31
  147. package/dist/components/index.js +5 -8
  148. package/dist/components/internal/ActionItemInternal.vue.d.ts +11 -13
  149. package/dist/components/internal/AppTopBarPageSelectorInternal.vue.d.ts +14 -23
  150. package/dist/components/internal/AppTopBarPillNavInternal.vue.d.ts +2 -1
  151. package/dist/components/internal/CalendarGridPanelInternal.vue.d.ts +2 -1
  152. package/dist/components/internal/DataStateInternal.vue.d.ts +7 -11
  153. package/dist/components/internal/{FilePickerTreeInternal.vue.d.ts → FilePickerListInternal.vue.d.ts} +9 -6
  154. package/dist/components/internal/FilePickerPreviewInternal.vue.d.ts +4 -3
  155. package/dist/components/internal/FormFieldRendererInternal.vue.d.ts +16 -18
  156. package/dist/components/internal/FormSectionRenderer.vue.d.ts +36 -32
  157. package/dist/components/internal/PlateEditorBindingInternal.vue.d.ts +8 -0
  158. package/dist/components/internal/ResourcePickerListInternal.vue.d.ts +65 -0
  159. package/dist/components/internal/SettingsPaneHeadInternal.vue.d.ts +15 -0
  160. package/dist/components/internal/WellEditPopupInternal.vue.d.ts +12 -4
  161. package/dist/components/internal/WorkspaceControlsInternal.vue.d.ts +6 -13
  162. package/dist/components/internal/WorkspaceShellInternal.vue.d.ts +19 -42
  163. package/dist/components/internal/WorkspaceSidebarInternal.vue.d.ts +9 -19
  164. package/dist/components/internal/filePickerPresentation.d.ts +8 -0
  165. package/dist/components/internal/generatedJobsApi.d.ts +9 -0
  166. package/dist/{components-Bbg_gtzF.js → components-GDDvof8D.js} +7088 -5955
  167. package/dist/components-GDDvof8D.js.map +1 -0
  168. package/dist/composables/controlSchemaTypes.d.ts +4 -43
  169. package/dist/composables/createFilePickerAdapter.d.ts +5 -1
  170. package/dist/composables/filePicker/usePickerNavigation.d.ts +7 -2
  171. package/dist/composables/index.d.ts +2 -13
  172. package/dist/composables/index.js +7 -11
  173. package/dist/composables/pluginWorkspaceModel.d.ts +1 -3
  174. package/dist/composables/useAutoGroup.d.ts +10 -0
  175. package/dist/composables/useBioTemplateComponents.d.ts +15 -3
  176. package/dist/composables/useBioTemplateControls.d.ts +5 -1
  177. package/dist/composables/useBioTemplatePackWorkspace.d.ts +2 -0
  178. package/dist/composables/useBioTemplatePresetWorkspace.d.ts +5 -1
  179. package/dist/composables/useBioTemplateWorkspace.d.ts +5 -1
  180. package/dist/composables/useChemicalFormula.d.ts +2 -1
  181. package/dist/composables/useDropdownState.d.ts +5 -0
  182. package/dist/composables/useExperimentSave.d.ts +5 -1
  183. package/dist/composables/useFileBrowser.d.ts +3 -2
  184. package/dist/composables/useFilePicker.d.ts +25 -13
  185. package/dist/composables/useFocusTrap.d.ts +2 -1
  186. package/dist/composables/useGroupAssignment.d.ts +5 -1
  187. package/dist/composables/useJobsStatusTray.d.ts +5 -5
  188. package/dist/composables/useMenuKeyboard.d.ts +3 -3
  189. package/dist/composables/usePlatformContext.d.ts +3 -0
  190. package/dist/composables/usePluginClient.d.ts +1 -1
  191. package/dist/composables/useRackEditor.d.ts +36 -1
  192. package/dist/composables/useSequenceUtils.d.ts +8 -0
  193. package/dist/composables/useTemplateCollection.d.ts +5 -1
  194. package/dist/composables/workspaceRecipes.d.ts +1 -0
  195. package/dist/composables-D6uqp0UF.js +591 -0
  196. package/dist/composables-D6uqp0UF.js.map +1 -0
  197. package/dist/{errors-BLuqMee5.js → experiment-DgllIc3I.js} +89 -333
  198. package/dist/experiment-DgllIc3I.js.map +1 -0
  199. package/dist/{experiment-utils-CV2Wza3z.js → experiment-utils-DTANyVKV.js} +68 -37
  200. package/dist/experiment-utils-DTANyVKV.js.map +1 -0
  201. package/dist/index.d.ts +2 -0
  202. package/dist/index.js +122 -17
  203. package/dist/index.js.map +1 -1
  204. package/dist/install.js +1 -2
  205. package/dist/install.js.map +1 -1
  206. package/dist/instrument.d.ts +6 -0
  207. package/dist/lcms.d.ts +11 -0
  208. package/dist/permissions.d.ts +2 -47
  209. package/dist/permissions.js +2 -26
  210. package/dist/permissions.js.map +1 -1
  211. package/dist/settings-BLr8lzw6.js +341 -0
  212. package/dist/settings-BLr8lzw6.js.map +1 -0
  213. package/dist/stores/auth.d.ts +2 -150
  214. package/dist/stores/experiment.d.ts +2 -106
  215. package/dist/stores/index.js +2 -2
  216. package/dist/stores/settings.d.ts +2 -44
  217. package/dist/styles.css +8608 -6950
  218. package/dist/tailwind.preset.js.map +1 -1
  219. package/dist/templates/adapters.d.ts +3 -0
  220. package/dist/templates/assayMatrixAdapters.d.ts +8 -1
  221. package/dist/templates/assayMatrixBuilder.d.ts +1 -0
  222. package/dist/templates/builderPresetControls.d.ts +1 -0
  223. package/dist/templates/calibrationCurveAdapters.d.ts +3 -0
  224. package/dist/templates/calibrationCurveBuilder.d.ts +1 -0
  225. package/dist/templates/catalog.d.ts +6 -2
  226. package/dist/templates/componentBindings.d.ts +31 -5
  227. package/dist/templates/componentPlateHelpers.d.ts +7 -1
  228. package/dist/templates/controlSchemas.d.ts +9 -0
  229. package/dist/templates/defaultBioTemplateBuilder.d.ts +1 -0
  230. package/dist/templates/doseResponseAdapters.d.ts +2 -0
  231. package/dist/templates/doseResponseBuilder.d.ts +1 -0
  232. package/dist/templates/elisaAssayCollectionBuilder.d.ts +1 -0
  233. package/dist/templates/flowCytometryAssayCollectionBuilder.d.ts +1 -0
  234. package/dist/templates/flowCytometryPanelBuilder.d.ts +1 -0
  235. package/dist/templates/flowPanelAdapters.d.ts +3 -0
  236. package/dist/templates/index.d.ts +1 -1
  237. package/dist/templates/index.js +2 -3
  238. package/dist/templates/instrumentRunAdapters.d.ts +13 -2
  239. package/dist/templates/instrumentRunBuilder.d.ts +1 -0
  240. package/dist/templates/lcmsBatchCollectionBuilder.d.ts +1 -0
  241. package/dist/templates/packs.d.ts +4 -0
  242. package/dist/templates/plateMapAdapters.d.ts +2 -0
  243. package/dist/templates/plateMapBuilder.d.ts +1 -0
  244. package/dist/templates/presets.d.ts +6 -2
  245. package/dist/templates/protocolAdapters.d.ts +4 -0
  246. package/dist/templates/protocolStepsBuilder.d.ts +1 -0
  247. package/dist/templates/qpcrAdapters.d.ts +4 -0
  248. package/dist/templates/qpcrExpressionCollectionBuilder.d.ts +1 -0
  249. package/dist/templates/qpcrPlateBuilder.d.ts +1 -0
  250. package/dist/templates/reagentAdapters.d.ts +4 -0
  251. package/dist/templates/reagentListBuilder.d.ts +1 -0
  252. package/dist/templates/samplePrepAdapters.d.ts +3 -0
  253. package/dist/templates/samplePrepBuilder.d.ts +1 -0
  254. package/dist/templates/sampleSheetAdapters.d.ts +4 -0
  255. package/dist/templates/sampleSheetBuilder.d.ts +1 -0
  256. package/dist/templates/targetedMetabolomicsCollectionBuilder.d.ts +1 -0
  257. package/dist/templates/templateEnvelopes.d.ts +8 -0
  258. package/dist/templates/templatePackCollectionBuilder.d.ts +1 -0
  259. package/dist/templates/templatePresetCollectionBuilder.d.ts +2 -0
  260. package/dist/templates/templateValidators.d.ts +12 -0
  261. package/dist/templates/timeCourseAdapters.d.ts +4 -0
  262. package/dist/templates/timeCourseBuilder.d.ts +1 -0
  263. package/dist/templates/wellPlateScreenCollectionBuilder.d.ts +1 -0
  264. package/dist/templates/westernBlotAssayCollectionBuilder.d.ts +1 -0
  265. package/dist/templates-BU1pet28.js +12304 -0
  266. package/dist/templates-BU1pet28.js.map +1 -0
  267. package/dist/types/auth.d.ts +0 -27
  268. package/dist/types/componentLabTypes.d.ts +14 -7
  269. package/dist/types/componentWorkflowTypes.d.ts +26 -0
  270. package/dist/types/components.d.ts +40 -17
  271. package/dist/types/fileBrowserTypes.d.ts +13 -0
  272. package/dist/types/filePicker.d.ts +19 -1
  273. package/dist/types/generated-ui.d.ts +13 -0
  274. package/dist/types/index.d.ts +4 -4
  275. package/dist/types/index.js +1 -1
  276. package/dist/types/instrument.d.ts +43 -15
  277. package/dist/types/platform.d.ts +2 -0
  278. package/dist/utils/color.d.ts +6 -1
  279. package/dist/utils/formModelSync.d.ts +1 -0
  280. package/dist/utils/plotlyTemplate.d.ts +3 -0
  281. package/dist/utils/rack.d.ts +16 -0
  282. package/dist/utils/sampleTypeMarker.d.ts +23 -0
  283. package/dist/{validation-ChMyixAf.js → validation-Dmp9Q5W0.js} +3032 -838
  284. package/dist/validation-Dmp9Q5W0.js.map +1 -0
  285. package/package.json +17 -23
  286. package/src/__stories__/experiment-helpers.ts +8 -4
  287. package/src/__tests__/components/ActionMenu.test.ts +66 -0
  288. package/src/__tests__/components/AlertBox.test.ts +21 -0
  289. package/src/__tests__/components/AppAvatarMenu.test.ts +25 -0
  290. package/src/__tests__/components/AppTopBar.test.ts +79 -0
  291. package/src/__tests__/components/AppTopBarPageSelector.test.ts +20 -0
  292. package/src/__tests__/components/AppTopBarPillNav.test.ts +74 -0
  293. package/src/__tests__/components/ArtifactSelectorModal.test.ts +20 -6
  294. package/src/__tests__/components/AuditTrail.test.ts +38 -0
  295. package/src/__tests__/components/BaseCheckbox.test.ts +43 -0
  296. package/src/__tests__/components/BaseInput.test.ts +43 -0
  297. package/src/__tests__/components/BaseModal.test.ts +90 -0
  298. package/src/__tests__/components/BaseRadioGroup.test.ts +8 -0
  299. package/src/__tests__/components/BaseSlider.test.ts +116 -0
  300. package/src/__tests__/components/BaseToggle.test.ts +7 -0
  301. package/src/__tests__/components/BatchProgressList.test.ts +22 -14
  302. package/src/__tests__/components/BioTemplateExperimentWorkspaceView.test.ts +4 -4
  303. package/src/__tests__/components/BioTemplatePackWorkspaceView.test.ts +1 -1
  304. package/src/__tests__/components/BioTemplatePresetWorkspaceView.test.ts +8 -8
  305. package/src/__tests__/components/BioTemplateRenderer.test.ts +2 -2
  306. package/src/__tests__/components/Breadcrumb.test.ts +45 -0
  307. package/src/__tests__/components/CalendarGridPanel.test.ts +14 -0
  308. package/src/__tests__/components/ChartContainer.test.ts +23 -0
  309. package/src/__tests__/components/ChemicalFormula.test.ts +15 -0
  310. package/src/__tests__/components/CollapsibleCard.test.ts +12 -9
  311. package/src/__tests__/components/ComponentBindingRenderer.test.ts +45 -17
  312. package/src/__tests__/components/ConcentrationInput.test.ts +17 -2
  313. package/src/__tests__/components/DataFrame.test.ts +107 -4
  314. package/src/__tests__/components/DataStates.test.ts +0 -16
  315. package/src/__tests__/components/DatePicker.test.ts +10 -0
  316. package/src/__tests__/components/DoseCalculator.test.ts +47 -0
  317. package/src/__tests__/components/DoseCalculatorVolumeField.test.ts +37 -34
  318. package/src/__tests__/components/EmptyState.test.ts +16 -1
  319. package/src/__tests__/components/ExperimentSelectorModal.test.ts +31 -3
  320. package/src/__tests__/components/ExperimentTimeline.test.ts +45 -0
  321. package/src/__tests__/components/FilePicker.state.test.ts +2 -2
  322. package/src/__tests__/components/FilePicker.test.ts +360 -13
  323. package/src/__tests__/components/FileUploader.test.ts +15 -0
  324. package/src/__tests__/components/FitPanel.test.ts +96 -0
  325. package/src/__tests__/components/FormulaInput.test.ts +97 -0
  326. package/src/__tests__/components/GeneratedPathInput.test.ts +168 -41
  327. package/src/__tests__/components/GeneratedPlotlyResult.test.ts +1 -1
  328. package/src/__tests__/components/GeneratedResultRenderer.test.ts +47 -2
  329. package/src/__tests__/components/InstrumentStateBadge.test.ts +50 -0
  330. package/src/__tests__/components/JobsStatusTray.test.ts +27 -0
  331. package/src/__tests__/components/MoleculeInput.test.ts +78 -0
  332. package/src/__tests__/components/MultiSelect.test.ts +6 -0
  333. package/src/__tests__/components/PlateEditor.test.ts +1134 -0
  334. package/src/__tests__/components/PlateEditorBindingInternal.test.ts +64 -0
  335. package/src/__tests__/components/PlotlyChart.test.ts +147 -1
  336. package/src/__tests__/components/ProgressBar.test.ts +18 -0
  337. package/src/__tests__/components/ProtocolStepEditor.test.ts +106 -18
  338. package/src/__tests__/components/ProtocolStepParameterField.test.ts +74 -29
  339. package/src/__tests__/components/ReagentList.presentation.test.ts +10 -5
  340. package/src/__tests__/components/ReagentList.test.ts +23 -0
  341. package/src/__tests__/components/ResourcePickerListInternal.test.ts +141 -0
  342. package/src/__tests__/components/RetiredStyles.test.ts +0 -6
  343. package/src/__tests__/components/SampleHierarchyTree.test.ts +102 -0
  344. package/src/__tests__/components/SampleLegend.test.ts +18 -0
  345. package/src/__tests__/components/SampleSelector.test.ts +92 -1
  346. package/src/__tests__/components/SampleSelectorSampleRow.test.ts +5 -2
  347. package/src/__tests__/components/ScheduleCalendar.test.ts +32 -0
  348. package/src/__tests__/components/ScientificNumber.test.ts +113 -0
  349. package/src/__tests__/components/SearchableSelect.test.ts +21 -0
  350. package/src/__tests__/components/SecretInput.test.ts +6 -0
  351. package/src/__tests__/components/SegmentedControl.test.ts +14 -0
  352. package/src/__tests__/components/SequenceInput.test.ts +81 -0
  353. package/src/__tests__/components/SettingsModal.schema.test.ts +5 -5
  354. package/src/__tests__/components/SettingsModal.test.ts +371 -23
  355. package/src/__tests__/components/Skeleton.test.ts +23 -0
  356. package/src/__tests__/components/SmartGroupFieldRecipe.test.ts +12 -0
  357. package/src/__tests__/components/SmartGroupModal.test.ts +69 -0
  358. package/src/__tests__/components/StepWizard.test.ts +75 -0
  359. package/src/__tests__/components/TagsInput.test.ts +16 -0
  360. package/src/__tests__/components/TimePicker.test.ts +66 -0
  361. package/src/__tests__/components/TimeRangeInput.test.ts +83 -0
  362. package/src/__tests__/components/UnitInput.test.ts +147 -0
  363. package/src/__tests__/components/WellEditPopupInternal.test.ts +434 -2
  364. package/src/__tests__/components/WellPlate.decoration.test.ts +18 -0
  365. package/src/__tests__/components/WellPlate.geometry.test.ts +13 -0
  366. package/src/__tests__/components/WellPlate.interaction.test.ts +213 -0
  367. package/src/__tests__/components/WellPlate.keyboard.test.ts +24 -0
  368. package/src/__tests__/components/WellPlate.rendering.test.ts +38 -19
  369. package/src/__tests__/components/WellPlate.sampleDrop.test.ts +19 -0
  370. package/src/__tests__/components/WellPlate.sampleTypeIndicator.test.ts +58 -0
  371. package/src/__tests__/composables/createFilePickerAdapter.test.ts +114 -1
  372. package/src/__tests__/composables/useBioTemplatePackWorkspace.test.ts +1 -1
  373. package/src/__tests__/composables/useBioTemplateWorkspace.test.ts +1 -1
  374. package/src/__tests__/composables/useChemicalFormula.test.ts +60 -0
  375. package/src/__tests__/composables/useControlSchema.test.ts +15 -5
  376. package/src/__tests__/composables/useDropdownState.test.ts +20 -1
  377. package/src/__tests__/composables/useGeneratedAnalysis.test.ts +52 -0
  378. package/src/__tests__/composables/usePickerNavigation.test.ts +61 -1
  379. package/src/__tests__/composables/usePlatformFilePickerAdapter.test.ts +18 -6
  380. package/src/__tests__/composables/useRackEditor.test.ts +270 -0
  381. package/src/__tests__/composables/useSequenceUtils.test.ts +28 -0
  382. package/src/__tests__/docs/frontendDocsCatalog.test.ts +44 -9
  383. package/src/__tests__/styles/baseControlsRules.test.ts +115 -0
  384. package/src/__tests__/styles/controlRefreshRules.test.ts +218 -0
  385. package/src/__tests__/styles/cssTokens.test.ts +7 -5
  386. package/src/__tests__/styles/darkModeRules.test.ts +47 -0
  387. package/src/__tests__/styles/menusShellRefresh.test.ts +75 -0
  388. package/src/__tests__/templates/templates.test.ts +65 -15
  389. package/src/__tests__/templates/templatesDeprecation.test.ts +78 -0
  390. package/src/__tests__/utils/permissions.test.ts +0 -68
  391. package/src/__tests__/utils/plotlyTemplate.test.ts +69 -0
  392. package/src/__tests__/utils/sampleTypeMarker.test.ts +54 -0
  393. package/src/components/ActionMenu.vue +44 -23
  394. package/src/components/AdductText.story.vue +18 -0
  395. package/src/components/AdductText.vue +7 -1
  396. package/src/components/AlertBox.vue +3 -7
  397. package/src/components/AppAvatarMenu.vue +12 -10
  398. package/src/components/AppSidebar.vue +1 -1
  399. package/src/components/AppTopBar.story.vue +47 -4
  400. package/src/components/AppTopBar.vue +16 -22
  401. package/src/components/ArtifactSelectorModal.story.vue +1 -1
  402. package/src/components/ArtifactSelectorModal.vue +48 -160
  403. package/src/components/AuditTrail.vue +26 -12
  404. package/src/components/AutoGroupModal.vue +1 -1
  405. package/src/components/BaseCheckbox.story.vue +58 -2
  406. package/src/components/BaseCheckbox.vue +21 -3
  407. package/src/components/BaseInput.story.vue +51 -0
  408. package/src/components/BaseInput.vue +62 -1
  409. package/src/components/BaseModal.story.vue +55 -0
  410. package/src/components/BaseModal.vue +83 -50
  411. package/src/components/BaseRadioGroup.vue +1 -1
  412. package/src/components/BaseSlider.story.vue +36 -0
  413. package/src/components/BaseSlider.vue +56 -8
  414. package/src/components/BaseToggle.vue +1 -7
  415. package/src/components/BatchProgressList.vue +50 -52
  416. package/src/components/BioTemplatePresetWorkspaceView.vue +1 -1
  417. package/src/components/Breadcrumb.story.vue +1 -1
  418. package/src/components/Breadcrumb.vue +50 -15
  419. package/src/components/ChartContainer.story.vue +42 -0
  420. package/src/components/ChartContainer.vue +22 -1
  421. package/src/components/ChemicalFormula.story.vue +11 -11
  422. package/src/components/ChemicalFormula.vue +1 -0
  423. package/src/components/CollapsibleCard.vue +12 -32
  424. package/src/components/ComponentBindingRenderer.vue +6 -8
  425. package/src/components/ConcentrationInput.story.vue +1 -1
  426. package/src/components/ConcentrationInput.vue +8 -14
  427. package/src/components/ControlWorkspaceView.vue +1 -1
  428. package/src/components/DataFrame.story.vue +45 -2
  429. package/src/components/DataFrame.vue +28 -13
  430. package/src/components/DatePicker.story.vue +11 -0
  431. package/src/components/DatePicker.vue +5 -5
  432. package/src/components/DateTimePicker.story.vue +1 -1
  433. package/src/components/DateTimePicker.vue +8 -5
  434. package/src/components/Divider.story.vue +1 -1
  435. package/src/components/DoseCalculator.vue +44 -51
  436. package/src/components/DoseCalculatorVolumeField.vue +22 -35
  437. package/src/components/DoseDesignWorkspaceView.vue +1 -1
  438. package/src/components/EmptyState.story.vue +4 -4
  439. package/src/components/EmptyState.vue +4 -2
  440. package/src/components/ExperimentPopover.story.vue +2 -2
  441. package/src/components/ExperimentPopover.vue +6 -4
  442. package/src/components/ExperimentSelectorModal.story.vue +2 -1
  443. package/src/components/ExperimentSelectorModal.vue +91 -261
  444. package/src/components/ExperimentTimeline.story.vue +29 -0
  445. package/src/components/ExperimentTimeline.vue +20 -0
  446. package/src/components/FilePicker.story.vue +65 -10
  447. package/src/components/FilePicker.vue +203 -121
  448. package/src/components/FitPanel.story.vue +72 -6
  449. package/src/components/FitPanel.vue +70 -18
  450. package/src/components/FormField.vue +2 -0
  451. package/src/components/FormulaInput.story.vue +6 -0
  452. package/src/components/FormulaInput.vue +49 -70
  453. package/src/components/GeneratedPathInput.story.vue +121 -8
  454. package/src/components/GeneratedPathInput.vue +155 -86
  455. package/src/components/GeneratedPlotlyResult.vue +1 -1
  456. package/src/components/GeneratedPluginView.vue +4 -4
  457. package/src/components/GeneratedResultRenderer.vue +19 -0
  458. package/src/components/InstrumentStateBadge.story.vue +41 -0
  459. package/src/components/InstrumentStateBadge.vue +24 -14
  460. package/src/components/JobsStatusTray.vue +30 -8
  461. package/src/components/MoleculeInput.vue +12 -7
  462. package/src/components/MultiSelect.vue +3 -3
  463. package/src/components/PlateEditor.story.vue +333 -0
  464. package/src/components/PlateEditor.vue +793 -0
  465. package/src/components/PlotlyChart.story.vue +37 -1
  466. package/src/components/PlotlyChart.vue +86 -16
  467. package/src/components/PluginWorkspaceView.props.ts +1 -7
  468. package/src/components/PluginWorkspaceView.vue +0 -4
  469. package/src/components/ProgressBar.story.vue +0 -30
  470. package/src/components/ProgressBar.vue +3 -53
  471. package/src/components/ProtocolStepEditor.story.vue +8 -0
  472. package/src/components/ProtocolStepEditor.vue +55 -145
  473. package/src/components/ProtocolStepParameterField.vue +55 -93
  474. package/src/components/ReagentList.presentation.ts +7 -6
  475. package/src/components/ReagentList.vue +18 -17
  476. package/src/components/SampleHierarchyTree.story.vue +19 -0
  477. package/src/components/SampleHierarchyTree.vue +47 -14
  478. package/src/components/SampleLegend.vue +12 -4
  479. package/src/components/SampleSelector.story.vue +5 -1
  480. package/src/components/SampleSelector.vue +25 -15
  481. package/src/components/SampleSelectorGroupNode.vue +10 -20
  482. package/src/components/SampleSelectorSampleRow.vue +7 -18
  483. package/src/components/ScheduleCalendar.story.vue +14 -0
  484. package/src/components/ScheduleCalendar.vue +13 -1
  485. package/src/components/ScientificNumber.story.vue +15 -2
  486. package/src/components/ScientificNumber.vue +22 -26
  487. package/src/components/SearchableSelect.vue +14 -9
  488. package/src/components/SecretInput.vue +1 -1
  489. package/src/components/SegmentedControl.story.vue +23 -0
  490. package/src/components/SegmentedControl.vue +6 -1
  491. package/src/components/SequenceInput.story.vue +27 -5
  492. package/src/components/SequenceInput.vue +74 -29
  493. package/src/components/SequenceProgressBar.vue +0 -1
  494. package/src/components/SettingsModal.schema.ts +4 -2
  495. package/src/components/SettingsModal.story.vue +83 -22
  496. package/src/components/SettingsModal.vue +338 -79
  497. package/src/components/Skeleton.vue +6 -35
  498. package/src/components/SmartGroup.types.ts +2 -2
  499. package/src/components/SmartGroupFieldRecipe.groups.ts +4 -1
  500. package/src/components/SmartGroupFieldRecipe.vue +14 -8
  501. package/src/components/SmartGroupManual.vue +14 -11
  502. package/src/components/StepWizard.vue +16 -19
  503. package/src/components/TagsInput.story.vue +16 -11
  504. package/src/components/TagsInput.vue +20 -3
  505. package/src/components/TimePicker.story.vue +38 -3
  506. package/src/components/TimePicker.vue +26 -11
  507. package/src/components/TimeRangeInput.story.vue +50 -1
  508. package/src/components/TimeRangeInput.vue +36 -17
  509. package/src/components/UnitInput.story.vue +1 -1
  510. package/src/components/UnitInput.vue +173 -107
  511. package/src/components/WellPlate.colors.ts +7 -6
  512. package/src/components/WellPlate.geometry.ts +3 -0
  513. package/src/components/WellPlate.interaction.ts +39 -5
  514. package/src/components/WellPlate.rendering.ts +21 -27
  515. package/src/components/WellPlate.sampleDrop.ts +20 -12
  516. package/src/components/WellPlate.story.vue +18 -7
  517. package/src/components/WellPlate.vue +28 -22
  518. package/src/components/index.ts +34 -31
  519. package/src/components/internal/AppTopBarPageSelectorInternal.vue +13 -7
  520. package/src/components/internal/AppTopBarPillNavInternal.vue +12 -7
  521. package/src/components/internal/CalendarGridPanelInternal.vue +1 -1
  522. package/src/components/internal/FilePickerListInternal.vue +318 -0
  523. package/src/components/internal/FilePickerPreviewInternal.vue +54 -52
  524. package/src/components/internal/PlateEditorBindingInternal.vue +37 -0
  525. package/src/components/internal/ResourcePickerListInternal.vue +237 -0
  526. package/src/components/internal/SettingsPaneHeadInternal.vue +41 -0
  527. package/src/components/internal/WellEditPopupInternal.vue +219 -146
  528. package/src/components/internal/WorkspaceShellInternal.vue +0 -6
  529. package/src/components/internal/filePickerPresentation.ts +30 -0
  530. package/src/components/internal/generatedJobsApi.ts +12 -0
  531. package/src/composables/autoGroup/index.ts +3 -0
  532. package/src/composables/controlSchemaAdapters.ts +0 -4
  533. package/src/composables/controlSchemaFormFields.ts +0 -4
  534. package/src/composables/controlSchemaTypes.ts +4 -43
  535. package/src/composables/createFilePickerAdapter.ts +90 -22
  536. package/src/composables/filePicker/localFiles.ts +1 -0
  537. package/src/composables/filePicker/usePickerNavigation.ts +29 -2
  538. package/src/composables/index.ts +2 -71
  539. package/src/composables/pluginWorkspaceModel.ts +0 -3
  540. package/src/composables/useAutoGroup.ts +10 -0
  541. package/src/composables/useBioTemplateComponents.ts +15 -3
  542. package/src/composables/useBioTemplateControls.ts +5 -1
  543. package/src/composables/useBioTemplatePackWorkspace.ts +2 -0
  544. package/src/composables/useBioTemplatePresetWorkspace.ts +5 -1
  545. package/src/composables/useBioTemplateWorkspace.ts +5 -1
  546. package/src/composables/useChemicalFormula.ts +39 -13
  547. package/src/composables/useDropdownState.ts +6 -1
  548. package/src/composables/useExperimentSave.ts +5 -1
  549. package/src/composables/useFileBrowser.ts +3 -2
  550. package/src/composables/useFilePicker.ts +98 -13
  551. package/src/composables/useFocusTrap.ts +9 -6
  552. package/src/composables/useGeneratedAnalysis.ts +38 -0
  553. package/src/composables/useGroupAssignment.ts +5 -1
  554. package/src/composables/useJobsStatusTray.ts +5 -5
  555. package/src/composables/useMenuKeyboard.ts +5 -3
  556. package/src/composables/usePlatformFilePickerAdapter.ts +26 -4
  557. package/src/composables/usePluginClient.ts +1 -1
  558. package/src/composables/usePluginWorkspace.ts +0 -1
  559. package/src/composables/useRackEditor.ts +202 -12
  560. package/src/composables/useSequenceUtils.ts +20 -2
  561. package/src/composables/useTemplateCollection.ts +5 -1
  562. package/src/composables/workspaceRecipes.ts +1 -0
  563. package/src/index.ts +9 -3
  564. package/src/instrument.ts +6 -0
  565. package/src/lcms.ts +11 -0
  566. package/src/permissions.ts +2 -59
  567. package/src/styles/components/action-menu.css +9 -38
  568. package/src/styles/components/adduct-text.css +15 -3
  569. package/src/styles/components/alert-box.css +19 -70
  570. package/src/styles/components/app-avatar-menu.css +22 -57
  571. package/src/styles/components/app-container.css +4 -4
  572. package/src/styles/components/app-layout.css +18 -18
  573. package/src/styles/components/app-page-selector.css +50 -105
  574. package/src/styles/components/app-pill-nav.css +24 -42
  575. package/src/styles/components/app-sidebar.css +2 -2
  576. package/src/styles/components/app-top-bar.css +78 -55
  577. package/src/styles/components/artifact-selector-modal.css +1 -211
  578. package/src/styles/components/audit-trail.css +45 -38
  579. package/src/styles/components/avatar.css +1 -1
  580. package/src/styles/components/batch-progress-list.css +179 -95
  581. package/src/styles/components/breadcrumb.css +34 -15
  582. package/src/styles/components/calendar.css +2 -8
  583. package/src/styles/components/chart-container.css +81 -38
  584. package/src/styles/components/checkbox.css +8 -6
  585. package/src/styles/components/chemical-formula.css +8 -6
  586. package/src/styles/components/collapsible-card.css +6 -46
  587. package/src/styles/components/concentration-input.css +1 -10
  588. package/src/styles/components/dataframe.css +48 -67
  589. package/src/styles/components/date-picker.css +124 -62
  590. package/src/styles/components/datetime-picker.css +81 -47
  591. package/src/styles/components/divider.css +2 -4
  592. package/src/styles/components/dose-calculator.css +9 -135
  593. package/src/styles/components/empty-state.css +26 -35
  594. package/src/styles/components/experiment-code-badge.css +1 -1
  595. package/src/styles/components/experiment-popover.css +16 -83
  596. package/src/styles/components/experiment-selector-modal.css +9 -226
  597. package/src/styles/components/experiment-timeline.css +120 -50
  598. package/src/styles/components/file-picker.css +323 -299
  599. package/src/styles/components/file-uploader.css +4 -6
  600. package/src/styles/components/fit-panel.css +108 -22
  601. package/src/styles/components/form-field.css +6 -4
  602. package/src/styles/components/formula-input.css +121 -48
  603. package/src/styles/components/group-assigner.css +1 -3
  604. package/src/styles/components/icon-button.css +15 -37
  605. package/src/styles/components/input.css +91 -2
  606. package/src/styles/components/instrument-monitor.css +37 -447
  607. package/src/styles/components/jobs-status-tray.css +82 -61
  608. package/src/styles/components/loading-spinner.css +18 -0
  609. package/src/styles/components/mobile-support-gate.css +15 -17
  610. package/src/styles/components/modal.css +44 -33
  611. package/src/styles/components/molecule-input.css +31 -16
  612. package/src/styles/components/multi-select.css +33 -29
  613. package/src/styles/components/number-input.css +1 -1
  614. package/src/styles/components/plate-editor.css +497 -0
  615. package/src/styles/components/popover.css +162 -0
  616. package/src/styles/components/progress-bar.css +1 -70
  617. package/src/styles/components/protocol-step-editor.css +21 -333
  618. package/src/styles/components/radio-group.css +9 -18
  619. package/src/styles/components/reagent-editor.css +3 -7
  620. package/src/styles/components/reagent-list.css +63 -69
  621. package/src/styles/components/resource-card.css +4 -6
  622. package/src/styles/components/resource-picker-list.css +212 -0
  623. package/src/styles/components/sample-hierarchy-tree.css +83 -65
  624. package/src/styles/components/sample-legend.css +18 -7
  625. package/src/styles/components/sample-selector.css +41 -68
  626. package/src/styles/components/schedule-calendar.css +59 -54
  627. package/src/styles/components/scientific-number.css +72 -18
  628. package/src/styles/components/searchable-select.css +17 -26
  629. package/src/styles/components/secret-input.css +20 -23
  630. package/src/styles/components/section-card.css +3 -5
  631. package/src/styles/components/segmented-control.css +14 -1
  632. package/src/styles/components/select.css +19 -8
  633. package/src/styles/components/sequence-input.css +85 -37
  634. package/src/styles/components/sequence-progress-bar.css +18 -37
  635. package/src/styles/components/settings-modal.css +683 -34
  636. package/src/styles/components/skeleton.css +24 -23
  637. package/src/styles/components/slider.css +74 -8
  638. package/src/styles/components/smart-group.css +27 -39
  639. package/src/styles/components/status-indicator.css +1 -1
  640. package/src/styles/components/step-wizard.css +62 -99
  641. package/src/styles/components/tabs.css +2 -6
  642. package/src/styles/components/tags-input.css +64 -54
  643. package/src/styles/components/textarea.css +2 -2
  644. package/src/styles/components/time-picker.css +67 -38
  645. package/src/styles/components/time-range-input.css +16 -18
  646. package/src/styles/components/toast.css +1 -1
  647. package/src/styles/components/toggle.css +21 -31
  648. package/src/styles/components/tooltip.css +13 -15
  649. package/src/styles/components/unit-input.css +86 -36
  650. package/src/styles/components/well-edit-popup.css +111 -189
  651. package/src/styles/components/well-plate.css +7 -7
  652. package/src/styles/index.css +5 -7
  653. package/src/styles/variables.css +35 -7
  654. package/src/templates/adapters.ts +4 -0
  655. package/src/templates/assayMatrixAdapters.ts +8 -1
  656. package/src/templates/assayMatrixBuilder.ts +1 -0
  657. package/src/templates/builderPresetControls.ts +1 -0
  658. package/src/templates/calibrationCurveAdapters.ts +3 -0
  659. package/src/templates/calibrationCurveBuilder.ts +1 -0
  660. package/src/templates/catalog.ts +6 -2
  661. package/src/templates/componentBindingCatalog.ts +1 -1
  662. package/src/templates/componentBindings.ts +31 -5
  663. package/src/templates/componentDoseResponseProps.ts +0 -1
  664. package/src/templates/componentPlateHelpers.ts +22 -1
  665. package/src/templates/componentPlateMapProps.ts +7 -5
  666. package/src/templates/componentQpcrPlateProps.ts +0 -1
  667. package/src/templates/controlSchemas.ts +9 -0
  668. package/src/templates/defaultBioTemplateBuilder.ts +1 -0
  669. package/src/templates/doseResponseAdapters.ts +2 -0
  670. package/src/templates/doseResponseBuilder.ts +1 -0
  671. package/src/templates/elisaAssayCollectionBuilder.ts +1 -0
  672. package/src/templates/flowCytometryAssayCollectionBuilder.ts +1 -0
  673. package/src/templates/flowCytometryPanelBuilder.ts +1 -0
  674. package/src/templates/flowPanelAdapters.ts +3 -0
  675. package/src/templates/index.ts +4 -0
  676. package/src/templates/instrumentRunAdapters.ts +13 -2
  677. package/src/templates/instrumentRunBuilder.ts +1 -0
  678. package/src/templates/lcmsBatchCollectionBuilder.ts +1 -0
  679. package/src/templates/packs.ts +4 -0
  680. package/src/templates/plateMapAdapters.ts +2 -0
  681. package/src/templates/plateMapBuilder.ts +1 -0
  682. package/src/templates/presets.ts +6 -2
  683. package/src/templates/protocolAdapters.ts +4 -0
  684. package/src/templates/protocolStepsBuilder.ts +1 -0
  685. package/src/templates/qpcrAdapters.ts +4 -0
  686. package/src/templates/qpcrExpressionCollectionBuilder.ts +1 -0
  687. package/src/templates/qpcrPlateBuilder.ts +1 -0
  688. package/src/templates/reagentAdapters.ts +4 -0
  689. package/src/templates/reagentListBuilder.ts +1 -0
  690. package/src/templates/samplePrepAdapters.ts +3 -0
  691. package/src/templates/samplePrepBuilder.ts +1 -0
  692. package/src/templates/sampleSheetAdapters.ts +4 -0
  693. package/src/templates/sampleSheetBuilder.ts +1 -0
  694. package/src/templates/targetedMetabolomicsCollectionBuilder.ts +1 -0
  695. package/src/templates/templateEnvelopes.ts +8 -0
  696. package/src/templates/templatePackCollectionBuilder.ts +1 -0
  697. package/src/templates/templatePresetCollectionBuilder.ts +2 -0
  698. package/src/templates/templateValidators.ts +12 -0
  699. package/src/templates/timeCourseAdapters.ts +4 -0
  700. package/src/templates/timeCourseBuilder.ts +1 -0
  701. package/src/templates/wellPlateScreenCollectionBuilder.ts +1 -0
  702. package/src/templates/westernBlotAssayCollectionBuilder.ts +1 -0
  703. package/src/types/auth.ts +0 -37
  704. package/src/types/componentLabTypes.ts +16 -13
  705. package/src/types/componentWorkflowTypes.ts +29 -0
  706. package/src/types/components.ts +43 -20
  707. package/src/types/fileBrowserTypes.ts +15 -0
  708. package/src/types/filePicker.ts +19 -1
  709. package/src/types/generated-ui.ts +15 -0
  710. package/src/types/index.ts +12 -11
  711. package/src/types/instrument.ts +47 -15
  712. package/src/types/platform.ts +2 -0
  713. package/src/utils/color.ts +16 -1
  714. package/src/utils/formModelSync.ts +1 -1
  715. package/src/utils/plotlyTemplate.ts +39 -0
  716. package/src/utils/rack.ts +16 -0
  717. package/src/utils/sampleTypeMarker.ts +44 -0
  718. package/dist/ExperimentPopover-CJdNlCZb.js +0 -451
  719. package/dist/ExperimentPopover-CJdNlCZb.js.map +0 -1
  720. package/dist/ExperimentSelectorModal-DHE9k8TP.js +0 -507
  721. package/dist/ExperimentSelectorModal-DHE9k8TP.js.map +0 -1
  722. package/dist/SettingsModal-DELMkUFR.js +0 -492
  723. package/dist/SettingsModal-DELMkUFR.js.map +0 -1
  724. package/dist/Skeleton-jhF9wUkU.js +0 -485
  725. package/dist/Skeleton-jhF9wUkU.js.map +0 -1
  726. package/dist/__tests__/composables/usePluginConfig.test.d.ts +0 -15
  727. package/dist/chunk-BoAXSpZd.js +0 -33
  728. package/dist/components/AppPluginSwitcher.vue.d.ts +0 -40
  729. package/dist/components/ColorSlider.vue.d.ts +0 -34
  730. package/dist/components/DropdownButton.vue.d.ts +0 -49
  731. package/dist/components/FileBrowserModal.vue.d.ts +0 -99
  732. package/dist/components/InstrumentAlertLog.vue.d.ts +0 -22
  733. package/dist/components/InstrumentStatusCard.vue.d.ts +0 -13
  734. package/dist/components/LcmsSequenceTable.vue.d.ts +0 -54
  735. package/dist/components/PlateMapEditor.vue.d.ts +0 -50
  736. package/dist/components/RackEditor.vue.d.ts +0 -78
  737. package/dist/components/fileBrowserPresentation.d.ts +0 -10
  738. package/dist/components/internal/FileBrowserDialogInternal.vue.d.ts +0 -34
  739. package/dist/components/internal/FileBrowserListingInternal.vue.d.ts +0 -25
  740. package/dist/components/internal/FileBrowserToolbarInternal.vue.d.ts +0 -26
  741. package/dist/components/internal/PlateMapEditorToolbarInternal.vue.d.ts +0 -28
  742. package/dist/components-Bbg_gtzF.js.map +0 -1
  743. package/dist/composables/useAsync.d.ts +0 -132
  744. package/dist/composables/useAuth.d.ts +0 -47
  745. package/dist/composables/useCommandHistory.d.ts +0 -33
  746. package/dist/composables/useOptimisticMutation.d.ts +0 -32
  747. package/dist/composables/usePasskey.d.ts +0 -10
  748. package/dist/composables/usePluginConfig.d.ts +0 -27
  749. package/dist/composables/useResourceCrud.d.ts +0 -44
  750. package/dist/composables/useWellPainting.d.ts +0 -39
  751. package/dist/composables/useWellPlateAdapter.d.ts +0 -40
  752. package/dist/composables/useWellPlateEditor.d.ts +0 -33
  753. package/dist/composables/useWellPlateValidation.d.ts +0 -31
  754. package/dist/composables-BCbYb2lA.js +0 -2356
  755. package/dist/composables-BCbYb2lA.js.map +0 -1
  756. package/dist/errors-BLuqMee5.js.map +0 -1
  757. package/dist/experiment-CVDRAnqp.js +0 -90
  758. package/dist/experiment-CVDRAnqp.js.map +0 -1
  759. package/dist/experiment-utils-CV2Wza3z.js.map +0 -1
  760. package/dist/plotly.min-c2Sez60c.js +0 -180634
  761. package/dist/plotly.min-c2Sez60c.js.map +0 -1
  762. package/dist/templates-NuaNHohp.js +0 -5260
  763. package/dist/templates-NuaNHohp.js.map +0 -1
  764. package/dist/useControlSchema-vLiRPUmj.js +0 -7301
  765. package/dist/useControlSchema-vLiRPUmj.js.map +0 -1
  766. package/dist/useDropdownState-C7hRiVQf.js +0 -63
  767. package/dist/useDropdownState-C7hRiVQf.js.map +0 -1
  768. package/dist/useExperimentSelector-G_CAOFTX.js +0 -328
  769. package/dist/useExperimentSelector-G_CAOFTX.js.map +0 -1
  770. package/dist/useFormBuilder-D37ajgS8.js +0 -729
  771. package/dist/useFormBuilder-D37ajgS8.js.map +0 -1
  772. package/dist/validation-ChMyixAf.js.map +0 -1
  773. package/src/__tests__/components/AppPluginSwitcher.test.ts +0 -44
  774. package/src/__tests__/components/DropdownButton.test.ts +0 -628
  775. package/src/__tests__/components/FileBrowserModal.test.ts +0 -460
  776. package/src/__tests__/components/InstrumentAlertLog.test.ts +0 -59
  777. package/src/__tests__/components/LcmsSequenceTable.test.ts +0 -79
  778. package/src/__tests__/components/PlateMapEditorToolbarInternal.test.ts +0 -54
  779. package/src/__tests__/components/RackEditor.test.ts +0 -169
  780. package/src/__tests__/composables/useAuth.test.ts +0 -233
  781. package/src/__tests__/composables/useCommandHistory.test.ts +0 -43
  782. package/src/__tests__/composables/useOptimisticMutation.test.ts +0 -40
  783. package/src/__tests__/composables/usePluginConfig.test.ts +0 -497
  784. package/src/__tests__/composables/useResourceCrud.test.ts +0 -56
  785. package/src/__tests__/composables/useWellPainting.test.ts +0 -52
  786. package/src/__tests__/composables/useWellPlateAdapter.test.ts +0 -50
  787. package/src/__tests__/composables/useWellPlateValidation.test.ts +0 -42
  788. package/src/components/AppPluginSwitcher.story.vue +0 -87
  789. package/src/components/AppPluginSwitcher.vue +0 -134
  790. package/src/components/ColorSlider.story.vue +0 -120
  791. package/src/components/ColorSlider.vue +0 -160
  792. package/src/components/DropdownButton.story.vue +0 -102
  793. package/src/components/DropdownButton.vue +0 -181
  794. package/src/components/FileBrowserModal.story.vue +0 -203
  795. package/src/components/FileBrowserModal.vue +0 -384
  796. package/src/components/InstrumentAlertLog.vue +0 -187
  797. package/src/components/InstrumentStatusCard.vue +0 -184
  798. package/src/components/LcmsSequenceTable.vue +0 -222
  799. package/src/components/PlateMapEditor.story.vue +0 -92
  800. package/src/components/PlateMapEditor.vue +0 -423
  801. package/src/components/RackEditor.story.vue +0 -100
  802. package/src/components/RackEditor.vue +0 -429
  803. package/src/components/fileBrowserPresentation.ts +0 -39
  804. package/src/components/internal/FileBrowserDialogInternal.vue +0 -75
  805. package/src/components/internal/FileBrowserListingInternal.vue +0 -197
  806. package/src/components/internal/FileBrowserToolbarInternal.vue +0 -136
  807. package/src/components/internal/FilePickerTreeInternal.vue +0 -238
  808. package/src/components/internal/PlateMapEditorToolbarInternal.vue +0 -128
  809. package/src/composables/useAsync.ts +0 -327
  810. package/src/composables/useAuth.ts +0 -458
  811. package/src/composables/useCommandHistory.ts +0 -117
  812. package/src/composables/useOptimisticMutation.ts +0 -97
  813. package/src/composables/usePasskey.ts +0 -216
  814. package/src/composables/usePluginConfig.ts +0 -252
  815. package/src/composables/useResourceCrud.ts +0 -235
  816. package/src/composables/useWellPainting.ts +0 -167
  817. package/src/composables/useWellPlateAdapter.ts +0 -151
  818. package/src/composables/useWellPlateEditor.ts +0 -415
  819. package/src/composables/useWellPlateValidation.ts +0 -89
  820. package/src/plotly-dist.d.ts +0 -3
  821. package/src/styles/components/app-plugin-switcher.css +0 -196
  822. package/src/styles/components/color-slider.css +0 -110
  823. package/src/styles/components/dropdown-button.css +0 -280
  824. package/src/styles/components/file-browser-modal.css +0 -489
  825. package/src/styles/components/lcms-sequence-table.css +0 -204
  826. package/src/styles/components/plate-map-editor.css +0 -464
  827. package/src/styles/components/rack-editor.css +0 -287
  828. /package/dist/__tests__/components/{AppPluginSwitcher.test.d.ts → AlertBox.test.d.ts} +0 -0
  829. /package/dist/__tests__/components/{DropdownButton.test.d.ts → AuditTrail.test.d.ts} +0 -0
  830. /package/dist/__tests__/components/{FileBrowserModal.test.d.ts → BaseCheckbox.test.d.ts} +0 -0
  831. /package/dist/__tests__/components/{InstrumentAlertLog.test.d.ts → BaseSlider.test.d.ts} +0 -0
  832. /package/dist/__tests__/components/{LcmsSequenceTable.test.d.ts → DoseCalculator.test.d.ts} +0 -0
  833. /package/dist/__tests__/components/{PlateMapEditorToolbarInternal.test.d.ts → FileUploader.test.d.ts} +0 -0
  834. /package/dist/__tests__/components/{RackEditor.test.d.ts → FitPanel.test.d.ts} +0 -0
  835. /package/dist/__tests__/{composables/useAuth.test.d.ts → components/FormulaInput.test.d.ts} +0 -0
  836. /package/dist/__tests__/{composables/useCommandHistory.test.d.ts → components/InstrumentStateBadge.test.d.ts} +0 -0
  837. /package/dist/__tests__/{composables/useOptimisticMutation.test.d.ts → components/MoleculeInput.test.d.ts} +0 -0
  838. /package/dist/__tests__/{composables/useResourceCrud.test.d.ts → components/PlateEditor.test.d.ts} +0 -0
  839. /package/dist/__tests__/{composables/useWellPainting.test.d.ts → components/PlateEditorBindingInternal.test.d.ts} +0 -0
  840. /package/dist/__tests__/{composables/useWellPlateAdapter.test.d.ts → components/ResourcePickerListInternal.test.d.ts} +0 -0
  841. /package/dist/__tests__/{composables/useWellPlateValidation.test.d.ts → components/SampleLegend.test.d.ts} +0 -0
@@ -0,0 +1,81 @@
1
+ import { mount } from '@vue/test-utils'
2
+ import { describe, expect, it } from 'vitest'
3
+ import SequenceInput from '../../components/SequenceInput.vue'
4
+
5
+ describe('SequenceInput', () => {
6
+ it('should lead the toolbar with the sequence type when tools are shown', () => {
7
+ const wrapper = mount(SequenceInput, { props: { modelValue: 'ATGC' } })
8
+ expect(wrapper.get('.mint-sequence-input__toolbar').element.firstElementChild?.className)
9
+ .toBe('mint-sequence-input__type-badge')
10
+ })
11
+ })
12
+
13
+ describe('SequenceInput problems (9c)', () => {
14
+ it('should keep emitting the sanitised value when invalid characters are typed', async () => {
15
+ const wrapper = mount(SequenceInput, { props: { modelValue: 'ATG' } })
16
+ await wrapper.get('textarea').setValue('ATGXZ')
17
+ expect(wrapper.emitted('update:modelValue')?.at(-1)).toEqual(['ATG'])
18
+ })
19
+
20
+ it('should keep the typed text in the field when invalid characters are typed', async () => {
21
+ const wrapper = mount(SequenceInput, { props: { modelValue: 'ATG' } })
22
+ await wrapper.get('textarea').setValue('ATGXZ')
23
+ await wrapper.setProps({ modelValue: 'ATG' })
24
+ expect((wrapper.get('textarea').element as HTMLTextAreaElement).value).toBe('ATGXZ')
25
+ })
26
+
27
+ it('should show an error naming the invalid characters when they are typed', async () => {
28
+ const wrapper = mount(SequenceInput, { props: { modelValue: 'ATG' } })
29
+ await wrapper.get('textarea').setValue('ATGXZ')
30
+ expect(wrapper.get('.mint-sequence-input__problem--error').text()).toBe('Invalid characters: X Z')
31
+ })
32
+
33
+ it('should mark the field as error when invalid characters are typed', async () => {
34
+ const wrapper = mount(SequenceInput, { props: { modelValue: 'ATG' } })
35
+ await wrapper.get('textarea').setValue('ATGX')
36
+ expect(wrapper.classes()).toContain('mint-sequence-input--error')
37
+ })
38
+
39
+ it('should warn with the count when the sequence has N bases', () => {
40
+ const wrapper = mount(SequenceInput, { props: { modelValue: 'ATNNG' } })
41
+ expect(wrapper.get('.mint-sequence-input__problem--warning').text()).toBe('2 ambiguous bases (N)')
42
+ })
43
+
44
+ it('should show the typed text when the parent replaces the value', async () => {
45
+ const wrapper = mount(SequenceInput, { props: { modelValue: 'ATG' } })
46
+ await wrapper.get('textarea').setValue('ATGX')
47
+ await wrapper.setProps({ modelValue: 'CCC' })
48
+ expect((wrapper.get('textarea').element as HTMLTextAreaElement).value).toBe('CCC')
49
+ })
50
+
51
+ it('should show the model value when a tool returns it to the last typed text', async () => {
52
+ const wrapper = mount(SequenceInput, {
53
+ props: { modelValue: '', 'onUpdate:modelValue': (value: string) => wrapper.setProps({ modelValue: value }) },
54
+ })
55
+ await wrapper.get('textarea').setValue('ACG')
56
+ const revComp = wrapper.findAll('button').find(button => button.text() === 'Rev Comp')!
57
+ await revComp.trigger('click')
58
+ await revComp.trigger('click')
59
+ expect((wrapper.get('textarea').element as HTMLTextAreaElement).value).toBe('ACG')
60
+ })
61
+
62
+ it('should not report protein residues typed after a DNA-like prefix when the type is auto', async () => {
63
+ const wrapper = mount(SequenceInput, { props: { modelValue: 'ATG' } })
64
+ await wrapper.get('textarea').setValue('ATGKLV')
65
+ expect(wrapper.find('.mint-sequence-input__problem--error').exists()).toBe(false)
66
+ })
67
+ })
68
+
69
+ describe('SequenceInput maxLength', () => {
70
+ it('should count only valid bases against maxLength when invalid characters are typed', async () => {
71
+ const wrapper = mount(SequenceInput, { props: { modelValue: '', type: 'dna', maxLength: 5 } })
72
+ await wrapper.get('textarea').setValue('AT??GC')
73
+ expect(wrapper.emitted('update:modelValue')?.at(-1)).toEqual(['ATGC'])
74
+ })
75
+
76
+ it('should cap the emitted sequence at maxLength bases when more are typed', async () => {
77
+ const wrapper = mount(SequenceInput, { props: { modelValue: '', type: 'dna', maxLength: 5 } })
78
+ await wrapper.get('textarea').setValue('ATGCATG')
79
+ expect(wrapper.emitted('update:modelValue')?.at(-1)).toEqual(['ATGCA'])
80
+ })
81
+ })
@@ -19,14 +19,14 @@ describe('SettingsModal schema helpers', () => {
19
19
  icon: '<svg />',
20
20
  fields: [
21
21
  { name: 'title', label: 'Title', type: 'text' },
22
- { name: 'adminOnly', label: 'Admin Only', type: 'text', requiresAdmin: true },
22
+ { name: 'adminOnly', label: 'Admin Only', type: 'text', access: { requiresAdmin: true } },
23
23
  ],
24
24
  columns: 2,
25
25
  },
26
26
  {
27
27
  id: 'hidden',
28
28
  label: 'Hidden',
29
- requiresAdmin: true,
29
+ access: { requiresAdmin: true },
30
30
  fields: [
31
31
  { name: 'secret', label: 'Secret', type: 'text' },
32
32
  ],
@@ -58,7 +58,7 @@ describe('SettingsModal schema helpers', () => {
58
58
  it('filters groups and fields with the caller access policy', () => {
59
59
  const filtered = filterSettingsSchemaByAccess(
60
60
  schema,
61
- (item) => !item.requiresAdmin
61
+ (item) => !item.access?.requiresAdmin
62
62
  )
63
63
 
64
64
  expect(filtered.groups).toHaveLength(1)
@@ -78,11 +78,11 @@ describe('SettingsModal schema helpers', () => {
78
78
  it('normalizes manual tabs before access filtering', () => {
79
79
  const tabs: SettingsTabInput[] = [
80
80
  'General',
81
- { id: 'admin', label: 'Admin', requiresAdmin: true },
81
+ { id: 'admin', label: 'Admin', access: { requiresAdmin: true } },
82
82
  ]
83
83
 
84
84
  expect(
85
- normalizeVisibleSettingsTabs(tabs, (item) => !item.requiresAdmin)
85
+ normalizeVisibleSettingsTabs(tabs, (item) => !item.access?.requiresAdmin)
86
86
  ).toEqual([
87
87
  { id: 'General', label: 'General' },
88
88
  ])
@@ -4,6 +4,7 @@ import { describe, expect, it } from 'vitest'
4
4
  import SettingsModal from '../../components/SettingsModal.vue'
5
5
  import { defineControlModel, type ControlSchema } from '../../composables/useControlSchema'
6
6
  import { useAuthStore } from '../../stores/auth'
7
+ import { colorPalettes, useSettingsStore } from '../../stores/settings'
7
8
  import type { SettingsModalSchema } from '../../types'
8
9
 
9
10
  describe('SettingsModal', () => {
@@ -27,6 +28,7 @@ describe('SettingsModal', () => {
27
28
  it('accepts string shorthand manual tabs', async () => {
28
29
  const wrapper = mountSettingsModal({
29
30
  tabs: ['General', 'Advanced'],
31
+ layout: 'horizontal',
30
32
  }, {
31
33
  'tab-General': '<div class="general-tab">General Content</div>',
32
34
  'tab-Advanced': '<div class="advanced-tab">Advanced Content</div>',
@@ -75,19 +77,20 @@ describe('SettingsModal', () => {
75
77
  ],
76
78
  }
77
79
 
78
- const wrapper = mountSettingsModal({ schema: baseSchema })
80
+ const wrapper = mountSettingsModal({ schema: baseSchema, layout: 'horizontal' })
79
81
 
80
- await wrapper.find('input').setValue('0.5')
82
+ await wrapper.find('.mint-settings-modal input').setValue('0.5')
81
83
  await wrapper.setProps({ schema: nextSchema })
82
84
 
85
+ // "1" = the tab's modified-from-default count (threshold 0.1 → 0.5).
83
86
  const tabs = wrapper.findAll('.mint-modal__tab')
84
- expect(tabs.map(tab => tab.text())).toEqual(['General', 'Advanced'])
85
- expect((wrapper.find('input').element as HTMLInputElement).value).toBe('0.5')
87
+ expect(tabs.map(tab => tab.text())).toEqual(['General 1', 'Advanced'])
88
+ expect((wrapper.find('.mint-settings-modal input').element as HTMLInputElement).value).toBe('0.5')
86
89
 
87
90
  await tabs[1].trigger('click')
88
91
 
89
92
  expect(wrapper.text()).toContain('Method')
90
- expect((wrapper.find('input').element as HTMLInputElement).value).toBe('linear')
93
+ expect((wrapper.find('.mint-settings-modal input').element as HTMLInputElement).value).toBe('linear')
91
94
  })
92
95
 
93
96
  it('uses controlled values when a schema changes', async () => {
@@ -120,10 +123,10 @@ describe('SettingsModal', () => {
120
123
  values: { threshold: '0.25' },
121
124
  })
122
125
 
123
- await wrapper.find('input').setValue('0.5')
126
+ await wrapper.find('.mint-settings-modal input').setValue('0.5')
124
127
  await wrapper.setProps({ schema: nextSchema })
125
128
 
126
- const inputs = wrapper.findAll('input')
129
+ const inputs = wrapper.findAll('.mint-settings-modal input')
127
130
  expect((inputs[0].element as HTMLInputElement).value).toBe('0.25')
128
131
  expect((inputs[1].element as HTMLInputElement).value).toBe('linear')
129
132
  expect(wrapper.emitted('update:values')?.at(-1)?.[0]).toMatchObject({
@@ -152,7 +155,7 @@ describe('SettingsModal', () => {
152
155
  },
153
156
  })
154
157
 
155
- await wrapper.find('input').setValue('0.5')
158
+ await wrapper.find('.mint-settings-modal input').setValue('0.5')
156
159
 
157
160
  expect(wrapper.emitted('update:values')?.at(-1)?.[0]).toEqual({
158
161
  threshold: 0.5,
@@ -177,13 +180,13 @@ describe('SettingsModal', () => {
177
180
  },
178
181
  }
179
182
 
180
- const wrapper = mountSettingsModal({ controls })
183
+ const wrapper = mountSettingsModal({ controls, layout: 'horizontal' })
181
184
 
182
185
  const tabs = wrapper.findAll('.mint-modal__tab')
183
186
  expect(tabs.map(tab => tab.text())).toEqual(['Parameters', 'Advanced'])
184
- expect((wrapper.find('input').element as HTMLInputElement).value).toBe('0.25')
187
+ expect((wrapper.find('.mint-settings-modal input').element as HTMLInputElement).value).toBe('0.25')
185
188
 
186
- await wrapper.find('input').setValue('0.5')
189
+ await wrapper.find('.mint-settings-modal input').setValue('0.5')
187
190
  await tabs[1].trigger('click')
188
191
 
189
192
  expect((wrapper.find('select').element as HTMLSelectElement).value).toBe('linear')
@@ -219,10 +222,10 @@ describe('SettingsModal', () => {
219
222
  },
220
223
  })
221
224
 
222
- expect((wrapper.find('input').element as HTMLInputElement).value).toBe('0.35')
225
+ expect((wrapper.find('.mint-settings-modal input').element as HTMLInputElement).value).toBe('0.35')
223
226
  expect((wrapper.find('select').element as HTMLSelectElement).value).toBe('logistic')
224
227
 
225
- await wrapper.find('input').setValue('0.5')
228
+ await wrapper.find('.mint-settings-modal input').setValue('0.5')
226
229
 
227
230
  expect(wrapper.emitted('update:values')?.at(-1)?.[0]).toMatchObject({
228
231
  threshold: 0.5,
@@ -252,9 +255,9 @@ describe('SettingsModal', () => {
252
255
 
253
256
  expect(wrapper.text()).toContain('Threshold')
254
257
  expect(wrapper.text()).toContain('Method')
255
- expect((wrapper.find('input').element as HTMLInputElement).value).toBe('0.25')
258
+ expect((wrapper.find('.mint-settings-modal input').element as HTMLInputElement).value).toBe('0.25')
256
259
 
257
- await wrapper.find('input').setValue('0.5')
260
+ await wrapper.find('.mint-settings-modal input').setValue('0.5')
258
261
 
259
262
  expect(wrapper.emitted('update:values')?.at(-1)?.[0]).toMatchObject({
260
263
  threshold: 0.5,
@@ -293,7 +296,7 @@ describe('SettingsModal', () => {
293
296
  },
294
297
  })
295
298
 
296
- expect((wrapper.find('input').element as HTMLInputElement).value).toBe('0.75')
299
+ expect((wrapper.find('.mint-settings-modal input').element as HTMLInputElement).value).toBe('0.75')
297
300
  expect((wrapper.find('select').element as HTMLSelectElement).value).toBe('linear')
298
301
  })
299
302
 
@@ -319,7 +322,7 @@ describe('SettingsModal', () => {
319
322
 
320
323
  expect(wrapper.text()).toContain('Threshold')
321
324
  expect(wrapper.find('.manual-tab').exists()).toBe(false)
322
- expect((wrapper.find('input').element as HTMLInputElement).value).toBe('0.25')
325
+ expect((wrapper.find('.mint-settings-modal input').element as HTMLInputElement).value).toBe('0.25')
323
326
  expect(wrapper.emitted('update:values')?.at(-1)?.[0]).toMatchObject({
324
327
  threshold: 0.25,
325
328
  })
@@ -333,14 +336,14 @@ describe('SettingsModal', () => {
333
336
  label: 'General',
334
337
  fields: [
335
338
  { name: 'common', label: 'Common', type: 'text', defaultValue: 'shared' },
336
- { name: 'adminSecret', label: 'Admin Secret', type: 'text', visibleFor: 'admin' },
337
- { name: 'userNote', label: 'User Note', type: 'text', visibleFor: 'user' },
339
+ { name: 'adminSecret', label: 'Admin Secret', type: 'text', access: { visibleFor: 'admin' } },
340
+ { name: 'userNote', label: 'User Note', type: 'text', access: { visibleFor: 'user' } },
338
341
  ],
339
342
  },
340
343
  {
341
344
  id: 'admin',
342
345
  label: 'Admin',
343
- visibleFor: 'admin',
346
+ access: { visibleFor: 'admin' },
344
347
  fields: [
345
348
  { name: 'adminOnly', label: 'Admin Only', type: 'text' },
346
349
  ],
@@ -355,7 +358,7 @@ describe('SettingsModal', () => {
355
358
  expect(userWrapper.text()).not.toContain('Admin Secret')
356
359
  expect(userWrapper.text()).not.toContain('Admin Only')
357
360
 
358
- const adminWrapper = mountSettingsModal({ schema, userType: 'admin' })
361
+ const adminWrapper = mountSettingsModal({ schema, userType: 'admin', layout: 'horizontal' })
359
362
 
360
363
  expect(adminWrapper.findAll('.mint-modal__tab').map(tab => tab.text())).toEqual([
361
364
  'General',
@@ -390,10 +393,10 @@ describe('SettingsModal', () => {
390
393
  {
391
394
  id: 'plugins',
392
395
  label: 'Plugins',
393
- permissions: ['plugins.configure'],
396
+ access: { permissions: ['plugins.configure'] },
394
397
  fields: [
395
398
  { name: 'registry', label: 'Registry', type: 'text' },
396
- { name: 'danger', label: 'Danger Zone', type: 'text', requiresAdmin: true },
399
+ { name: 'danger', label: 'Danger Zone', type: 'text', access: { requiresAdmin: true } },
397
400
  ],
398
401
  },
399
402
  ],
@@ -404,4 +407,349 @@ describe('SettingsModal', () => {
404
407
  expect(wrapper.text()).toContain('Registry')
405
408
  expect(wrapper.text()).not.toContain('Danger Zone')
406
409
  })
410
+
411
+ it('should hide an admin-only group from a non-admin when the Python SDK marks it admin', () => {
412
+ const pinia = createPinia()
413
+ useAuthStore(pinia).setUserInfo({
414
+ id: 2,
415
+ username: 'member',
416
+ shortname: null,
417
+ email: null,
418
+ role: 'member',
419
+ roleObj: { slug: 'member', permissions: ['plugins.configure'] },
420
+ isActive: true,
421
+ })
422
+ // The shape mint_sdk.schema.apply_settings_form_admin_policy emits for config_requires_admin plugins.
423
+ const schema: SettingsModalSchema = {
424
+ groups: [
425
+ { id: 'general', label: 'General', fields: [{ name: 'note', label: 'Note', type: 'text' }] },
426
+ {
427
+ id: 'storage',
428
+ label: 'Storage',
429
+ access: { requiresAdmin: true },
430
+ fields: [{ name: 'nasRoot', label: 'NAS root', type: 'text' }],
431
+ },
432
+ ],
433
+ }
434
+
435
+ const wrapper = mountSettingsModal({ schema }, {}, pinia)
436
+
437
+ expect(wrapper.text()).not.toContain('NAS root')
438
+ })
439
+
440
+ it('should read access rules only from the nested access policy', () => {
441
+ // The flat duplicates were removed in 1.3; a leftover flat key no longer gates anything.
442
+ const schema = {
443
+ groups: [
444
+ {
445
+ id: 'legacy',
446
+ label: 'Legacy',
447
+ visibleFor: 'admin',
448
+ fields: [{ name: 'legacyField', label: 'Legacy field', type: 'text' }],
449
+ },
450
+ ],
451
+ } as unknown as SettingsModalSchema
452
+
453
+ const wrapper = mountSettingsModal({ schema, userType: 'user' })
454
+
455
+ expect(wrapper.text()).toContain('Legacy field')
456
+ })
457
+
458
+ describe('redesign (5d)', () => {
459
+ const railSchema: SettingsModalSchema = {
460
+ groups: [
461
+ {
462
+ id: 'general',
463
+ label: 'General',
464
+ description: 'Name and locale',
465
+ fields: [
466
+ { name: 'pluginName', label: 'Plugin name', type: 'text', defaultValue: 'IC50', hint: 'Shown in breadcrumbs' },
467
+ ],
468
+ },
469
+ {
470
+ id: 'model',
471
+ label: 'Model',
472
+ description: 'Curve model and bounds',
473
+ fields: [
474
+ { name: 'bottom', label: 'Bottom', type: 'number', defaultValue: 0 },
475
+ { name: 'top', label: 'Top', type: 'number', defaultValue: 100 },
476
+ ],
477
+ },
478
+ {
479
+ id: 'qc',
480
+ label: 'Quality control',
481
+ fields: [
482
+ { name: 'minR2', label: 'Minimum R²', type: 'number', defaultValue: 0.95, hint: 'Fits below this threshold are flagged for review' },
483
+ ],
484
+ },
485
+ {
486
+ id: 'notifications',
487
+ label: 'Notifications',
488
+ fields: [
489
+ { name: 'emailQc', label: 'Email on QC failure', type: 'checkbox', defaultValue: false },
490
+ ],
491
+ },
492
+ ],
493
+ }
494
+
495
+ const shortSchema: SettingsModalSchema = {
496
+ groups: [
497
+ {
498
+ id: 'general',
499
+ label: 'General',
500
+ fields: [
501
+ { name: 'pluginName', label: 'Plugin name', type: 'text', defaultValue: 'IC50' },
502
+ { name: 'note', label: 'Note', type: 'text' },
503
+ ],
504
+ },
505
+ {
506
+ id: 'notifications',
507
+ label: 'Notifications',
508
+ fields: [
509
+ { name: 'emailQc', label: 'Email on QC failure', type: 'checkbox', defaultValue: false },
510
+ ],
511
+ },
512
+ ],
513
+ }
514
+
515
+ function railItem(wrapper: ReturnType<typeof mountSettingsModal>, label: string) {
516
+ return wrapper.findAll('.mint-modal__rail-item').find(item => item.find('.mint-modal__rail-item-label').text() === label)!
517
+ }
518
+
519
+ it('should render the rail when the schema has more than three groups', () => {
520
+ const wrapper = mountSettingsModal({ schema: railSchema })
521
+
522
+ expect(wrapper.find('.mint-modal__rail').exists()).toBe(true)
523
+ })
524
+
525
+ it('should stack every group without a rail when the schema has three groups or fewer', () => {
526
+ const wrapper = mountSettingsModal({ schema: shortSchema })
527
+
528
+ expect(wrapper.findAll('.mint-settings-modal__group')).toHaveLength(2)
529
+ })
530
+
531
+ it('should keep the tab strip when the layout is horizontal', () => {
532
+ const wrapper = mountSettingsModal({ schema: railSchema, layout: 'horizontal' })
533
+
534
+ expect(wrapper.findAll('.mint-modal__tab')).toHaveLength(4)
535
+ })
536
+
537
+ it('should split the rail into Plugin and Personal sections when appearance is shown', () => {
538
+ const wrapper = mountSettingsModal({ schema: railSchema, showAppearance: true })
539
+
540
+ expect(wrapper.findAll('.mint-modal__rail-section').map(heading => heading.text())).toEqual(['Plugin', 'Personal'])
541
+ })
542
+
543
+ it('should list and open Appearance first when appearanceFirst is set', () => {
544
+ const wrapper = mountSettingsModal({
545
+ tabs: [{ id: 'plugins', label: 'Plugins' }],
546
+ showAppearance: true,
547
+ appearanceFirst: true,
548
+ layout: 'vertical',
549
+ })
550
+
551
+ expect(wrapper.get('.mint-modal__rail-item--active').text()).toContain('Appearance')
552
+ })
553
+
554
+ it('should label a manual tab rail section from its section', () => {
555
+ const wrapper = mountSettingsModal({
556
+ tabs: [{ id: 'plugins', label: 'Plugins', section: 'Platform' }],
557
+ showAppearance: true,
558
+ appearanceFirst: true,
559
+ layout: 'vertical',
560
+ })
561
+
562
+ expect(wrapper.findAll('.mint-modal__rail-section').map(heading => heading.text())).toEqual(['Personal', 'Platform'])
563
+ })
564
+
565
+ it('should not render rail section headings when appearance is hidden', () => {
566
+ const wrapper = mountSettingsModal({ schema: railSchema })
567
+
568
+ expect(wrapper.find('.mint-modal__rail-section').exists()).toBe(false)
569
+ })
570
+
571
+ it('should show the group description in the pane header when a group is active', () => {
572
+ const wrapper = mountSettingsModal({ schema: railSchema })
573
+
574
+ expect(wrapper.get('.mint-modal__pane-header').text()).toContain('Name and locale')
575
+ })
576
+
577
+ it('should show the modified count in the rail when a group has changed fields', () => {
578
+ const wrapper = mountSettingsModal({ schema: railSchema, values: { bottom: 5, top: 50 } })
579
+
580
+ expect(railItem(wrapper, 'Model').get('.mint-modal__rail-item-meta').text()).toBe('2')
581
+ })
582
+
583
+ it('should mark a row modified when its value differs from the default', () => {
584
+ const wrapper = mountSettingsModal({ schema: railSchema, values: { pluginName: 'Dose' } })
585
+
586
+ expect(wrapper.find('.mint-settings-modal__row--modified').exists()).toBe(true)
587
+ })
588
+
589
+ it('should not mark a row modified when the field has no default', () => {
590
+ const wrapper = mountSettingsModal({ schema: shortSchema, values: { note: 'hello' } })
591
+
592
+ expect(wrapper.find('.mint-settings-modal__row--modified').exists()).toBe(false)
593
+ })
594
+
595
+ it('should not mark a stored secret modified when its default is null', () => {
596
+ const wrapper = mountSettingsModal({
597
+ schema: { groups: [{ id: 'auth', label: 'Auth', fields: [{ name: 'apiKey', label: 'API key', type: 'secret', defaultValue: null }] }] },
598
+ values: { apiKey: { $secret: 'sec_1', set: true } },
599
+ })
600
+
601
+ expect(wrapper.find('.mint-settings-modal__row--modified').exists()).toBe(false)
602
+ })
603
+
604
+ it('should restore the field default when the row reset button is clicked', async () => {
605
+ const wrapper = mountSettingsModal({ schema: railSchema, values: { pluginName: 'Dose' } })
606
+
607
+ await wrapper.get('.mint-settings-modal__reset').trigger('click')
608
+
609
+ expect(wrapper.emitted('update:values')?.at(-1)?.[0]).toMatchObject({ pluginName: 'IC50' })
610
+ })
611
+
612
+ it('should place the row reset in the field cell when the row is modified', () => {
613
+ const wrapper = mountSettingsModal({ schema: railSchema, values: { pluginName: 'Dose' } })
614
+
615
+ expect(wrapper.find('.mint-settings-modal__row-field > .mint-settings-modal__reset').exists()).toBe(true)
616
+ })
617
+
618
+ it('should restore every field in the group when Restore group defaults is clicked', async () => {
619
+ const wrapper = mountSettingsModal({ schema: railSchema, values: { bottom: 5, top: 50 } })
620
+ await railItem(wrapper, 'Model').trigger('click')
621
+
622
+ await wrapper.get('.mint-settings-modal__restore-group').trigger('click')
623
+
624
+ expect(wrapper.emitted('update:values')?.at(-1)?.[0]).toMatchObject({ bottom: 0, top: 100 })
625
+ })
626
+
627
+ it('should disable Restore group defaults when nothing in the group is modified', () => {
628
+ const wrapper = mountSettingsModal({ schema: railSchema })
629
+
630
+ expect(wrapper.get('.mint-settings-modal__restore-group').attributes('disabled')).toBeDefined()
631
+ })
632
+
633
+ it('should list matching fields from every group when searching by hint', async () => {
634
+ const wrapper = mountSettingsModal({ schema: railSchema })
635
+
636
+ await wrapper.get('.mint-settings-modal__search input').setValue('flagged')
637
+
638
+ expect(wrapper.findAll('.mint-settings-modal__row')).toHaveLength(1)
639
+ })
640
+
641
+ it('should label each search result with its group', async () => {
642
+ const wrapper = mountSettingsModal({ schema: railSchema })
643
+
644
+ await wrapper.get('.mint-settings-modal__search input').setValue('flagged')
645
+
646
+ expect(wrapper.get('.mint-settings-modal__row-group').text()).toBe('Quality control')
647
+ })
648
+
649
+ it('should show the result count in the pane header when searching', async () => {
650
+ const wrapper = mountSettingsModal({ schema: railSchema })
651
+
652
+ await wrapper.get('.mint-settings-modal__search input').setValue('o')
653
+
654
+ expect(wrapper.get('.mint-modal__pane-header').text()).toContain('5 results')
655
+ })
656
+
657
+ it('should show an empty state when nothing matches the search', async () => {
658
+ const wrapper = mountSettingsModal({ schema: railSchema })
659
+
660
+ await wrapper.get('.mint-settings-modal__search input').setValue('zzz')
661
+
662
+ expect(wrapper.find('.mint-settings-modal__empty').exists()).toBe(true)
663
+ })
664
+
665
+ it('should clear the search when a rail item is clicked', async () => {
666
+ const wrapper = mountSettingsModal({ schema: railSchema })
667
+ await wrapper.get('.mint-settings-modal__search input').setValue('flagged')
668
+
669
+ await railItem(wrapper, 'Model').trigger('click')
670
+
671
+ expect((wrapper.get('.mint-settings-modal__search input').element as HTMLInputElement).value).toBe('')
672
+ })
673
+
674
+ it('should render a checkbox field as a toggle inside settings rows', () => {
675
+ const wrapper = mountSettingsModal({ schema: shortSchema })
676
+
677
+ expect(wrapper.find('.mint-settings-modal__row .mint-toggle').exists()).toBe(true)
678
+ })
679
+
680
+ it('should print a toggle hint under the row when the boolean field has one', () => {
681
+ const wrapper = mountSettingsModal({
682
+ schema: { groups: [{ id: 'g', label: 'G', fields: [{ name: 'weighted', label: 'Weighted', type: 'toggle', hint: 'Use when variance differs' }] }] },
683
+ })
684
+
685
+ expect(wrapper.get('.mint-settings-modal__row-hint').text()).toBe('Use when variance differs')
686
+ })
687
+
688
+ it('should say changes take effect immediately before anything changes', () => {
689
+ const wrapper = mountSettingsModal({ schema: shortSchema })
690
+
691
+ expect(wrapper.get('.mint-settings-modal__status').text()).toBe('Changes take effect immediately')
692
+ })
693
+
694
+ it('should show the applied status after a value changes', async () => {
695
+ const wrapper = mountSettingsModal({ schema: shortSchema })
696
+
697
+ await wrapper.get('.mint-settings-modal input').setValue('Dose')
698
+
699
+ expect(wrapper.get('.mint-settings-modal__status').text()).toBe('Applied · changes take effect immediately')
700
+ })
701
+
702
+ it('should keep the not-yet-applied status when the parent replaces the values', async () => {
703
+ const wrapper = mountSettingsModal({ schema: shortSchema, values: { pluginName: 'IC50' } })
704
+
705
+ await wrapper.setProps({ values: { pluginName: 'Loaded' } })
706
+
707
+ expect(wrapper.get('.mint-settings-modal__status').text()).toBe('Changes take effect immediately')
708
+ })
709
+
710
+ it('should close when Done is clicked', async () => {
711
+ const wrapper = mountSettingsModal({ schema: shortSchema })
712
+
713
+ await wrapper.get('.mint-settings-modal__done').trigger('click')
714
+
715
+ expect(wrapper.emitted('update:modelValue')?.at(-1)).toEqual([false])
716
+ })
717
+
718
+ it('should render a custom footer slot in place of the Done button', () => {
719
+ const wrapper = mountSettingsModal({ schema: shortSchema }, { footer: '<button class="custom-save">Save</button>' })
720
+
721
+ expect(wrapper.find('.mint-settings-modal__done').exists()).toBe(false)
722
+ })
723
+
724
+ it('should render a preview card for each theme when appearance is shown', () => {
725
+ const wrapper = mountSettingsModal({ showAppearance: true })
726
+
727
+ expect(wrapper.findAll('.mint-settings-modal__theme')).toHaveLength(3)
728
+ })
729
+
730
+ it('should set the theme when a theme card is clicked', async () => {
731
+ const pinia = createPinia()
732
+ const wrapper = mountSettingsModal({ showAppearance: true }, {}, pinia)
733
+
734
+ await wrapper.findAll('.mint-settings-modal__theme')[1].trigger('click')
735
+
736
+ expect(useSettingsStore(pinia).theme).toBe('dark')
737
+ })
738
+
739
+ it('should render a swatch strip for each palette when appearance is shown', () => {
740
+ const wrapper = mountSettingsModal({ showAppearance: true })
741
+
742
+ expect(wrapper.findAll('.mint-settings-modal__palette')).toHaveLength(Object.keys(colorPalettes).length)
743
+ })
744
+
745
+ it('should resize the density preview when the density changes', async () => {
746
+ const pinia = createPinia()
747
+ const wrapper = mountSettingsModal({ showAppearance: true }, {}, pinia)
748
+
749
+ useSettingsStore(pinia).tableDensity = 'compact'
750
+ await wrapper.vm.$nextTick()
751
+
752
+ expect(wrapper.get('.mint-settings-modal__density-preview').classes()).toContain('mint-settings-modal__density-preview--compact')
753
+ })
754
+ })
407
755
  })
@@ -0,0 +1,23 @@
1
+ import { mount } from '@vue/test-utils'
2
+ import { describe, expect, it } from 'vitest'
3
+ import Skeleton from '../../components/Skeleton.vue'
4
+
5
+ describe('Skeleton', () => {
6
+ it('should carry its own shape class when a variant is set', () => {
7
+ const wrapper = mount(Skeleton, { props: { variant: 'circular' } })
8
+
9
+ expect(wrapper.classes()).toEqual(['mint-skeleton', 'mint-skeleton--circular', 'skeleton-wave'])
10
+ })
11
+
12
+ it('should breathe for pulse like it does for wave when animation is pulse', () => {
13
+ const wrapper = mount(Skeleton, { props: { animation: 'pulse' } })
14
+
15
+ expect(wrapper.classes()).toContain('skeleton-wave')
16
+ })
17
+
18
+ it('should stay static when animation is none', () => {
19
+ const wrapper = mount(Skeleton, { props: { animation: 'none' } })
20
+
21
+ expect(wrapper.classes()).not.toContain('skeleton-wave')
22
+ })
23
+ })
@@ -0,0 +1,12 @@
1
+ import { mount } from '@vue/test-utils'
2
+ import { describe, expect, it } from 'vitest'
3
+ import SmartGroupFieldRecipe from '../../components/SmartGroupFieldRecipe.vue'
4
+
5
+ describe('SmartGroupFieldRecipe', () => {
6
+ it('should draw the QC chip dot as the neutral QC marker when a qcColor is set', () => {
7
+ const wrapper = mount(SmartGroupFieldRecipe, { props: { qcColor: '#f43f5e' } })
8
+
9
+ const dot = wrapper.find('.sg-qc__chip .sg-dot').element as HTMLElement
10
+ expect(dot.style.borderColor).toBe('var(--text-secondary-strong)')
11
+ })
12
+ })