@morscherlab/mint-sdk 1.0.0-rc.2 → 1.0.0-rc.5

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 (443) hide show
  1. package/dist/__tests__/components/AppTopBar.navigation.test.d.ts +1 -0
  2. package/dist/__tests__/components/DoseCalculatorVolumeField.test.d.ts +1 -0
  3. package/dist/__tests__/components/PlateMapEditorToolbarInternal.test.d.ts +1 -0
  4. package/dist/__tests__/components/PluginWorkspaceView.controls.test.d.ts +1 -0
  5. package/dist/__tests__/components/PluginWorkspaceView.navigation.test.d.ts +1 -0
  6. package/dist/__tests__/components/PluginWorkspaceView.shell.test.d.ts +1 -0
  7. package/dist/__tests__/components/ProtocolStep.presentation.test.d.ts +1 -0
  8. package/dist/__tests__/components/ProtocolStepEditor.state.test.d.ts +1 -0
  9. package/dist/__tests__/components/ProtocolStepParameterField.test.d.ts +1 -0
  10. package/dist/__tests__/components/ReagentList.presentation.test.d.ts +1 -0
  11. package/dist/__tests__/components/SampleSelector.colors.test.d.ts +1 -0
  12. package/dist/__tests__/components/SampleSelector.drag.test.d.ts +1 -0
  13. package/dist/__tests__/components/SampleSelector.groups.test.d.ts +1 -0
  14. package/dist/__tests__/components/SampleSelector.selection.test.d.ts +1 -0
  15. package/dist/__tests__/components/SampleSelectorSampleRow.test.d.ts +1 -0
  16. package/dist/__tests__/components/ScheduleCalendar.test.d.ts +1 -0
  17. package/dist/__tests__/components/SettingsModal.schema.test.d.ts +1 -0
  18. package/dist/__tests__/components/WellPlate.colors.test.d.ts +1 -0
  19. package/dist/__tests__/components/WellPlate.conditions.test.d.ts +1 -0
  20. package/dist/__tests__/components/WellPlate.geometry.test.d.ts +1 -0
  21. package/dist/__tests__/components/WellPlate.interaction.test.d.ts +1 -0
  22. package/dist/__tests__/components/WellPlate.legend.test.d.ts +1 -0
  23. package/dist/__tests__/components/WellPlate.rendering.test.d.ts +1 -0
  24. package/dist/__tests__/components/WellPlate.sampleDrop.test.d.ts +1 -0
  25. package/dist/__tests__/composables/autoGroup/classify.test.d.ts +1 -0
  26. package/dist/__tests__/composables/autoGroup/columns.test.d.ts +1 -0
  27. package/dist/__tests__/composables/autoGroup/compose.test.d.ts +1 -0
  28. package/dist/__tests__/composables/autoGroup/cooccurrence.test.d.ts +1 -0
  29. package/dist/__tests__/composables/autoGroup/fingerprint.test.d.ts +1 -0
  30. package/dist/__tests__/composables/autoGroup/integration.test.d.ts +1 -0
  31. package/dist/__tests__/composables/autoGroup/template.test.d.ts +1 -0
  32. package/dist/__tests__/composables/autoGroup/tokenize.test.d.ts +1 -0
  33. package/dist/__tests__/composables/useAutoGroupInputSources.test.d.ts +1 -0
  34. package/dist/__tests__/composables/useScheduleCalendarLayout.test.d.ts +1 -0
  35. package/dist/__tests__/docs/extractDocsComponents.test.d.ts +1 -0
  36. package/dist/__tests__/docs/extractDocsExports.test.d.ts +1 -0
  37. package/dist/__tests__/docs/extractDocsParsing.test.d.ts +1 -0
  38. package/dist/__tests__/docs/extractDocsTemplates.test.d.ts +1 -0
  39. package/dist/__tests__/docs/extractDocsTheme.test.d.ts +1 -0
  40. package/dist/components/AppTopBar.navigation.d.ts +11 -0
  41. package/dist/components/BaseButton.vue.d.ts +1 -1
  42. package/dist/components/BaseCheckbox.vue.d.ts +1 -1
  43. package/dist/components/BaseInput.vue.d.ts +2 -2
  44. package/dist/components/BasePill.vue.d.ts +1 -1
  45. package/dist/components/BaseRadioGroup.vue.d.ts +1 -1
  46. package/dist/components/BaseSelect.vue.d.ts +1 -1
  47. package/dist/components/BaseSlider.vue.d.ts +2 -2
  48. package/dist/components/BaseTextarea.vue.d.ts +2 -2
  49. package/dist/components/BaseToggle.vue.d.ts +1 -1
  50. package/dist/components/BioTemplateExperimentWorkspaceView.vue.d.ts +2 -2
  51. package/dist/components/BioTemplatePackWorkspaceView.vue.d.ts +1 -1
  52. package/dist/components/ColorSlider.vue.d.ts +2 -2
  53. package/dist/components/ConcentrationInput.vue.d.ts +2 -2
  54. package/dist/components/DatePicker.vue.d.ts +1 -1
  55. package/dist/components/DateTimePicker.vue.d.ts +2 -2
  56. package/dist/components/DoseCalculatorVolumeField.vue.d.ts +15 -0
  57. package/dist/components/DropdownButton.vue.d.ts +1 -1
  58. package/dist/components/FileUploader.vue.d.ts +2 -2
  59. package/dist/components/FormulaInput.vue.d.ts +2 -2
  60. package/dist/components/IconButton.vue.d.ts +1 -1
  61. package/dist/components/LoadingSpinner.vue.d.ts +1 -1
  62. package/dist/components/MoleculeInput.vue.d.ts +2 -2
  63. package/dist/components/MultiSelect.vue.d.ts +1 -1
  64. package/dist/components/NumberInput.vue.d.ts +1 -1
  65. package/dist/components/PlateMapEditor.vue.d.ts +6 -6
  66. package/dist/components/PluginWorkspaceView.controls.d.ts +28 -0
  67. package/dist/components/PluginWorkspaceView.navigation.d.ts +29 -0
  68. package/dist/components/PluginWorkspaceView.props.d.ts +151 -0
  69. package/dist/components/PluginWorkspaceView.shell.d.ts +19 -0
  70. package/dist/components/PluginWorkspaceView.vue.d.ts +46 -195
  71. package/dist/components/ProgressBar.vue.d.ts +1 -1
  72. package/dist/components/ProtocolStep.presentation.d.ts +4 -0
  73. package/dist/components/ProtocolStepEditor.state.d.ts +18 -0
  74. package/dist/components/ProtocolStepParameterField.vue.d.ts +12 -0
  75. package/dist/components/ReagentList.presentation.d.ts +16 -0
  76. package/dist/components/ResourceCard.vue.d.ts +1 -1
  77. package/dist/components/SampleSelector.colors.d.ts +13 -0
  78. package/dist/components/SampleSelector.drag.d.ts +24 -0
  79. package/dist/components/SampleSelector.groups.d.ts +15 -0
  80. package/dist/components/SampleSelector.selection.d.ts +26 -0
  81. package/dist/components/SampleSelector.vue.d.ts +4 -1
  82. package/dist/components/SampleSelectorSampleRow.vue.d.ts +21 -0
  83. package/dist/components/SegmentedControl.vue.d.ts +1 -1
  84. package/dist/components/SequenceInput.vue.d.ts +2 -2
  85. package/dist/components/SequenceProgressBar.vue.d.ts +1 -1
  86. package/dist/components/SettingsModal.schema.d.ts +9 -0
  87. package/dist/components/StatusIndicator.vue.d.ts +1 -1
  88. package/dist/components/TagsInput.vue.d.ts +2 -2
  89. package/dist/components/TimePicker.vue.d.ts +2 -2
  90. package/dist/components/TimeRangeInput.vue.d.ts +1 -1
  91. package/dist/components/UnitInput.vue.d.ts +2 -2
  92. package/dist/components/WellPlate.colors.d.ts +9 -0
  93. package/dist/components/WellPlate.conditions.d.ts +26 -0
  94. package/dist/components/WellPlate.geometry.d.ts +23 -0
  95. package/dist/components/WellPlate.interaction.d.ts +71 -0
  96. package/dist/components/WellPlate.legend.d.ts +2 -0
  97. package/dist/components/WellPlate.rendering.d.ts +24 -0
  98. package/dist/components/WellPlate.sampleDrop.d.ts +8 -0
  99. package/dist/components/WellPlate.vue.d.ts +1 -1
  100. package/dist/components/index.js +2 -2
  101. package/dist/components/internal/ActionItemInternal.vue.d.ts +1 -1
  102. package/dist/components/internal/PlateMapEditorToolbarInternal.vue.d.ts +28 -0
  103. package/dist/{components-BhK-dW99.js → components-DtHA2bgp.js} +3754 -2991
  104. package/dist/components-DtHA2bgp.js.map +1 -0
  105. package/dist/composables/autoGroup/classKey.d.ts +4 -0
  106. package/dist/composables/autoGroup/classify.d.ts +28 -0
  107. package/dist/composables/autoGroup/colors.d.ts +2 -0
  108. package/dist/composables/autoGroup/columns.d.ts +10 -0
  109. package/dist/composables/autoGroup/compose.d.ts +8 -0
  110. package/dist/composables/autoGroup/cooccurrence.d.ts +2 -0
  111. package/dist/composables/autoGroup/csv-shim.d.ts +2 -0
  112. package/dist/composables/autoGroup/fingerprint.d.ts +3 -0
  113. package/dist/composables/autoGroup/index.d.ts +16 -0
  114. package/dist/composables/autoGroup/replicatePreGroup.d.ts +38 -0
  115. package/dist/composables/autoGroup/template.d.ts +15 -0
  116. package/dist/composables/autoGroup/tokenize.d.ts +8 -0
  117. package/dist/composables/autoGroupConstants.d.ts +1 -0
  118. package/dist/composables/autoGroupGrouping.d.ts +3 -0
  119. package/dist/composables/controlComponentBindings.d.ts +7 -0
  120. package/dist/composables/controlSchemaAdapters.d.ts +20 -0
  121. package/dist/composables/controlSchemaDoseDesign.d.ts +11 -0
  122. package/dist/composables/controlSchemaFormFields.d.ts +3 -0
  123. package/dist/composables/controlSchemaLayout.d.ts +7 -0
  124. package/dist/composables/controlSchemaModel.d.ts +5 -0
  125. package/dist/composables/controlSchemaNormalize.d.ts +15 -0
  126. package/dist/composables/controlSchemaTypes.d.ts +305 -0
  127. package/dist/composables/controlSchemaUtils.d.ts +9 -0
  128. package/dist/composables/controlWorkspaceOptions.d.ts +2 -0
  129. package/dist/composables/formBuilderSchema.d.ts +18 -0
  130. package/dist/composables/index.js +3 -3
  131. package/dist/composables/pluginEndpointBuilder.d.ts +13 -0
  132. package/dist/composables/protocolTemplateCatalog.d.ts +26 -0
  133. package/dist/composables/useAutoGroup.d.ts +61 -74
  134. package/dist/composables/useAutoGroupInputSources.d.ts +32 -0
  135. package/dist/composables/useBioTemplateControls.d.ts +1 -1
  136. package/dist/composables/useBioTemplatePresetWorkspace.d.ts +1 -1
  137. package/dist/composables/useBioTemplateWorkspace.d.ts +1 -1
  138. package/dist/composables/useControlSchema.d.ts +8 -346
  139. package/dist/composables/useControlWorkspace.d.ts +5 -0
  140. package/dist/composables/useForm.d.ts +2 -33
  141. package/dist/composables/useFormBuilder.d.ts +2 -9
  142. package/dist/composables/useFormValidation.d.ts +34 -0
  143. package/dist/composables/usePluginClient.d.ts +1 -4
  144. package/dist/composables/useProtocolTemplates.d.ts +2 -24
  145. package/dist/composables/useScheduleCalendarLayout.d.ts +49 -0
  146. package/dist/{composables-Bg7CFuNz.js → composables-Dlg8jenH.js} +33 -31
  147. package/dist/composables-Dlg8jenH.js.map +1 -0
  148. package/dist/index.js +4 -4
  149. package/dist/install.js +2 -2
  150. package/dist/styles.css +547 -516
  151. package/dist/templates/adapters.d.ts +14 -47
  152. package/dist/templates/assayLookups.d.ts +3 -0
  153. package/dist/templates/assayMatrixAdapters.d.ts +6 -0
  154. package/dist/templates/assayMatrixBuilder.d.ts +2 -0
  155. package/dist/templates/assayNormalizers.d.ts +4 -0
  156. package/dist/templates/builderDefaults.d.ts +1 -0
  157. package/dist/templates/builderIdUtils.d.ts +4 -0
  158. package/dist/templates/builderPresetControls.d.ts +10 -0
  159. package/dist/templates/builderReadUtils.d.ts +8 -0
  160. package/dist/templates/builders.d.ts +26 -67
  161. package/dist/templates/calibrationCurveAdapters.d.ts +4 -0
  162. package/dist/templates/calibrationCurveBuilder.d.ts +2 -0
  163. package/dist/templates/calibrationNormalizers.d.ts +5 -0
  164. package/dist/templates/componentBindingCatalog.d.ts +25 -0
  165. package/dist/templates/componentBindingHelpers.d.ts +17 -0
  166. package/dist/templates/componentDoseResponseProps.d.ts +3 -0
  167. package/dist/templates/componentGenericProps.d.ts +8 -0
  168. package/dist/templates/componentPlateHelpers.d.ts +5 -0
  169. package/dist/templates/componentPlateMapProps.d.ts +3 -0
  170. package/dist/templates/componentPropsFactory.d.ts +3 -0
  171. package/dist/templates/componentQpcrPlateProps.d.ts +3 -0
  172. package/dist/templates/componentTargetResolvers.d.ts +5 -0
  173. package/dist/templates/componentTemplateProps.d.ts +3 -0
  174. package/dist/templates/controlSchemaClone.d.ts +4 -0
  175. package/dist/templates/controlSchemaConstants.d.ts +10 -0
  176. package/dist/templates/controlSchemaMerge.d.ts +3 -0
  177. package/dist/templates/controlSchemaTargets.d.ts +17 -0
  178. package/dist/templates/controlSchemaTypes.d.ts +4 -0
  179. package/dist/templates/controlSchemas.d.ts +4 -4
  180. package/dist/templates/defaultBioTemplateBuilder.d.ts +2 -0
  181. package/dist/templates/doseResponseAdapters.d.ts +4 -0
  182. package/dist/templates/doseResponseBuilder.d.ts +2 -0
  183. package/dist/templates/elisaAssayCollectionBuilder.d.ts +2 -0
  184. package/dist/templates/flowCytometryAssayCollectionBuilder.d.ts +2 -0
  185. package/dist/templates/flowCytometryPanelBuilder.d.ts +2 -0
  186. package/dist/templates/flowNormalizers.d.ts +8 -0
  187. package/dist/templates/flowPanelAdapters.d.ts +4 -0
  188. package/dist/templates/index.js +1 -1
  189. package/dist/templates/instrumentRunAdapterHelpers.d.ts +8 -0
  190. package/dist/templates/instrumentRunAdapters.d.ts +8 -0
  191. package/dist/templates/instrumentRunBuilder.d.ts +2 -0
  192. package/dist/templates/lcmsBatchCollectionBuilder.d.ts +2 -0
  193. package/dist/templates/plateGeometry.d.ts +4 -0
  194. package/dist/templates/plateMapAdapters.d.ts +3 -0
  195. package/dist/templates/plateMapBuilder.d.ts +2 -0
  196. package/dist/templates/presetControlSchemas.d.ts +534 -0
  197. package/dist/templates/protocolAdapters.d.ts +5 -0
  198. package/dist/templates/protocolNormalizers.d.ts +6 -0
  199. package/dist/templates/protocolStepsBuilder.d.ts +2 -0
  200. package/dist/templates/qpcrAdapters.d.ts +5 -0
  201. package/dist/templates/qpcrExpressionCollectionBuilder.d.ts +2 -0
  202. package/dist/templates/qpcrPlateBuilder.d.ts +2 -0
  203. package/dist/templates/reagentAdapters.d.ts +5 -0
  204. package/dist/templates/reagentListBuilder.d.ts +2 -0
  205. package/dist/templates/runNormalizers.d.ts +10 -0
  206. package/dist/templates/sampleNormalizers.d.ts +4 -0
  207. package/dist/templates/samplePrepAdapters.d.ts +4 -0
  208. package/dist/templates/samplePrepBuilder.d.ts +2 -0
  209. package/dist/templates/sampleSheetAdapters.d.ts +5 -0
  210. package/dist/templates/sampleSheetBuilder.d.ts +2 -0
  211. package/dist/templates/targetedMetabolomicsCollectionBuilder.d.ts +2 -0
  212. package/dist/templates/targetedMetabolomicsHelpers.d.ts +5 -0
  213. package/dist/templates/templateAdapterTypes.d.ts +48 -0
  214. package/dist/templates/templateControlSchemas.d.ts +400 -0
  215. package/dist/templates/templateCreateOptions.d.ts +165 -0
  216. package/dist/templates/templateEnvelopes.d.ts +9 -0
  217. package/dist/templates/templatePackCollectionBuilder.d.ts +2 -0
  218. package/dist/templates/templatePresetCollectionBuilder.d.ts +18 -0
  219. package/dist/templates/templateQpcrTypes.d.ts +42 -0
  220. package/dist/templates/templateValidators.d.ts +13 -0
  221. package/dist/templates/timeCourseAdapters.d.ts +5 -0
  222. package/dist/templates/timeCourseBuilder.d.ts +2 -0
  223. package/dist/templates/types.d.ts +5 -250
  224. package/dist/templates/wellPlateScreenCollectionBuilder.d.ts +2 -0
  225. package/dist/templates/westernBlotAssayCollectionBuilder.d.ts +2 -0
  226. package/dist/{templates-BorLR_7p.js → templates-DtdUvJ4c.js} +3565 -3411
  227. package/dist/templates-DtdUvJ4c.js.map +1 -0
  228. package/dist/types/auto-group.d.ts +79 -9
  229. package/dist/types/componentLabTypes.d.ts +161 -0
  230. package/dist/types/componentWorkflowTypes.d.ts +150 -0
  231. package/dist/types/components.d.ts +2 -311
  232. package/dist/{useProtocolTemplates-n6AJqSqv.js → useProtocolTemplates-Bm5vyH4_.js} +1220 -454
  233. package/dist/useProtocolTemplates-Bm5vyH4_.js.map +1 -0
  234. package/package.json +1 -1
  235. package/src/__tests__/components/AppTopBar.navigation.test.ts +70 -0
  236. package/src/__tests__/components/DoseCalculatorVolumeField.test.ts +53 -0
  237. package/src/__tests__/components/PlateMapEditorToolbarInternal.test.ts +54 -0
  238. package/src/__tests__/components/PluginWorkspaceView.controls.test.ts +156 -0
  239. package/src/__tests__/components/PluginWorkspaceView.navigation.test.ts +102 -0
  240. package/src/__tests__/components/PluginWorkspaceView.shell.test.ts +41 -0
  241. package/src/__tests__/components/ProtocolStep.presentation.test.ts +31 -0
  242. package/src/__tests__/components/ProtocolStepEditor.state.test.ts +165 -0
  243. package/src/__tests__/components/ProtocolStepParameterField.test.ts +44 -0
  244. package/src/__tests__/components/ReagentList.presentation.test.ts +68 -0
  245. package/src/__tests__/components/SampleSelector.colors.test.ts +49 -0
  246. package/src/__tests__/components/SampleSelector.drag.test.ts +100 -0
  247. package/src/__tests__/components/SampleSelector.groups.test.ts +81 -0
  248. package/src/__tests__/components/SampleSelector.selection.test.ts +70 -0
  249. package/src/__tests__/components/SampleSelector.test.ts +32 -0
  250. package/src/__tests__/components/SampleSelectorSampleRow.test.ts +37 -0
  251. package/src/__tests__/components/ScheduleCalendar.test.ts +44 -0
  252. package/src/__tests__/components/SettingsModal.schema.test.ts +97 -0
  253. package/src/__tests__/components/WellPlate.colors.test.ts +28 -0
  254. package/src/__tests__/components/WellPlate.conditions.test.ts +68 -0
  255. package/src/__tests__/components/WellPlate.geometry.test.ts +54 -0
  256. package/src/__tests__/components/WellPlate.interaction.test.ts +171 -0
  257. package/src/__tests__/components/WellPlate.legend.test.ts +13 -0
  258. package/src/__tests__/components/WellPlate.rendering.test.ts +122 -0
  259. package/src/__tests__/components/WellPlate.sampleDrop.test.ts +70 -0
  260. package/src/__tests__/composables/autoGroup/classify.test.ts +107 -0
  261. package/src/__tests__/composables/autoGroup/columns.test.ts +135 -0
  262. package/src/__tests__/composables/autoGroup/compose.test.ts +227 -0
  263. package/src/__tests__/composables/autoGroup/cooccurrence.test.ts +91 -0
  264. package/src/__tests__/composables/autoGroup/fingerprint.test.ts +50 -0
  265. package/src/__tests__/composables/autoGroup/integration.test.ts +79 -0
  266. package/src/__tests__/composables/autoGroup/template.test.ts +70 -0
  267. package/src/__tests__/composables/autoGroup/tokenize.test.ts +33 -0
  268. package/src/__tests__/composables/useAutoGroup.test.ts +129 -625
  269. package/src/__tests__/composables/useAutoGroupInputSources.test.ts +107 -0
  270. package/src/__tests__/composables/useControlSchema.test.ts +23 -0
  271. package/src/__tests__/composables/useScheduleCalendarLayout.test.ts +89 -0
  272. package/src/__tests__/docs/extractDocsComponents.test.ts +142 -0
  273. package/src/__tests__/docs/extractDocsExports.test.ts +77 -0
  274. package/src/__tests__/docs/extractDocsParsing.test.ts +69 -0
  275. package/src/__tests__/docs/extractDocsTemplates.test.ts +54 -0
  276. package/src/__tests__/docs/extractDocsTheme.test.ts +89 -0
  277. package/src/__tests__/docs/frontendDocsCatalog.test.ts +1 -1
  278. package/src/__tests__/fixtures/auto-group/mixed-lc-ms-batch.txt +187 -0
  279. package/src/components/AppSidebar.vue +2 -6
  280. package/src/components/AppTopBar.navigation.ts +62 -0
  281. package/src/components/AppTopBar.vue +17 -44
  282. package/src/components/AutoGroupModal.story.vue +50 -0
  283. package/src/components/AutoGroupModal.vue +441 -158
  284. package/src/components/ControlWorkspaceView.vue +2 -6
  285. package/src/components/DoseCalculator.vue +13 -73
  286. package/src/components/DoseCalculatorVolumeField.vue +61 -0
  287. package/src/components/ExperimentTimeline.vue +6 -31
  288. package/src/components/FormBuilder.vue +2 -7
  289. package/src/components/PlateMapEditor.vue +32 -106
  290. package/src/components/PluginWorkspaceView.controls.ts +182 -0
  291. package/src/components/PluginWorkspaceView.navigation.ts +106 -0
  292. package/src/components/PluginWorkspaceView.props.ts +174 -0
  293. package/src/components/PluginWorkspaceView.shell.ts +66 -0
  294. package/src/components/PluginWorkspaceView.vue +85 -404
  295. package/src/components/ProtocolStep.presentation.ts +31 -0
  296. package/src/components/ProtocolStepEditor.state.ts +104 -0
  297. package/src/components/ProtocolStepEditor.vue +48 -179
  298. package/src/components/ProtocolStepParameterField.vue +134 -0
  299. package/src/components/ReagentList.presentation.ts +105 -0
  300. package/src/components/ReagentList.vue +16 -79
  301. package/src/components/SampleSelector.colors.ts +43 -0
  302. package/src/components/SampleSelector.drag.ts +164 -0
  303. package/src/components/SampleSelector.groups.ts +109 -0
  304. package/src/components/SampleSelector.selection.ts +103 -0
  305. package/src/components/SampleSelector.vue +82 -349
  306. package/src/components/SampleSelectorSampleRow.vue +64 -0
  307. package/src/components/ScheduleCalendar.vue +44 -199
  308. package/src/components/SettingsModal.schema.ts +71 -0
  309. package/src/components/SettingsModal.vue +16 -46
  310. package/src/components/WellPlate.colors.ts +56 -0
  311. package/src/components/WellPlate.conditions.ts +100 -0
  312. package/src/components/WellPlate.geometry.ts +91 -0
  313. package/src/components/WellPlate.interaction.ts +272 -0
  314. package/src/components/WellPlate.legend.ts +8 -0
  315. package/src/components/WellPlate.rendering.ts +105 -0
  316. package/src/components/WellPlate.sampleDrop.ts +73 -0
  317. package/src/components/WellPlate.vue +102 -550
  318. package/src/components/internal/PlateMapEditorToolbarInternal.vue +128 -0
  319. package/src/composables/autoGroup/classKey.ts +5 -0
  320. package/src/composables/autoGroup/classify.ts +205 -0
  321. package/src/composables/autoGroup/colors.ts +6 -0
  322. package/src/composables/autoGroup/columns.ts +226 -0
  323. package/src/composables/autoGroup/compose.ts +156 -0
  324. package/src/composables/autoGroup/cooccurrence.ts +46 -0
  325. package/src/composables/autoGroup/csv-shim.ts +44 -0
  326. package/src/composables/autoGroup/fingerprint.ts +49 -0
  327. package/src/composables/autoGroup/index.ts +20 -0
  328. package/src/composables/autoGroup/replicatePreGroup.ts +90 -0
  329. package/src/composables/autoGroup/template.ts +126 -0
  330. package/src/composables/autoGroup/tokenize.ts +41 -0
  331. package/src/composables/autoGroup/vocab.json +67 -0
  332. package/src/composables/autoGroupConstants.ts +4 -0
  333. package/src/composables/autoGroupGrouping.ts +148 -0
  334. package/src/composables/controlComponentBindings.ts +80 -0
  335. package/src/composables/controlSchemaAdapters.ts +196 -0
  336. package/src/composables/controlSchemaDoseDesign.ts +215 -0
  337. package/src/composables/controlSchemaFormFields.ts +61 -0
  338. package/src/composables/controlSchemaLayout.ts +59 -0
  339. package/src/composables/controlSchemaModel.ts +163 -0
  340. package/src/composables/controlSchemaNormalize.ts +101 -0
  341. package/src/composables/controlSchemaTypes.ts +364 -0
  342. package/src/composables/controlSchemaUtils.ts +36 -0
  343. package/src/composables/controlWorkspaceOptions.ts +21 -0
  344. package/src/composables/formBuilderSchema.ts +153 -0
  345. package/src/composables/pluginEndpointBuilder.ts +203 -0
  346. package/src/composables/protocolTemplateCatalog.ts +325 -0
  347. package/src/composables/useAutoGroup.ts +395 -549
  348. package/src/composables/useAutoGroupInputSources.ts +147 -0
  349. package/src/composables/useBioTemplateControls.ts +1 -1
  350. package/src/composables/useBioTemplatePresetWorkspace.ts +1 -1
  351. package/src/composables/useBioTemplateWorkspace.ts +1 -1
  352. package/src/composables/useControlSchema.ts +64 -1312
  353. package/src/composables/useControlWorkspace.ts +201 -0
  354. package/src/composables/useForm.ts +5 -187
  355. package/src/composables/useFormBuilder.ts +11 -153
  356. package/src/composables/useFormValidation.ts +154 -0
  357. package/src/composables/usePluginClient.ts +10 -193
  358. package/src/composables/useProtocolTemplates.ts +10 -328
  359. package/src/composables/useScheduleCalendarLayout.ts +287 -0
  360. package/src/styles/components/auto-group-modal.css +248 -310
  361. package/src/templates/adapters.ts +89 -930
  362. package/src/templates/assayLookups.ts +33 -0
  363. package/src/templates/assayMatrixAdapters.ts +78 -0
  364. package/src/templates/assayMatrixBuilder.ts +59 -0
  365. package/src/templates/assayNormalizers.ts +34 -0
  366. package/src/templates/builderDefaults.ts +11 -0
  367. package/src/templates/builderIdUtils.ts +20 -0
  368. package/src/templates/builderPresetControls.ts +165 -0
  369. package/src/templates/builderReadUtils.ts +57 -0
  370. package/src/templates/builders.ts +122 -2350
  371. package/src/templates/calibrationCurveAdapters.ts +59 -0
  372. package/src/templates/calibrationCurveBuilder.ts +99 -0
  373. package/src/templates/calibrationNormalizers.ts +60 -0
  374. package/src/templates/componentBindingCatalog.ts +90 -0
  375. package/src/templates/componentBindingHelpers.ts +93 -0
  376. package/src/templates/componentBindings.ts +12 -461
  377. package/src/templates/componentDoseResponseProps.ts +42 -0
  378. package/src/templates/componentGenericProps.ts +77 -0
  379. package/src/templates/componentPlateHelpers.ts +29 -0
  380. package/src/templates/componentPlateMapProps.ts +32 -0
  381. package/src/templates/componentPropsFactory.ts +21 -0
  382. package/src/templates/componentQpcrPlateProps.ts +28 -0
  383. package/src/templates/componentTargetResolvers.ts +69 -0
  384. package/src/templates/componentTemplateProps.ts +78 -0
  385. package/src/templates/controlSchemaClone.ts +32 -0
  386. package/src/templates/controlSchemaConstants.ts +11 -0
  387. package/src/templates/controlSchemaMerge.ts +40 -0
  388. package/src/templates/controlSchemaTargets.ts +87 -0
  389. package/src/templates/controlSchemaTypes.ts +20 -0
  390. package/src/templates/controlSchemas.ts +22 -704
  391. package/src/templates/defaultBioTemplateBuilder.ts +124 -0
  392. package/src/templates/doseResponseAdapters.ts +45 -0
  393. package/src/templates/doseResponseBuilder.ts +44 -0
  394. package/src/templates/elisaAssayCollectionBuilder.ts +62 -0
  395. package/src/templates/flowCytometryAssayCollectionBuilder.ts +41 -0
  396. package/src/templates/flowCytometryPanelBuilder.ts +53 -0
  397. package/src/templates/flowNormalizers.ts +58 -0
  398. package/src/templates/flowPanelAdapters.ts +58 -0
  399. package/src/templates/instrumentRunAdapterHelpers.ts +94 -0
  400. package/src/templates/instrumentRunAdapters.ts +163 -0
  401. package/src/templates/instrumentRunBuilder.ts +97 -0
  402. package/src/templates/lcmsBatchCollectionBuilder.ts +38 -0
  403. package/src/templates/plateGeometry.ts +62 -0
  404. package/src/templates/plateMapAdapters.ts +36 -0
  405. package/src/templates/plateMapBuilder.ts +43 -0
  406. package/src/templates/presetControlSchemas.ts +258 -0
  407. package/src/templates/protocolAdapters.ts +69 -0
  408. package/src/templates/protocolNormalizers.ts +37 -0
  409. package/src/templates/protocolStepsBuilder.ts +36 -0
  410. package/src/templates/qpcrAdapters.ts +104 -0
  411. package/src/templates/qpcrExpressionCollectionBuilder.ts +33 -0
  412. package/src/templates/qpcrPlateBuilder.ts +96 -0
  413. package/src/templates/reagentAdapters.ts +77 -0
  414. package/src/templates/reagentListBuilder.ts +30 -0
  415. package/src/templates/runNormalizers.ts +63 -0
  416. package/src/templates/sampleNormalizers.ts +58 -0
  417. package/src/templates/samplePrepAdapters.ts +63 -0
  418. package/src/templates/samplePrepBuilder.ts +51 -0
  419. package/src/templates/sampleSheetAdapters.ts +75 -0
  420. package/src/templates/sampleSheetBuilder.ts +23 -0
  421. package/src/templates/targetedMetabolomicsCollectionBuilder.ts +79 -0
  422. package/src/templates/targetedMetabolomicsHelpers.ts +102 -0
  423. package/src/templates/templateAdapterTypes.ts +58 -0
  424. package/src/templates/templateControlSchemas.ts +320 -0
  425. package/src/templates/templateCreateOptions.ts +208 -0
  426. package/src/templates/templateEnvelopes.ts +137 -0
  427. package/src/templates/templatePackCollectionBuilder.ts +23 -0
  428. package/src/templates/templatePresetCollectionBuilder.ts +139 -0
  429. package/src/templates/templateQpcrTypes.ts +48 -0
  430. package/src/templates/templateValidators.ts +414 -0
  431. package/src/templates/timeCourseAdapters.ts +73 -0
  432. package/src/templates/timeCourseBuilder.ts +64 -0
  433. package/src/templates/types.ts +79 -275
  434. package/src/templates/wellPlateScreenCollectionBuilder.ts +36 -0
  435. package/src/templates/westernBlotAssayCollectionBuilder.ts +68 -0
  436. package/src/types/auto-group.ts +107 -9
  437. package/src/types/componentLabTypes.ts +235 -0
  438. package/src/types/componentWorkflowTypes.ts +190 -0
  439. package/src/types/components.ts +74 -424
  440. package/dist/components-BhK-dW99.js.map +0 -1
  441. package/dist/composables-Bg7CFuNz.js.map +0 -1
  442. package/dist/templates-BorLR_7p.js.map +0 -1
  443. package/dist/useProtocolTemplates-n6AJqSqv.js.map +0 -1
@@ -0,0 +1,148 @@
1
+ import type {
2
+ AutoGroupResult,
3
+ ColumnInfo,
4
+ MetadataRow,
5
+ OutlierAction,
6
+ ParsedCsvData,
7
+ } from '../types/auto-group'
8
+ import type { SampleGroup } from '../types/components'
9
+ import { DEFAULT_COLORS } from './autoGroupConstants'
10
+
11
+ export function computeGroups(
12
+ allSamples: string[],
13
+ columns: ColumnInfo[],
14
+ enabledFields: Set<number>,
15
+ outlierActions: Map<number, OutlierAction>,
16
+ delimiter: string,
17
+ minFieldCount: number,
18
+ ): AutoGroupResult {
19
+ const excludedSamples: string[] = []
20
+ const qcSamples: string[] = []
21
+ const conformingSamples: string[] = []
22
+
23
+ for (let i = 0; i < allSamples.length; i++) {
24
+ const action = outlierActions.get(i)
25
+ if (action === 'exclude') {
26
+ excludedSamples.push(allSamples[i])
27
+ } else if (action === 'qc') {
28
+ qcSamples.push(allSamples[i])
29
+ } else {
30
+ conformingSamples.push(allSamples[i])
31
+ }
32
+ }
33
+
34
+ // Build group map
35
+ const groupMap = new Map<string, string[]>()
36
+ const metadata: MetadataRow[] = []
37
+ const enabledIndices = [...enabledFields].sort((a, b) => a - b)
38
+ const suffixCount = minFieldCount - 1
39
+
40
+ for (const sample of conformingSamples) {
41
+ const parts = sample.split(delimiter)
42
+ const splitAt = Math.max(1, parts.length - suffixCount)
43
+ const row = [
44
+ parts.slice(0, splitAt).join(delimiter),
45
+ ...parts.slice(splitAt),
46
+ ]
47
+
48
+ // Build group key from enabled columns
49
+ const keyParts: string[] = []
50
+ for (const idx of enabledIndices) {
51
+ if (idx < row.length && idx < columns.length) {
52
+ keyParts.push(row[idx])
53
+ }
54
+ }
55
+ const groupKey = keyParts.join(' / ')
56
+
57
+ const group = groupMap.get(groupKey)
58
+ if (group) {
59
+ group.push(sample)
60
+ } else {
61
+ groupMap.set(groupKey, [sample])
62
+ }
63
+
64
+ // Build metadata row with ALL columns
65
+ const fields: Record<string, string> = {}
66
+ for (const col of columns) {
67
+ if (col.index < row.length) {
68
+ fields[col.name] = row[col.index]
69
+ }
70
+ }
71
+ metadata.push({ sampleName: sample, fields, group: groupKey })
72
+ }
73
+
74
+ // Convert to SampleGroup[]
75
+ const groups: SampleGroup[] = []
76
+ let colorIdx = 0
77
+ for (const [name, samples] of groupMap) {
78
+ groups.push({
79
+ name,
80
+ color: DEFAULT_COLORS[colorIdx % DEFAULT_COLORS.length],
81
+ samples,
82
+ })
83
+ colorIdx++
84
+ }
85
+
86
+ // QC group
87
+ if (qcSamples.length > 0) {
88
+ groups.push({
89
+ name: 'QC',
90
+ color: '#6B7280',
91
+ samples: qcSamples,
92
+ })
93
+ for (const sample of qcSamples) {
94
+ metadata.push({ sampleName: sample, fields: {}, group: 'QC' })
95
+ }
96
+ }
97
+
98
+ return { groups, metadata, excludedSamples }
99
+ }
100
+
101
+ export function computeGroupsFromCsv(
102
+ csvData: ParsedCsvData,
103
+ columns: ColumnInfo[],
104
+ enabledFields: Set<number>,
105
+ ): AutoGroupResult {
106
+ const groupMap = new Map<string, string[]>()
107
+ const metadata: MetadataRow[] = []
108
+ const enabledCols = columns
109
+ .filter(c => enabledFields.has(c.index))
110
+ .sort((a, b) => a.index - b.index)
111
+
112
+ for (const row of csvData.rows) {
113
+ const sampleName = row[csvData.sampleColumn]
114
+
115
+ // Build group key from enabled CSV column values
116
+ // Use originalName for CSV row lookup (survives user renames), display name for group key
117
+ const keyParts = enabledCols.map(col => row[col.originalName ?? col.name])
118
+ const groupKey = keyParts.join(' / ')
119
+
120
+ const group = groupMap.get(groupKey)
121
+ if (group) {
122
+ group.push(sampleName)
123
+ } else {
124
+ groupMap.set(groupKey, [sampleName])
125
+ }
126
+
127
+ // Build metadata row with ALL columns - use display name as key, original for lookup
128
+ const fields: Record<string, string> = {}
129
+ for (const col of columns) {
130
+ fields[col.name] = row[col.originalName ?? col.name]
131
+ }
132
+ metadata.push({ sampleName, fields, group: groupKey })
133
+ }
134
+
135
+ // Convert to SampleGroup[]
136
+ const groups: SampleGroup[] = []
137
+ let colorIdx = 0
138
+ for (const [name, samples] of groupMap) {
139
+ groups.push({
140
+ name,
141
+ color: DEFAULT_COLORS[colorIdx % DEFAULT_COLORS.length],
142
+ samples,
143
+ })
144
+ colorIdx++
145
+ }
146
+
147
+ return { groups, metadata, excludedSamples: [] }
148
+ }
@@ -0,0 +1,80 @@
1
+ import type {
2
+ ControlComponentBinding,
3
+ ControlComponentBindingConfig,
4
+ ControlComponentBindingRecordConfig,
5
+ ControlComponentBindingsById,
6
+ ControlComponentBindingsConfig,
7
+ ControlComponentPropsMap,
8
+ ControlComponentPropSource,
9
+ } from './controlSchemaTypes'
10
+
11
+ /** Map control workspace values into component props for direct `v-bind` usage. */
12
+ export function controlValuesToComponentProps<TValues extends Record<string, unknown>>(
13
+ values: TValues,
14
+ mapping?: ControlComponentPropsMap<TValues>,
15
+ ): Record<string, unknown> {
16
+ if (mapping === undefined) return { ...values }
17
+
18
+ if (Array.isArray(mapping)) {
19
+ const props: Record<string, unknown> = {}
20
+ for (const key of mapping) {
21
+ props[key] = values[key]
22
+ }
23
+ return props
24
+ }
25
+
26
+ const props: Record<string, unknown> = {}
27
+ for (const [prop, source] of Object.entries(mapping) as Array<[string, ControlComponentPropSource<TValues>]>) {
28
+ props[prop] = typeof source === 'function' ? source(values) : values[source]
29
+ }
30
+ return props
31
+ }
32
+
33
+ /** Map control workspace values into named SDK component bindings for direct slot rendering. */
34
+ export function controlValuesToComponentBindings<TValues extends Record<string, unknown>>(
35
+ values: TValues,
36
+ bindings?: ControlComponentBindingsConfig<TValues>,
37
+ ): ControlComponentBinding[] {
38
+ if (bindings === undefined) return []
39
+
40
+ return normalizeControlComponentBindingConfigs(bindings).map(binding => ({
41
+ id: binding.id,
42
+ component: binding.component,
43
+ props: controlValuesToComponentProps(values, binding.props),
44
+ }))
45
+ }
46
+
47
+ /** Map control workspace values into SDK component bindings keyed by binding id. */
48
+ export function controlValuesToComponentBindingsById<TValues extends Record<string, unknown>>(
49
+ values: TValues,
50
+ bindings?: ControlComponentBindingsConfig<TValues>,
51
+ ): ControlComponentBindingsById {
52
+ return Object.fromEntries(
53
+ controlValuesToComponentBindings(values, bindings).map(binding => [binding.id, binding]),
54
+ )
55
+ }
56
+
57
+ function normalizeControlComponentBindingConfigs<TValues extends Record<string, unknown>>(
58
+ bindings: ControlComponentBindingsConfig<TValues>,
59
+ ): Array<Required<Pick<ControlComponentBindingConfig<TValues>, 'id' | 'component'>> & Pick<ControlComponentBindingConfig<TValues>, 'props'>> {
60
+ if (Array.isArray(bindings)) {
61
+ const usedIds = new Map<string, number>()
62
+ return bindings.map(binding => ({
63
+ id: uniqueComponentBindingId(binding.id ?? binding.component, usedIds),
64
+ component: binding.component,
65
+ props: binding.props,
66
+ }))
67
+ }
68
+
69
+ return Object.entries(bindings).map(([id, binding]: [string, ControlComponentBindingRecordConfig<TValues>]) => ({
70
+ id,
71
+ component: binding.component,
72
+ props: binding.props,
73
+ }))
74
+ }
75
+
76
+ function uniqueComponentBindingId(id: string, usedIds: Map<string, number>): string {
77
+ const count = usedIds.get(id) ?? 0
78
+ usedIds.set(id, count + 1)
79
+ return count === 0 ? id : `${id}-${count + 1}`
80
+ }
@@ -0,0 +1,196 @@
1
+ import type {
2
+ PillNavItem,
3
+ SidebarToolSection,
4
+ SettingsModalSchema,
5
+ TopBarSettingsConfig,
6
+ } from '../types'
7
+ import type {
8
+ FormSectionSchema,
9
+ } from '../types/form-builder'
10
+ import {
11
+ controlToFormField,
12
+ } from './controlSchemaFormFields'
13
+ import {
14
+ controlViewItem,
15
+ firstSidebarConfig,
16
+ isSidebarEnabled,
17
+ sectionConfig,
18
+ } from './controlSchemaLayout'
19
+ import {
20
+ normalizeControls,
21
+ } from './controlSchemaNormalize'
22
+ import {
23
+ humanize,
24
+ orderedUnique,
25
+ } from './controlSchemaUtils'
26
+ import type {
27
+ ControlFormSchema,
28
+ ControlSchema,
29
+ ControlSchemaOptions,
30
+ } from './controlSchemaTypes'
31
+
32
+ /** Convert a compact control schema into a FormBuilder schema. */
33
+ export function controlsToFormSchema(
34
+ controls: ControlSchema,
35
+ options: ControlSchemaOptions = {},
36
+ ): ControlFormSchema {
37
+ const normalized = normalizeControls(controls, options)
38
+ const sectionIds = orderedUnique(normalized.map(control => control.sectionId))
39
+ const sections = sectionIds.map((sectionId): FormSectionSchema => {
40
+ const sectionControls = normalized.filter(control => control.sectionId === sectionId)
41
+ const config = sectionConfig(sectionId, sectionControls, options)
42
+ return {
43
+ id: sectionId,
44
+ title: config.title ?? config.label ?? humanize(sectionId),
45
+ description: config.description,
46
+ columns: config.columns ?? options.columns ?? 1,
47
+ defaultOpen: config.defaultOpen,
48
+ condition: config.condition,
49
+ fields: sectionControls.map(controlToFormField),
50
+ }
51
+ })
52
+
53
+ return {
54
+ sections,
55
+ submitLabel: options.submitLabel,
56
+ cancelLabel: options.cancelLabel,
57
+ showCancel: options.showCancel,
58
+ }
59
+ }
60
+
61
+ /** Convert controls into AppSidebar panels grouped by view and section. */
62
+ export function controlsToSidebarPanels(
63
+ controls: ControlSchema,
64
+ options: ControlSchemaOptions = {},
65
+ ): Record<string, SidebarToolSection[]> {
66
+ const normalized = normalizeControls(controls, options)
67
+ .filter(control => isSidebarEnabled(control.definition.sidebar))
68
+ const viewIds = orderedUnique(normalized.map(control => control.viewId))
69
+ const panels: Record<string, SidebarToolSection[]> = {}
70
+
71
+ for (const viewId of viewIds) {
72
+ const viewControls = normalized.filter(control => control.viewId === viewId)
73
+ const sectionIds = orderedUnique(viewControls.map(control => control.sectionId))
74
+ panels[viewId] = sectionIds.map((sectionId): SidebarToolSection => {
75
+ const sectionControls = viewControls.filter(control => control.sectionId === sectionId)
76
+ const config = sectionConfig(sectionId, sectionControls, options)
77
+ const sidebarConfig = firstSidebarConfig(sectionControls)
78
+ return {
79
+ id: sectionId,
80
+ label: sidebarConfig?.label ?? config.label ?? config.title ?? humanize(sectionId),
81
+ subtitle: sidebarConfig?.subtitle ?? config.subtitle,
82
+ icon: sidebarConfig?.icon ?? config.icon,
83
+ iconColor: sidebarConfig?.iconColor ?? config.iconColor,
84
+ iconBg: sidebarConfig?.iconBg ?? config.iconBg,
85
+ defaultOpen: sidebarConfig?.defaultOpen ?? config.defaultOpen,
86
+ showToggle: sidebarConfig?.showToggle ?? config.showToggle,
87
+ }
88
+ })
89
+ }
90
+
91
+ return panels
92
+ }
93
+
94
+ /** Convert controls into a SettingsModal schema grouped by the same sections. */
95
+ export function controlsToSettingsSchema(
96
+ controls: ControlSchema,
97
+ options: ControlSchemaOptions = {},
98
+ ): SettingsModalSchema {
99
+ const normalized = normalizeControls(controls, options)
100
+ const sectionIds = orderedUnique(normalized.map(control => control.sectionId))
101
+
102
+ return {
103
+ groups: sectionIds.map((sectionId) => {
104
+ const sectionControls = normalized.filter(control => control.sectionId === sectionId)
105
+ const config = sectionConfig(sectionId, sectionControls, options)
106
+ return {
107
+ id: sectionId,
108
+ label: config.label ?? config.title ?? humanize(sectionId),
109
+ description: config.description ?? config.subtitle,
110
+ icon: typeof config.icon === 'string' ? config.icon : undefined,
111
+ fields: sectionControls.map(controlToFormField),
112
+ columns: config.columns ?? options.columns ?? 1,
113
+ condition: config.condition,
114
+ access: config.access,
115
+ visibleFor: config.visibleFor,
116
+ requiresAdmin: config.requiresAdmin,
117
+ permissions: config.permissions,
118
+ anyPermissions: config.anyPermissions,
119
+ }
120
+ }),
121
+ }
122
+ }
123
+
124
+ /** Convert controls into an AppTopBar settingsConfig object that passes compact controls through to SettingsModal. */
125
+ export function controlsToTopBarSettingsConfig(
126
+ controls: ControlSchema,
127
+ options: ControlSchemaOptions = {},
128
+ config: Omit<TopBarSettingsConfig, 'schema' | 'controls' | 'controlOptions'> = {},
129
+ ): TopBarSettingsConfig {
130
+ return {
131
+ ...config,
132
+ controls,
133
+ controlOptions: options,
134
+ }
135
+ }
136
+
137
+ /** Return generated control view IDs that have at least one sidebar panel. */
138
+ export function controlsToViewIds(
139
+ controls: ControlSchema,
140
+ options: ControlSchemaOptions = {},
141
+ ): string[] {
142
+ return controlsToViewItems(controls, options).map(item => item.id)
143
+ }
144
+
145
+ /** Return AppTopBar pillNav-compatible view items for switching generated control sidebars. */
146
+ export function controlsToViewItems(
147
+ controls: ControlSchema,
148
+ options: ControlSchemaOptions = {},
149
+ ): PillNavItem[] {
150
+ return Object.entries(controlsToSidebarPanels(controls, options))
151
+ .filter(([, sections]) => sections.length > 0)
152
+ .map(([id]) => controlViewItem(id, options))
153
+ }
154
+
155
+ /** Return the first generated sidebar view ID, or an empty string when controls render no sidebar panels. */
156
+ export function getDefaultControlView(
157
+ controls: ControlSchema,
158
+ options: ControlSchemaOptions = {},
159
+ ): string {
160
+ return controlsToViewIds(controls, options)[0] ?? ''
161
+ }
162
+
163
+ /** Return a headerless single-section FormBuilder schema for rendering inside an AppSidebar section slot. */
164
+ export function controlsToSectionFormSchema(
165
+ controls: ControlSchema,
166
+ sectionId: string,
167
+ options: ControlSchemaOptions = {},
168
+ ): ControlFormSchema {
169
+ const schema = controlsToFormSchema(controls, options)
170
+ return {
171
+ sections: schema.sections
172
+ .filter(section => section.id === sectionId)
173
+ .map(section => ({ ...section, title: '', description: undefined })),
174
+ submitLabel: schema.submitLabel,
175
+ cancelLabel: schema.cancelLabel,
176
+ showCancel: schema.showCancel,
177
+ }
178
+ }
179
+
180
+ /** Return headerless FormBuilder schemas keyed by section ID for AppSidebar auto-rendering. */
181
+ export function controlsToSectionFormSchemas(
182
+ controls: ControlSchema,
183
+ options: ControlSchemaOptions = {},
184
+ ): Record<string, ControlFormSchema> {
185
+ const schema = controlsToFormSchema(controls, options)
186
+ const schemas: Record<string, ControlFormSchema> = {}
187
+ for (const section of schema.sections) {
188
+ schemas[section.id] = {
189
+ sections: [{ ...section, title: '', description: undefined }],
190
+ submitLabel: schema.submitLabel,
191
+ cancelLabel: schema.cancelLabel,
192
+ showCancel: schema.showCancel,
193
+ }
194
+ }
195
+ return schemas
196
+ }
@@ -0,0 +1,215 @@
1
+ import type {
2
+ ControlComponentBindingsConfig,
3
+ ControlComponentPropSource,
4
+ ControlComponentPropsByIdMap,
5
+ ControlComponentPropsMap,
6
+ ControlModelBinding,
7
+ ControlSchema,
8
+ DoseCalculatorControlPropsOptions,
9
+ DoseDesignControlModelOptions,
10
+ WellPlateControlPropsOptions,
11
+ WellPlateDoseControlPropsOptions,
12
+ } from './controlSchemaTypes'
13
+ import type { WellConcentration } from './useDoseCalculator'
14
+ import {
15
+ defineControlModel,
16
+ } from './controlSchemaModel'
17
+ import {
18
+ recordValue,
19
+ } from './controlSchemaUtils'
20
+
21
+ /** Return a default WellPlate prop mapping for generated control workspaces. */
22
+ export function defineWellPlateControlProps<TValues extends Record<string, unknown> = Record<string, unknown>>(
23
+ options: WellPlateControlPropsOptions<TValues> = {},
24
+ ): ControlComponentPropsMap<TValues> {
25
+ const selectedWells = options.selectedWells ?? sourceKey<TValues>('selectedWells')
26
+ const onUpdateModelValue = options.onUpdateModelValue === false
27
+ ? undefined
28
+ : options.onUpdateModelValue ?? updateControlValueSource(selectedWells)
29
+
30
+ return compactComponentPropsMap<TValues>({
31
+ modelValue: selectedWells,
32
+ 'onUpdate:modelValue': onUpdateModelValue,
33
+ format: options.format ?? sourceKey<TValues>('plateFormat'),
34
+ wells: options.wells ?? sourceKey<TValues>('wells'),
35
+ disabled: options.disabled ?? sourceKey<TValues>('disabled'),
36
+ readonly: options.readonly ?? sourceKey<TValues>('readonly'),
37
+ showLegend: options.showLegend,
38
+ showSampleTypeIndicator: options.showSampleTypeIndicator,
39
+ })
40
+ }
41
+
42
+ /** Return a default DoseCalculator prop mapping for generated control workspaces. */
43
+ export function defineDoseCalculatorControlProps<TValues extends Record<string, unknown> = Record<string, unknown>>(
44
+ options: DoseCalculatorControlPropsOptions<TValues> = {},
45
+ ): ControlComponentPropsMap<TValues> {
46
+ const targetWells = options.targetWells ?? sourceKey<TValues>('selectedWells')
47
+ const wells = options.wells ?? sourceKey<TValues>('wells')
48
+ const onApplyToWells = options.onApplyToWells === false
49
+ ? undefined
50
+ : options.onApplyToWells ?? defaultDoseApplyHandler(wells, targetWells)
51
+
52
+ return compactComponentPropsMap<TValues>({
53
+ mode: options.mode ?? sourceKey<TValues>('doseMode'),
54
+ targetWells,
55
+ disabled: options.disabled ?? sourceKey<TValues>('disabled'),
56
+ molecularWeight: options.molecularWeight,
57
+ onApplyToWells,
58
+ })
59
+ }
60
+
61
+ /** Return named WellPlate + DoseCalculator prop mappings for one dose-design control model. */
62
+ export function defineWellPlateDoseControlProps<TValues extends Record<string, unknown> = Record<string, unknown>>(
63
+ options: WellPlateDoseControlPropsOptions<TValues> = {},
64
+ ): ControlComponentPropsByIdMap<TValues> {
65
+ return {
66
+ [options.plateId ?? 'plate']: defineWellPlateControlProps(options.plate),
67
+ [options.doseId ?? 'dose']: defineDoseCalculatorControlProps(options.dose),
68
+ }
69
+ }
70
+
71
+ /** Return named WellPlate + DoseCalculator component bindings for one dose-design control model. */
72
+ export function defineWellPlateDoseComponentBindings<TValues extends Record<string, unknown> = Record<string, unknown>>(
73
+ options: WellPlateDoseControlPropsOptions<TValues> = {},
74
+ ): ControlComponentBindingsConfig<TValues> {
75
+ return [
76
+ {
77
+ id: options.plateId ?? 'plate',
78
+ component: 'WellPlate',
79
+ props: defineWellPlateControlProps(options.plate),
80
+ },
81
+ {
82
+ id: options.doseId ?? 'dose',
83
+ component: 'DoseCalculator',
84
+ props: defineDoseCalculatorControlProps(options.dose),
85
+ },
86
+ ]
87
+ }
88
+
89
+ /** Return a complete ControlWorkspaceView model for WellPlate + DoseCalculator dose design. */
90
+ export function defineDoseDesignControlModel(
91
+ options: DoseDesignControlModelOptions = {},
92
+ ): ControlModelBinding {
93
+ const viewId = options.viewId ?? 'design'
94
+ const sectionId = options.sectionId ?? 'dose'
95
+ const doseControls: ControlSchema = {
96
+ selectedWells: {
97
+ type: 'tags',
98
+ label: 'Selected wells',
99
+ default: [...(options.selectedWells ?? ['A1', 'A2'])],
100
+ },
101
+ plateFormat: {
102
+ label: 'Plate format',
103
+ default: options.plateFormat ?? 96,
104
+ options: options.plateFormats ?? [96, 384],
105
+ },
106
+ doseMode: {
107
+ label: 'Dose mode',
108
+ default: options.doseMode ?? 'serial',
109
+ options: options.doseModes ?? ['serial', 'dilution', 'conversion'],
110
+ },
111
+ disabled: {
112
+ label: 'Disable tools',
113
+ default: options.disabled ?? false,
114
+ },
115
+ }
116
+
117
+ if (options.includeMolecularWeight) {
118
+ doseControls.molecularWeight = {
119
+ type: 'number',
120
+ label: 'Molecular weight',
121
+ default: options.molecularWeight ?? 300,
122
+ min: 0,
123
+ }
124
+ }
125
+
126
+ const componentProps: WellPlateDoseControlPropsOptions = {
127
+ ...options.componentProps,
128
+ dose: {
129
+ ...(options.componentProps?.dose ?? {}),
130
+ ...(options.includeMolecularWeight && options.componentProps?.dose?.molecularWeight === undefined
131
+ ? { molecularWeight: 'molecularWeight' }
132
+ : {}),
133
+ },
134
+ }
135
+
136
+ return defineControlModel({
137
+ componentBindings: defineWellPlateDoseComponentBindings(componentProps),
138
+ componentPropsById: defineWellPlateDoseControlProps(componentProps),
139
+ views: {
140
+ [viewId]: {
141
+ label: options.viewLabel ?? 'Design',
142
+ sections: {
143
+ [sectionId]: {
144
+ label: options.sectionLabel ?? 'Dose design',
145
+ description: options.sectionDescription ?? 'Well selection and dose calculator controls',
146
+ controls: doseControls,
147
+ },
148
+ },
149
+ },
150
+ },
151
+ })
152
+ }
153
+
154
+ function compactComponentPropsMap<TValues extends Record<string, unknown>>(
155
+ mapping: Record<string, ControlComponentPropSource<TValues> | undefined>,
156
+ ): ControlComponentPropsMap<TValues> {
157
+ return Object.fromEntries(
158
+ Object.entries(mapping).filter((entry): entry is [string, ControlComponentPropSource<TValues>] =>
159
+ entry[1] !== undefined
160
+ ),
161
+ )
162
+ }
163
+
164
+ function sourceKey<TValues extends Record<string, unknown>>(key: string): keyof TValues & string {
165
+ return key as keyof TValues & string
166
+ }
167
+
168
+ function updateControlValueSource<TValues extends Record<string, unknown>>(
169
+ source: ControlComponentPropSource<TValues>,
170
+ ): ((values: TValues) => (value: string[]) => void) | undefined {
171
+ if (typeof source !== 'string') return undefined
172
+ return values => (value: string[]) => {
173
+ const writableValues = values as Record<string, unknown>
174
+ writableValues[source] = value
175
+ }
176
+ }
177
+
178
+ function defaultDoseApplyHandler<TValues extends Record<string, unknown>>(
179
+ wells: ControlComponentPropSource<TValues>,
180
+ targetWells: ControlComponentPropSource<TValues>,
181
+ ): ((values: TValues) => (results: WellConcentration[]) => void) | undefined {
182
+ if (wells === targetWells) return undefined
183
+ return updateWellsFromDoseResults(wells)
184
+ }
185
+
186
+ function updateWellsFromDoseResults<TValues extends Record<string, unknown>>(
187
+ source: ControlComponentPropSource<TValues>,
188
+ ): ((values: TValues) => (results: WellConcentration[]) => void) | undefined {
189
+ if (typeof source !== 'string') return undefined
190
+ return values => (results: WellConcentration[]) => {
191
+ const writableValues = values as Record<string, unknown>
192
+ const currentWells = recordValue(writableValues[source])
193
+ const nextWells: Record<string, Record<string, unknown>> = {}
194
+ for (const [wellId, well] of Object.entries(currentWells)) {
195
+ nextWells[wellId] = recordValue(well)
196
+ }
197
+
198
+ for (const result of results) {
199
+ const existing = recordValue(nextWells[result.wellId])
200
+ const metadata = recordValue(existing.metadata)
201
+ nextWells[result.wellId] = {
202
+ ...existing,
203
+ state: 'filled',
204
+ value: result.concentration.value,
205
+ metadata: {
206
+ ...metadata,
207
+ concentration: result.concentration,
208
+ ...(result.volume === undefined ? {} : { volume: result.volume }),
209
+ },
210
+ }
211
+ }
212
+
213
+ writableValues[source] = nextWells
214
+ }
215
+ }
@@ -0,0 +1,61 @@
1
+ import type {
2
+ FieldValidation,
3
+ FormFieldSchema,
4
+ } from '../types/form-builder'
5
+ import {
6
+ defaultValueForControl,
7
+ normalizeOption,
8
+ type NormalizedControl,
9
+ } from './controlSchemaNormalize'
10
+ import {
11
+ humanize,
12
+ numericValue,
13
+ } from './controlSchemaUtils'
14
+ import type {
15
+ ControlDefinition,
16
+ } from './controlSchemaTypes'
17
+
18
+ export function controlToFormField(control: NormalizedControl): FormFieldSchema {
19
+ const { name, definition, type } = control
20
+ const props = fieldProps(definition)
21
+ return {
22
+ name,
23
+ label: definition.label ?? humanize(name),
24
+ type,
25
+ defaultValue: defaultValueForControl(definition, type),
26
+ placeholder: definition.placeholder,
27
+ hint: definition.hint,
28
+ size: definition.size,
29
+ disabled: definition.disabled,
30
+ readonly: definition.readonly,
31
+ validation: validationForControl(definition),
32
+ condition: definition.condition,
33
+ access: definition.access,
34
+ visibleFor: definition.visibleFor,
35
+ requiresAdmin: definition.requiresAdmin,
36
+ permissions: definition.permissions,
37
+ anyPermissions: definition.anyPermissions,
38
+ colSpan: definition.colSpan,
39
+ props,
40
+ }
41
+ }
42
+
43
+ function fieldProps(definition: ControlDefinition): Record<string, unknown> {
44
+ const props: Record<string, unknown> = {}
45
+ if (definition.min !== undefined) props.min = numericValue(definition.min)
46
+ if (definition.max !== undefined) props.max = numericValue(definition.max)
47
+ if (definition.options) props.options = definition.options.map(normalizeOption)
48
+ return { ...props, ...(definition.props ?? {}) }
49
+ }
50
+
51
+ function validationForControl(definition: ControlDefinition): FieldValidation | undefined {
52
+ const validation: FieldValidation = { ...(definition.validation ?? {}) }
53
+ if (definition.required !== undefined) validation.required = definition.required
54
+ if (definition.min !== undefined) validation.min = definition.min
55
+ if (definition.max !== undefined) validation.max = definition.max
56
+ if (definition.minLength !== undefined) validation.minLength = definition.minLength
57
+ if (definition.maxLength !== undefined) validation.maxLength = definition.maxLength
58
+ if (definition.email !== undefined) validation.email = definition.email
59
+ if (definition.pattern !== undefined) validation.pattern = definition.pattern
60
+ return Object.keys(validation).length > 0 ? validation : undefined
61
+ }