@morscherlab/mint-sdk 1.0.0-rc.4 → 1.0.0-rc.6

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 (324) 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/AppSidebar.vue.d.ts +9 -6
  41. package/dist/components/AppTopBar.navigation.d.ts +11 -0
  42. package/dist/components/BaseButton.vue.d.ts +1 -1
  43. package/dist/components/BaseCheckbox.vue.d.ts +7 -2
  44. package/dist/components/BaseInput.vue.d.ts +2 -2
  45. package/dist/components/BasePill.vue.d.ts +2 -2
  46. package/dist/components/BaseRadioGroup.vue.d.ts +2 -2
  47. package/dist/components/BaseSelect.vue.d.ts +1 -1
  48. package/dist/components/BaseSlider.vue.d.ts +2 -2
  49. package/dist/components/BaseTextarea.vue.d.ts +2 -2
  50. package/dist/components/BaseToggle.vue.d.ts +7 -2
  51. package/dist/components/BioTemplateExperimentWorkspaceView.vue.d.ts +2 -2
  52. package/dist/components/BioTemplatePackWorkspaceView.vue.d.ts +1 -1
  53. package/dist/components/CollapsibleCard.vue.d.ts +9 -0
  54. package/dist/components/ColorSlider.vue.d.ts +2 -2
  55. package/dist/components/ConcentrationInput.vue.d.ts +2 -2
  56. package/dist/components/ControlWorkspaceView.vue.d.ts +4 -4
  57. package/dist/components/DatePicker.vue.d.ts +1 -1
  58. package/dist/components/DateTimePicker.vue.d.ts +2 -2
  59. package/dist/components/DoseCalculatorVolumeField.vue.d.ts +15 -0
  60. package/dist/components/DoseDesignWorkspaceView.vue.d.ts +2 -2
  61. package/dist/components/DropdownButton.vue.d.ts +1 -1
  62. package/dist/components/FileUploader.vue.d.ts +2 -2
  63. package/dist/components/FormulaInput.vue.d.ts +2 -2
  64. package/dist/components/IconButton.vue.d.ts +1 -1
  65. package/dist/components/LoadingSpinner.vue.d.ts +1 -1
  66. package/dist/components/MoleculeInput.vue.d.ts +2 -2
  67. package/dist/components/MultiSelect.vue.d.ts +1 -1
  68. package/dist/components/NumberInput.vue.d.ts +1 -1
  69. package/dist/components/PlateMapEditor.vue.d.ts +6 -6
  70. package/dist/components/PluginWorkspaceView.controls.d.ts +28 -0
  71. package/dist/components/PluginWorkspaceView.navigation.d.ts +29 -0
  72. package/dist/components/PluginWorkspaceView.props.d.ts +151 -0
  73. package/dist/components/PluginWorkspaceView.shell.d.ts +19 -0
  74. package/dist/components/PluginWorkspaceView.vue.d.ts +51 -196
  75. package/dist/components/ProgressBar.vue.d.ts +1 -1
  76. package/dist/components/ProtocolStep.presentation.d.ts +4 -0
  77. package/dist/components/ProtocolStepEditor.state.d.ts +18 -0
  78. package/dist/components/ProtocolStepParameterField.vue.d.ts +12 -0
  79. package/dist/components/ReagentList.presentation.d.ts +16 -0
  80. package/dist/components/ResourceCard.vue.d.ts +1 -1
  81. package/dist/components/SampleSelector.colors.d.ts +13 -0
  82. package/dist/components/SampleSelector.drag.d.ts +24 -0
  83. package/dist/components/SampleSelector.groups.d.ts +15 -0
  84. package/dist/components/SampleSelector.selection.d.ts +26 -0
  85. package/dist/components/SampleSelector.vue.d.ts +4 -1
  86. package/dist/components/SampleSelectorSampleRow.vue.d.ts +21 -0
  87. package/dist/components/SegmentedControl.vue.d.ts +1 -1
  88. package/dist/components/SequenceInput.vue.d.ts +2 -2
  89. package/dist/components/SequenceProgressBar.vue.d.ts +1 -1
  90. package/dist/components/SettingsModal.schema.d.ts +9 -0
  91. package/dist/components/StatusIndicator.vue.d.ts +1 -1
  92. package/dist/components/TagsInput.vue.d.ts +2 -2
  93. package/dist/components/TimePicker.vue.d.ts +2 -2
  94. package/dist/components/TimeRangeInput.vue.d.ts +1 -1
  95. package/dist/components/UnitInput.vue.d.ts +2 -2
  96. package/dist/components/WellPlate.colors.d.ts +9 -0
  97. package/dist/components/WellPlate.conditions.d.ts +26 -0
  98. package/dist/components/WellPlate.geometry.d.ts +23 -0
  99. package/dist/components/WellPlate.interaction.d.ts +71 -0
  100. package/dist/components/WellPlate.legend.d.ts +2 -0
  101. package/dist/components/WellPlate.rendering.d.ts +24 -0
  102. package/dist/components/WellPlate.sampleDrop.d.ts +8 -0
  103. package/dist/components/WellPlate.vue.d.ts +1 -1
  104. package/dist/components/index.js +2 -2
  105. package/dist/components/internal/ActionItemInternal.vue.d.ts +1 -1
  106. package/dist/components/internal/PlateMapEditorToolbarInternal.vue.d.ts +28 -0
  107. package/dist/{components-DafPc4rM.js → components-Blx4MG--.js} +4073 -4222
  108. package/dist/components-Blx4MG--.js.map +1 -0
  109. package/dist/composables/autoGroup/classKey.d.ts +4 -0
  110. package/dist/composables/autoGroup/classify.d.ts +28 -0
  111. package/dist/composables/autoGroup/colors.d.ts +2 -0
  112. package/dist/composables/autoGroup/columns.d.ts +10 -0
  113. package/dist/composables/autoGroup/compose.d.ts +8 -0
  114. package/dist/composables/autoGroup/cooccurrence.d.ts +2 -0
  115. package/dist/composables/autoGroup/csv-shim.d.ts +2 -0
  116. package/dist/composables/autoGroup/fingerprint.d.ts +3 -0
  117. package/dist/composables/autoGroup/index.d.ts +16 -0
  118. package/dist/composables/autoGroup/replicatePreGroup.d.ts +38 -0
  119. package/dist/composables/autoGroup/template.d.ts +15 -0
  120. package/dist/composables/autoGroup/tokenize.d.ts +8 -0
  121. package/dist/composables/autoGroupConstants.d.ts +1 -0
  122. package/dist/composables/autoGroupGrouping.d.ts +3 -0
  123. package/dist/composables/controlComponentBindings.d.ts +1 -1
  124. package/dist/composables/controlSchemaAdapters.d.ts +1 -1
  125. package/dist/composables/controlSchemaDoseDesign.d.ts +11 -0
  126. package/dist/composables/controlSchemaLayout.d.ts +1 -1
  127. package/dist/composables/controlSchemaModel.d.ts +5 -0
  128. package/dist/composables/controlSchemaNormalize.d.ts +1 -1
  129. package/dist/composables/controlSchemaTypes.d.ts +311 -0
  130. package/dist/composables/controlWorkspaceOptions.d.ts +1 -1
  131. package/dist/composables/formBuilderSchema.d.ts +18 -0
  132. package/dist/composables/index.js +3 -3
  133. package/dist/composables/pluginEndpointBuilder.d.ts +13 -0
  134. package/dist/composables/protocolTemplateCatalog.d.ts +26 -0
  135. package/dist/composables/useAutoGroup.d.ts +61 -74
  136. package/dist/composables/useAutoGroupInputSources.d.ts +32 -0
  137. package/dist/composables/useBioTemplateControls.d.ts +1 -1
  138. package/dist/composables/useBioTemplatePresetWorkspace.d.ts +1 -1
  139. package/dist/composables/useBioTemplateWorkspace.d.ts +1 -1
  140. package/dist/composables/useControlSchema.d.ts +4 -316
  141. package/dist/composables/useControlWorkspace.d.ts +1 -1
  142. package/dist/composables/useForm.d.ts +2 -33
  143. package/dist/composables/useFormBuilder.d.ts +2 -9
  144. package/dist/composables/useFormValidation.d.ts +34 -0
  145. package/dist/composables/usePluginClient.d.ts +1 -4
  146. package/dist/composables/useProtocolTemplates.d.ts +2 -24
  147. package/dist/composables/useScheduleCalendarLayout.d.ts +49 -0
  148. package/dist/{composables-BMkPQhVK.js → composables-CHDjDIQT.js} +33 -31
  149. package/dist/composables-CHDjDIQT.js.map +1 -0
  150. package/dist/index.js +4 -4
  151. package/dist/install.js +2 -2
  152. package/dist/styles.css +1432 -660
  153. package/dist/templates/controlSchemaTypes.d.ts +1 -1
  154. package/dist/templates/index.js +1 -1
  155. package/dist/templates/templateAdapterTypes.d.ts +48 -0
  156. package/dist/templates/templateCreateOptions.d.ts +165 -0
  157. package/dist/templates/templateQpcrTypes.d.ts +42 -0
  158. package/dist/templates/types.d.ts +5 -250
  159. package/dist/{templates-bUAWMn5L.js → templates-DSbHJC4v.js} +1536 -297
  160. package/dist/templates-DSbHJC4v.js.map +1 -0
  161. package/dist/types/auto-group.d.ts +79 -9
  162. package/dist/types/componentLabTypes.d.ts +161 -0
  163. package/dist/types/componentWorkflowTypes.d.ts +150 -0
  164. package/dist/types/components.d.ts +14 -311
  165. package/dist/types/form-builder.d.ts +3 -0
  166. package/dist/types/index.d.ts +1 -1
  167. package/dist/{useProtocolTemplates-QZtHFFH2.js → useProtocolTemplates-BbPOYPzO.js} +1220 -454
  168. package/dist/useProtocolTemplates-BbPOYPzO.js.map +1 -0
  169. package/package.json +1 -1
  170. package/src/__tests__/components/AppSidebar.test.ts +67 -0
  171. package/src/__tests__/components/AppTopBar.navigation.test.ts +70 -0
  172. package/src/__tests__/components/CollapsibleCard.test.ts +47 -0
  173. package/src/__tests__/components/DoseCalculatorVolumeField.test.ts +53 -0
  174. package/src/__tests__/components/FormBuilder.test.ts +57 -0
  175. package/src/__tests__/components/PlateMapEditorToolbarInternal.test.ts +54 -0
  176. package/src/__tests__/components/PluginWorkspaceView.controls.test.ts +156 -0
  177. package/src/__tests__/components/PluginWorkspaceView.navigation.test.ts +102 -0
  178. package/src/__tests__/components/PluginWorkspaceView.shell.test.ts +43 -0
  179. package/src/__tests__/components/ProtocolStep.presentation.test.ts +31 -0
  180. package/src/__tests__/components/ProtocolStepEditor.state.test.ts +165 -0
  181. package/src/__tests__/components/ProtocolStepParameterField.test.ts +44 -0
  182. package/src/__tests__/components/ReagentList.presentation.test.ts +68 -0
  183. package/src/__tests__/components/SampleSelector.colors.test.ts +49 -0
  184. package/src/__tests__/components/SampleSelector.drag.test.ts +100 -0
  185. package/src/__tests__/components/SampleSelector.groups.test.ts +81 -0
  186. package/src/__tests__/components/SampleSelector.selection.test.ts +70 -0
  187. package/src/__tests__/components/SampleSelector.test.ts +32 -0
  188. package/src/__tests__/components/SampleSelectorSampleRow.test.ts +37 -0
  189. package/src/__tests__/components/ScheduleCalendar.test.ts +44 -0
  190. package/src/__tests__/components/SettingsModal.schema.test.ts +97 -0
  191. package/src/__tests__/components/WellPlate.colors.test.ts +28 -0
  192. package/src/__tests__/components/WellPlate.conditions.test.ts +68 -0
  193. package/src/__tests__/components/WellPlate.geometry.test.ts +54 -0
  194. package/src/__tests__/components/WellPlate.interaction.test.ts +171 -0
  195. package/src/__tests__/components/WellPlate.legend.test.ts +13 -0
  196. package/src/__tests__/components/WellPlate.rendering.test.ts +122 -0
  197. package/src/__tests__/components/WellPlate.sampleDrop.test.ts +70 -0
  198. package/src/__tests__/composables/autoGroup/classify.test.ts +107 -0
  199. package/src/__tests__/composables/autoGroup/columns.test.ts +135 -0
  200. package/src/__tests__/composables/autoGroup/compose.test.ts +227 -0
  201. package/src/__tests__/composables/autoGroup/cooccurrence.test.ts +91 -0
  202. package/src/__tests__/composables/autoGroup/fingerprint.test.ts +50 -0
  203. package/src/__tests__/composables/autoGroup/integration.test.ts +79 -0
  204. package/src/__tests__/composables/autoGroup/template.test.ts +70 -0
  205. package/src/__tests__/composables/autoGroup/tokenize.test.ts +33 -0
  206. package/src/__tests__/composables/useAutoGroup.test.ts +129 -625
  207. package/src/__tests__/composables/useAutoGroupInputSources.test.ts +107 -0
  208. package/src/__tests__/composables/useControlSchema.test.ts +23 -0
  209. package/src/__tests__/composables/useScheduleCalendarLayout.test.ts +89 -0
  210. package/src/__tests__/docs/extractDocsComponents.test.ts +142 -0
  211. package/src/__tests__/docs/extractDocsExports.test.ts +77 -0
  212. package/src/__tests__/docs/extractDocsParsing.test.ts +69 -0
  213. package/src/__tests__/docs/extractDocsTemplates.test.ts +54 -0
  214. package/src/__tests__/docs/extractDocsTheme.test.ts +89 -0
  215. package/src/__tests__/docs/frontendDocsCatalog.test.ts +1 -1
  216. package/src/__tests__/fixtures/auto-group/mixed-lc-ms-batch.txt +187 -0
  217. package/src/components/AppSidebar.story.vue +79 -6
  218. package/src/components/AppSidebar.vue +74 -6
  219. package/src/components/AppTopBar.navigation.ts +62 -0
  220. package/src/components/AppTopBar.vue +17 -44
  221. package/src/components/AutoGroupModal.story.vue +50 -0
  222. package/src/components/AutoGroupModal.vue +441 -158
  223. package/src/components/BaseCheckbox.story.vue +27 -0
  224. package/src/components/BaseCheckbox.vue +63 -1
  225. package/src/components/BaseToggle.story.vue +27 -0
  226. package/src/components/BaseToggle.vue +66 -1
  227. package/src/components/CollapsibleCard.vue +123 -45
  228. package/src/components/ControlWorkspaceView.vue +2 -6
  229. package/src/components/DoseCalculator.vue +13 -73
  230. package/src/components/DoseCalculatorVolumeField.vue +61 -0
  231. package/src/components/ExperimentTimeline.vue +6 -31
  232. package/src/components/FormBuilder.story.vue +13 -0
  233. package/src/components/FormBuilder.vue +2 -7
  234. package/src/components/PlateMapEditor.vue +32 -106
  235. package/src/components/PluginWorkspaceView.controls.ts +182 -0
  236. package/src/components/PluginWorkspaceView.navigation.ts +106 -0
  237. package/src/components/PluginWorkspaceView.props.ts +174 -0
  238. package/src/components/PluginWorkspaceView.shell.ts +67 -0
  239. package/src/components/PluginWorkspaceView.vue +88 -404
  240. package/src/components/ProtocolStep.presentation.ts +31 -0
  241. package/src/components/ProtocolStepEditor.state.ts +104 -0
  242. package/src/components/ProtocolStepEditor.vue +48 -179
  243. package/src/components/ProtocolStepParameterField.vue +134 -0
  244. package/src/components/ReagentList.presentation.ts +105 -0
  245. package/src/components/ReagentList.vue +16 -79
  246. package/src/components/SampleSelector.colors.ts +43 -0
  247. package/src/components/SampleSelector.drag.ts +164 -0
  248. package/src/components/SampleSelector.groups.ts +109 -0
  249. package/src/components/SampleSelector.selection.ts +103 -0
  250. package/src/components/SampleSelector.vue +82 -349
  251. package/src/components/SampleSelectorSampleRow.vue +64 -0
  252. package/src/components/ScheduleCalendar.vue +44 -199
  253. package/src/components/SettingsModal.schema.ts +71 -0
  254. package/src/components/SettingsModal.vue +16 -46
  255. package/src/components/WellPlate.colors.ts +56 -0
  256. package/src/components/WellPlate.conditions.ts +100 -0
  257. package/src/components/WellPlate.geometry.ts +91 -0
  258. package/src/components/WellPlate.interaction.ts +272 -0
  259. package/src/components/WellPlate.legend.ts +8 -0
  260. package/src/components/WellPlate.rendering.ts +105 -0
  261. package/src/components/WellPlate.sampleDrop.ts +73 -0
  262. package/src/components/WellPlate.vue +102 -550
  263. package/src/components/internal/FormFieldRendererInternal.vue +23 -5
  264. package/src/components/internal/PlateMapEditorToolbarInternal.vue +128 -0
  265. package/src/composables/autoGroup/classKey.ts +5 -0
  266. package/src/composables/autoGroup/classify.ts +205 -0
  267. package/src/composables/autoGroup/colors.ts +6 -0
  268. package/src/composables/autoGroup/columns.ts +226 -0
  269. package/src/composables/autoGroup/compose.ts +156 -0
  270. package/src/composables/autoGroup/cooccurrence.ts +46 -0
  271. package/src/composables/autoGroup/csv-shim.ts +44 -0
  272. package/src/composables/autoGroup/fingerprint.ts +49 -0
  273. package/src/composables/autoGroup/index.ts +20 -0
  274. package/src/composables/autoGroup/replicatePreGroup.ts +90 -0
  275. package/src/composables/autoGroup/template.ts +126 -0
  276. package/src/composables/autoGroup/tokenize.ts +41 -0
  277. package/src/composables/autoGroup/vocab.json +67 -0
  278. package/src/composables/autoGroupConstants.ts +4 -0
  279. package/src/composables/autoGroupGrouping.ts +148 -0
  280. package/src/composables/controlComponentBindings.ts +1 -1
  281. package/src/composables/controlSchemaAdapters.ts +4 -1
  282. package/src/composables/controlSchemaDoseDesign.ts +215 -0
  283. package/src/composables/controlSchemaFormFields.ts +4 -1
  284. package/src/composables/controlSchemaLayout.ts +1 -1
  285. package/src/composables/controlSchemaModel.ts +163 -0
  286. package/src/composables/controlSchemaNormalize.ts +1 -1
  287. package/src/composables/controlSchemaTypes.ts +372 -0
  288. package/src/composables/controlWorkspaceOptions.ts +1 -1
  289. package/src/composables/formBuilderSchema.ts +153 -0
  290. package/src/composables/pluginEndpointBuilder.ts +203 -0
  291. package/src/composables/protocolTemplateCatalog.ts +325 -0
  292. package/src/composables/useAutoGroup.ts +395 -549
  293. package/src/composables/useAutoGroupInputSources.ts +147 -0
  294. package/src/composables/useBioTemplateControls.ts +1 -1
  295. package/src/composables/useBioTemplatePresetWorkspace.ts +1 -1
  296. package/src/composables/useBioTemplateWorkspace.ts +1 -1
  297. package/src/composables/useControlSchema.ts +21 -692
  298. package/src/composables/useControlWorkspace.ts +7 -13
  299. package/src/composables/useForm.ts +5 -187
  300. package/src/composables/useFormBuilder.ts +11 -153
  301. package/src/composables/useFormValidation.ts +154 -0
  302. package/src/composables/usePluginClient.ts +10 -193
  303. package/src/composables/useProtocolTemplates.ts +10 -328
  304. package/src/composables/useScheduleCalendarLayout.ts +287 -0
  305. package/src/styles/components/app-sidebar.css +134 -6
  306. package/src/styles/components/auto-group-modal.css +248 -310
  307. package/src/styles/components/checkbox.css +87 -0
  308. package/src/styles/components/collapsible-card.css +154 -14
  309. package/src/styles/components/toggle.css +80 -0
  310. package/src/templates/controlSchemaTypes.ts +1 -1
  311. package/src/templates/templateAdapterTypes.ts +58 -0
  312. package/src/templates/templateCreateOptions.ts +208 -0
  313. package/src/templates/templateQpcrTypes.ts +48 -0
  314. package/src/templates/types.ts +79 -275
  315. package/src/types/auto-group.ts +107 -9
  316. package/src/types/componentLabTypes.ts +235 -0
  317. package/src/types/componentWorkflowTypes.ts +190 -0
  318. package/src/types/components.ts +95 -424
  319. package/src/types/form-builder.ts +3 -0
  320. package/src/types/index.ts +2 -0
  321. package/dist/components-DafPc4rM.js.map +0 -1
  322. package/dist/composables-BMkPQhVK.js.map +0 -1
  323. package/dist/templates-bUAWMn5L.js.map +0 -1
  324. package/dist/useProtocolTemplates-QZtHFFH2.js.map +0 -1
@@ -1,27 +1,6 @@
1
- import type {
2
- ComputedRef,
3
- Ref,
4
- } from 'vue'
5
- import type {
6
- PillNavItem,
7
- SidebarToolSection,
8
- SelectOption,
9
- SettingsModalSchema,
10
- TopBarSettingsConfig,
11
- } from '../types'
12
- import type { AccessPolicy, AccessAudienceInput } from '../permissions'
13
- import type {
14
- FieldCondition,
15
- FieldValidation,
16
- FormFieldSchema,
17
- FormFieldType,
18
- FormSchema,
19
- FormSectionSchema,
20
- } from '../types/form-builder'
21
1
  import {
22
2
  defaultValueForControl,
23
3
  normalizeControls,
24
- normalizeControlDefinition,
25
4
  } from './controlSchemaNormalize'
26
5
  import {
27
6
  controlToFormField,
@@ -35,11 +14,15 @@ import {
35
14
  controlsToTopBarSettingsConfig,
36
15
  controlsToViewItems,
37
16
  } from './controlSchemaAdapters'
38
- import {
39
- omitUndefined,
40
- recordValue,
41
- } from './controlSchemaUtils'
42
- import type { WellConcentration } from './useDoseCalculator'
17
+ import type {
18
+ ControlComponentBindingsConfig,
19
+ ControlSchema,
20
+ ControlSchemaOptions,
21
+ ControlValues,
22
+ UseControlSchemaReturn,
23
+ } from './controlSchemaTypes'
24
+
25
+ export type * from './controlSchemaTypes'
43
26
 
44
27
  export {
45
28
  mergeControlWorkspaceOptions,
@@ -67,348 +50,19 @@ export {
67
50
  getDefaultControlView,
68
51
  } from './controlSchemaAdapters'
69
52
 
70
- export type ControlOptionValue = string | number | boolean
71
- export type ControlOption = ControlOptionValue | SelectOption<unknown>
72
- export type ControlPrimitive = string | number | boolean
73
- export type ControlShorthand = ControlPrimitive | readonly ControlOption[]
74
- export type ControlInput = ControlDefinition | ControlShorthand
75
-
76
- export interface ControlSectionConfig {
77
- id?: string
78
- label?: string
79
- title?: string
80
- description?: string
81
- subtitle?: string
82
- icon?: string | string[]
83
- iconColor?: string
84
- iconBg?: string
85
- columns?: 1 | 2 | 3
86
- condition?: FieldCondition
87
- access?: AccessPolicy
88
- visibleFor?: AccessAudienceInput
89
- requiresAdmin?: boolean
90
- permissions?: readonly string[]
91
- anyPermissions?: readonly string[]
92
- defaultOpen?: boolean
93
- showToggle?: boolean
94
- }
95
-
96
- export interface ControlViewConfig {
97
- label?: string
98
- icon?: string
99
- to?: string
100
- href?: string
101
- disabled?: boolean
102
- children?: PillNavItem['children']
103
- }
104
-
105
- export interface ControlSidebarConfig extends Omit<ControlSectionConfig, 'id' | 'title' | 'description' | 'columns'> {
106
- enabled?: boolean
107
- }
108
-
109
- export interface ControlDefinition {
110
- type?: FormFieldType
111
- label?: string
112
- default?: unknown
113
- defaultValue?: unknown
114
- placeholder?: string
115
- hint?: string
116
- size?: 'sm' | 'md' | 'lg'
117
- disabled?: boolean
118
- readonly?: boolean
119
- required?: boolean | string
120
- min?: number | { value: number; message: string }
121
- max?: number | { value: number; message: string }
122
- minLength?: number | { value: number; message: string }
123
- maxLength?: number | { value: number; message: string }
124
- email?: boolean | string
125
- pattern?: string | { value: string; message: string }
126
- validation?: FieldValidation
127
- condition?: FieldCondition
128
- access?: AccessPolicy
129
- visibleFor?: AccessAudienceInput
130
- requiresAdmin?: boolean
131
- permissions?: readonly string[]
132
- anyPermissions?: readonly string[]
133
- options?: readonly ControlOption[]
134
- section?: string
135
- sectionLabel?: string
136
- sectionDescription?: string
137
- sectionSubtitle?: string
138
- view?: string
139
- order?: number
140
- colSpan?: number
141
- props?: Record<string, unknown>
142
- sidebar?: boolean | ControlSidebarConfig
143
- }
144
-
145
- export type ControlSchema = Record<string, ControlInput>
146
- export type ControlFormSchema = Extract<FormSchema, { sections: FormSectionSchema[] }>
147
-
148
- export interface ControlSchemaOptions {
149
- view?: string
150
- views?: Record<string, ControlViewConfig>
151
- section?: string
152
- sectionLabel?: string
153
- sections?: Record<string, ControlSectionConfig>
154
- columns?: 1 | 2 | 3
155
- submitLabel?: string
156
- cancelLabel?: string
157
- showCancel?: boolean
158
- }
159
-
160
- export interface ControlWorkspaceOptions extends ControlSchemaOptions {
161
- initialValues?: Record<string, unknown>
162
- topBarSettings?: Omit<TopBarSettingsConfig, 'schema' | 'controls' | 'controlOptions' | 'values'>
163
- }
164
-
165
- export interface ControlModelSectionConfig extends ControlSectionConfig {
166
- controls: ControlSchema
167
- sidebar?: boolean | ControlSidebarConfig
168
- }
169
-
170
- export interface ControlModelViewConfig extends ControlViewConfig {
171
- controls?: ControlSchema
172
- section?: string
173
- sectionLabel?: string
174
- sectionDescription?: string
175
- sections?: Record<string, ControlModelSectionConfig>
176
- }
177
-
178
- export interface ControlModel extends Omit<ControlWorkspaceOptions, 'sections' | 'views'> {
179
- controls?: ControlSchema
180
- sections?: Record<string, ControlModelSectionConfig>
181
- views?: Record<string, ControlModelViewConfig>
182
- /** Optional SDK component bindings returned with generated component props for custom workspace slots. */
183
- componentBindings?: ControlComponentBindingsConfig
184
- /** Alias for componentBindings in raw control models. */
185
- components?: ControlComponentBindingsConfig
186
- /** Optional ControlWorkspaceView componentProps mapping returned with the generated controls/options. */
187
- componentProps?: ControlComponentPropsMap
188
- /** Optional named componentProps mappings returned for multiple SDK components. */
189
- componentPropsById?: ControlComponentPropsByIdMap
190
- }
191
-
192
- export interface ControlModelBinding {
193
- controls: ControlSchema
194
- controlOptions: ControlWorkspaceOptions
195
- componentBindings?: ControlComponentBindingsConfig
196
- componentProps?: ControlComponentPropsMap
197
- componentPropsById?: ControlComponentPropsByIdMap
198
- }
199
-
200
- export interface ControlSidebarBinding {
201
- panels: Record<string, SidebarToolSection[]>
202
- forms: Record<string, ControlFormSchema>
203
- viewIds: string[]
204
- viewItems: PillNavItem[]
205
- defaultView: string
206
- }
207
-
208
- export interface ControlFormBinding {
209
- schema: ControlFormSchema
210
- }
211
-
212
- export interface ControlSettingsBinding {
213
- schema: SettingsModalSchema
214
- }
215
-
216
- export interface ControlTopBarSettingsBinding {
217
- showSettings: true
218
- settingsConfig: TopBarSettingsConfig
219
- }
220
-
221
- export interface ControlWorkspaceFormBinding extends ControlFormBinding {
222
- modelValue: Record<string, unknown>
223
- 'onUpdate:modelValue': (values: Record<string, unknown>) => void
224
- }
225
-
226
- export interface ControlWorkspaceSidebarBinding extends ControlSidebarBinding {
227
- activeView: string
228
- modelValue: Record<string, unknown>
229
- 'onUpdate:modelValue': (values: Record<string, unknown>) => void
230
- values: Record<string, unknown>
231
- 'onUpdate:values': (values: Record<string, unknown>) => void
232
- }
233
-
234
- export interface ControlWorkspaceTopBarSettingsBinding extends ControlTopBarSettingsBinding {
235
- onSettingsValuesChange: (values: Record<string, unknown>) => void
236
- }
237
-
238
- export interface ControlWorkspacePillNavBinding {
239
- items: PillNavItem[]
240
- currentItemId: string
241
- onSelect: (item: PillNavItem) => void
242
- }
243
-
244
- export interface ControlWorkspaceTopBarBinding extends ControlWorkspaceTopBarSettingsBinding {
245
- pillNav: PillNavItem[]
246
- currentPillId: string
247
- onPillSelect: (item: PillNavItem) => void
248
- }
249
-
250
- export type ControlWorkspaceAppTopBarPillBinding = ControlWorkspaceTopBarBinding
251
-
252
- export interface ControlWorkspaceComponentBindings {
253
- form: ControlWorkspaceFormBinding
254
- sidebar: ControlWorkspaceSidebarBinding
255
- topBar: ComputedRef<ControlWorkspaceTopBarBinding>
256
- topBarSettings: ControlWorkspaceTopBarSettingsBinding
257
- pillNav: ControlWorkspacePillNavBinding
258
- componentBindings: ComputedRef<ControlComponentBinding[]>
259
- componentBindingsById: ComputedRef<ControlComponentBindingsById>
260
- componentProps: ComputedRef<Record<string, unknown>>
261
- componentPropsById: ComputedRef<Record<string, Record<string, unknown>>>
262
- }
263
-
264
- export type ControlComponentPropSource<TValues extends Record<string, unknown> = Record<string, unknown>> =
265
- | (keyof TValues & string)
266
- | ((values: TValues) => unknown)
267
-
268
- export type ControlComponentPropsMap<TValues extends Record<string, unknown> = Record<string, unknown>> =
269
- | readonly (keyof TValues & string)[]
270
- | Record<string, ControlComponentPropSource<TValues>>
271
-
272
- export type ControlComponentPropsByIdMap<TValues extends Record<string, unknown> = Record<string, unknown>> =
273
- Record<string, ControlComponentPropsMap<TValues>>
274
-
275
- export interface ControlComponentBindingConfig<TValues extends Record<string, unknown> = Record<string, unknown>> {
276
- id?: string
277
- component: string
278
- props?: ControlComponentPropsMap<TValues>
279
- }
280
-
281
- export interface ControlComponentBindingRecordConfig<TValues extends Record<string, unknown> = Record<string, unknown>> {
282
- component: string
283
- props?: ControlComponentPropsMap<TValues>
284
- }
285
-
286
- export type ControlComponentBindingsConfig<TValues extends Record<string, unknown> = Record<string, unknown>> =
287
- | readonly ControlComponentBindingConfig<TValues>[]
288
- | Record<string, ControlComponentBindingRecordConfig<TValues>>
289
-
290
- export interface ControlComponentBinding {
291
- id: string
292
- component: string
293
- props: Record<string, unknown>
294
- }
295
-
296
- export type ControlComponentBindingsById = Record<string, ControlComponentBinding>
297
-
298
- export interface WellPlateControlPropsOptions<TValues extends Record<string, unknown> = Record<string, unknown>> {
299
- selectedWells?: ControlComponentPropSource<TValues>
300
- format?: ControlComponentPropSource<TValues>
301
- wells?: ControlComponentPropSource<TValues>
302
- disabled?: ControlComponentPropSource<TValues>
303
- readonly?: ControlComponentPropSource<TValues>
304
- showLegend?: ControlComponentPropSource<TValues>
305
- showSampleTypeIndicator?: ControlComponentPropSource<TValues>
306
- /** Listener for WellPlate v-model updates. Set false to keep generated props one-way. */
307
- onUpdateModelValue?: ((values: TValues) => (wellIds: string[]) => void) | false
308
- }
309
-
310
- export interface DoseCalculatorControlPropsOptions<TValues extends Record<string, unknown> = Record<string, unknown>> {
311
- mode?: ControlComponentPropSource<TValues>
312
- targetWells?: ControlComponentPropSource<TValues>
313
- /** Control value key used by the default apply-to-wells handler. */
314
- wells?: ControlComponentPropSource<TValues>
315
- disabled?: ControlComponentPropSource<TValues>
316
- molecularWeight?: ControlComponentPropSource<TValues>
317
- /** Listener for DoseCalculator apply-to-wells. Set false to keep generated props one-way. */
318
- onApplyToWells?: ((values: TValues) => (results: WellConcentration[]) => void) | false
319
- }
320
-
321
- export interface WellPlateDoseControlPropsOptions<TValues extends Record<string, unknown> = Record<string, unknown>> {
322
- plateId?: string
323
- doseId?: string
324
- plate?: WellPlateControlPropsOptions<TValues>
325
- dose?: DoseCalculatorControlPropsOptions<TValues>
326
- }
327
-
328
- export interface DoseDesignControlModelOptions {
329
- viewId?: string
330
- viewLabel?: string
331
- sectionId?: string
332
- sectionLabel?: string
333
- sectionDescription?: string
334
- selectedWells?: readonly string[]
335
- plateFormat?: number
336
- plateFormats?: readonly number[]
337
- doseMode?: 'serial' | 'dilution' | 'conversion'
338
- doseModes?: readonly ('serial' | 'dilution' | 'conversion')[]
339
- disabled?: boolean
340
- includeMolecularWeight?: boolean
341
- molecularWeight?: number
342
- componentProps?: WellPlateDoseControlPropsOptions
343
- }
344
-
345
- export interface UseControlSchemaReturn<TControls extends ControlSchema> {
346
- controls: TControls
347
- fields: FormFieldSchema[]
348
- formSchema: ControlFormSchema
349
- form: ControlFormBinding
350
- settingsSchema: SettingsModalSchema
351
- settings: ControlSettingsBinding
352
- topBarSettingsConfig: TopBarSettingsConfig
353
- topBarSettings: ControlTopBarSettingsBinding
354
- sidebarPanels: Record<string, SidebarToolSection[]>
355
- viewIds: string[]
356
- viewItems: PillNavItem[]
357
- defaultView: string
358
- sectionSchemas: Record<string, ControlFormSchema>
359
- sidebar: ControlSidebarBinding
360
- initialValues: ControlValues<TControls>
361
- sectionSchema: (sectionId: string) => ControlFormSchema
362
- }
363
-
364
- export interface UseControlWorkspaceReturn<TControls extends ControlSchema>
365
- extends Omit<UseControlSchemaReturn<TControls>, 'form' | 'sidebar' | 'topBarSettings'> {
366
- schema: UseControlSchemaReturn<TControls>
367
- values: ControlValues<TControls> & Record<string, unknown>
368
- activeView: Ref<string>
369
- form: ControlWorkspaceFormBinding
370
- sidebar: ControlWorkspaceSidebarBinding
371
- topBar: ComputedRef<ControlWorkspaceTopBarBinding>
372
- pillNav: ControlWorkspacePillNavBinding
373
- topBarSettings: ControlWorkspaceTopBarSettingsBinding
374
- bindings: ControlWorkspaceComponentBindings
375
- componentBindings: ComputedRef<ControlComponentBinding[]>
376
- componentBindingsById: ComputedRef<ControlComponentBindingsById>
377
- componentProps: ComputedRef<Record<string, unknown>>
378
- componentPropsById: ComputedRef<Record<string, Record<string, unknown>>>
379
- setActiveView: (viewId: string) => void
380
- setValues: (values: Record<string, unknown>) => void
381
- resetValues: (values?: Record<string, unknown>) => void
382
- getComponentProps: (
383
- mapping?: ControlComponentPropsMap<ControlValues<TControls> & Record<string, unknown>>
384
- ) => Record<string, unknown>
385
- getComponentPropsById: (
386
- mappings?: ControlComponentPropsByIdMap<ControlValues<TControls> & Record<string, unknown>>
387
- ) => Record<string, Record<string, unknown>>
388
- getComponentBindings: (
389
- bindings?: ControlComponentBindingsConfig<ControlValues<TControls> & Record<string, unknown>>
390
- ) => ControlComponentBinding[]
391
- getComponentBindingsById: (
392
- bindings?: ControlComponentBindingsConfig<ControlValues<TControls> & Record<string, unknown>>
393
- ) => ControlComponentBindingsById
394
- }
395
-
396
- export type ControlValues<TControls extends ControlSchema> = {
397
- [K in keyof TControls]: ControlValue<TControls[K]>
398
- }
399
-
400
- type ControlValue<TControl> =
401
- TControl extends { default: infer TDefault }
402
- ? TDefault
403
- : TControl extends { defaultValue: infer TDefaultValue }
404
- ? TDefaultValue
405
- : TControl extends readonly [infer First, ...unknown[]]
406
- ? OptionValue<First>
407
- : TControl extends ControlPrimitive
408
- ? TControl
409
- : unknown
53
+ export {
54
+ defineControlModel,
55
+ isControlModelBinding,
56
+ resolveControlModel,
57
+ } from './controlSchemaModel'
410
58
 
411
- type OptionValue<TOption> = TOption extends SelectOption<infer TValue> ? TValue : TOption
59
+ export {
60
+ defineDoseCalculatorControlProps,
61
+ defineDoseDesignControlModel,
62
+ defineWellPlateControlProps,
63
+ defineWellPlateDoseComponentBindings,
64
+ defineWellPlateDoseControlProps,
65
+ } from './controlSchemaDoseDesign'
412
66
 
413
67
  /** Preserve literal control keys while marking an object as a MINT control schema. */
414
68
  export function defineControls<TControls extends ControlSchema>(controls: TControls): TControls {
@@ -422,94 +76,6 @@ export function defineControlComponentBindings<TBindings extends ControlComponen
422
76
  return bindings
423
77
  }
424
78
 
425
- /** Create a complete workspace component binding from a simple controls data model for ControlWorkspaceView, generated forms, and sidebars. */
426
- export function defineControlModel(model: ControlModel): ControlModelBinding {
427
- const {
428
- controls: rootControls,
429
- sections: rootSections,
430
- views: modelViews,
431
- components,
432
- componentBindings,
433
- componentProps,
434
- componentPropsById,
435
- ...baseOptions
436
- } = model
437
- const resolvedComponentBindings = componentBindings ?? components
438
- const controls: ControlSchema = {}
439
- const views: Record<string, ControlViewConfig> = {}
440
- const sections: Record<string, ControlSectionConfig> = {}
441
-
442
- const defaultViewId = model.view ?? 'default'
443
- const defaultSectionId = model.section ?? 'controls'
444
-
445
- if (rootControls) {
446
- registerSectionOptions(sections, defaultSectionId, {
447
- id: defaultSectionId,
448
- label: model.sectionLabel,
449
- title: model.sectionLabel,
450
- columns: model.columns,
451
- })
452
- appendModelControls(controls, rootControls, defaultViewId, defaultSectionId)
453
- }
454
-
455
- for (const [sectionId, section] of Object.entries(rootSections ?? {})) {
456
- registerSectionOptions(sections, sectionId, controlModelSectionOptions(section))
457
- appendModelControls(controls, section.controls, defaultViewId, sectionId, section.sidebar)
458
- }
459
-
460
- for (const [viewId, view] of Object.entries(modelViews ?? {})) {
461
- const {
462
- controls: viewControls,
463
- sections: viewSections,
464
- section,
465
- sectionLabel,
466
- sectionDescription,
467
- ...viewConfig
468
- } = view
469
-
470
- views[viewId] = omitUndefined(viewConfig)
471
-
472
- if (viewControls) {
473
- const sectionId = section ?? `${viewId}-controls`
474
- const label = sectionLabel ?? view.label
475
- registerSectionOptions(sections, sectionId, {
476
- id: sectionId,
477
- label,
478
- title: label,
479
- description: sectionDescription,
480
- columns: model.columns,
481
- })
482
- appendModelControls(controls, viewControls, viewId, sectionId)
483
- }
484
-
485
- for (const [sectionKey, sectionConfig] of Object.entries(viewSections ?? {})) {
486
- const sectionId = sectionConfig.id ?? `${viewId}-${sectionKey}`
487
- registerSectionOptions(sections, sectionId, controlModelSectionOptions(sectionConfig))
488
- appendModelControls(controls, sectionConfig.controls, viewId, sectionId, sectionConfig.sidebar)
489
- }
490
- }
491
-
492
- const controlOptions: ControlWorkspaceOptions = {
493
- ...baseOptions,
494
- }
495
-
496
- if (Object.keys(views).length > 0) {
497
- controlOptions.views = views
498
- }
499
-
500
- if (Object.keys(sections).length > 0) {
501
- controlOptions.sections = sections
502
- }
503
-
504
- return {
505
- controls,
506
- controlOptions,
507
- ...(resolvedComponentBindings === undefined ? {} : { componentBindings: resolvedComponentBindings }),
508
- ...(componentProps === undefined ? {} : { componentProps }),
509
- ...(componentPropsById === undefined ? {} : { componentPropsById }),
510
- }
511
- }
512
-
513
79
  /** Build default values for a control schema, matching FormBuilder field defaults. */
514
80
  export function getControlDefaults<TControls extends ControlSchema>(
515
81
  controls: TControls,
@@ -521,139 +87,6 @@ export function getControlDefaults<TControls extends ControlSchema>(
521
87
  return values as ControlValues<TControls>
522
88
  }
523
89
 
524
- /** Return a default WellPlate prop mapping for generated control workspaces. */
525
- export function defineWellPlateControlProps<TValues extends Record<string, unknown> = Record<string, unknown>>(
526
- options: WellPlateControlPropsOptions<TValues> = {},
527
- ): ControlComponentPropsMap<TValues> {
528
- const selectedWells = options.selectedWells ?? sourceKey<TValues>('selectedWells')
529
- const onUpdateModelValue = options.onUpdateModelValue === false
530
- ? undefined
531
- : options.onUpdateModelValue ?? updateControlValueSource(selectedWells)
532
-
533
- return compactComponentPropsMap<TValues>({
534
- modelValue: selectedWells,
535
- 'onUpdate:modelValue': onUpdateModelValue,
536
- format: options.format ?? sourceKey<TValues>('plateFormat'),
537
- wells: options.wells ?? sourceKey<TValues>('wells'),
538
- disabled: options.disabled ?? sourceKey<TValues>('disabled'),
539
- readonly: options.readonly ?? sourceKey<TValues>('readonly'),
540
- showLegend: options.showLegend,
541
- showSampleTypeIndicator: options.showSampleTypeIndicator,
542
- })
543
- }
544
-
545
- /** Return a default DoseCalculator prop mapping for generated control workspaces. */
546
- export function defineDoseCalculatorControlProps<TValues extends Record<string, unknown> = Record<string, unknown>>(
547
- options: DoseCalculatorControlPropsOptions<TValues> = {},
548
- ): ControlComponentPropsMap<TValues> {
549
- const targetWells = options.targetWells ?? sourceKey<TValues>('selectedWells')
550
- const wells = options.wells ?? sourceKey<TValues>('wells')
551
- const onApplyToWells = options.onApplyToWells === false
552
- ? undefined
553
- : options.onApplyToWells ?? defaultDoseApplyHandler(wells, targetWells)
554
-
555
- return compactComponentPropsMap<TValues>({
556
- mode: options.mode ?? sourceKey<TValues>('doseMode'),
557
- targetWells,
558
- disabled: options.disabled ?? sourceKey<TValues>('disabled'),
559
- molecularWeight: options.molecularWeight,
560
- onApplyToWells,
561
- })
562
- }
563
-
564
- /** Return named WellPlate + DoseCalculator prop mappings for one dose-design control model. */
565
- export function defineWellPlateDoseControlProps<TValues extends Record<string, unknown> = Record<string, unknown>>(
566
- options: WellPlateDoseControlPropsOptions<TValues> = {},
567
- ): ControlComponentPropsByIdMap<TValues> {
568
- return {
569
- [options.plateId ?? 'plate']: defineWellPlateControlProps(options.plate),
570
- [options.doseId ?? 'dose']: defineDoseCalculatorControlProps(options.dose),
571
- }
572
- }
573
-
574
- /** Return named WellPlate + DoseCalculator component bindings for one dose-design control model. */
575
- export function defineWellPlateDoseComponentBindings<TValues extends Record<string, unknown> = Record<string, unknown>>(
576
- options: WellPlateDoseControlPropsOptions<TValues> = {},
577
- ): ControlComponentBindingsConfig<TValues> {
578
- return [
579
- {
580
- id: options.plateId ?? 'plate',
581
- component: 'WellPlate',
582
- props: defineWellPlateControlProps(options.plate),
583
- },
584
- {
585
- id: options.doseId ?? 'dose',
586
- component: 'DoseCalculator',
587
- props: defineDoseCalculatorControlProps(options.dose),
588
- },
589
- ]
590
- }
591
-
592
- /** Return a complete ControlWorkspaceView model for WellPlate + DoseCalculator dose design. */
593
- export function defineDoseDesignControlModel(
594
- options: DoseDesignControlModelOptions = {},
595
- ): ControlModelBinding {
596
- const viewId = options.viewId ?? 'design'
597
- const sectionId = options.sectionId ?? 'dose'
598
- const doseControls: ControlSchema = {
599
- selectedWells: {
600
- type: 'tags',
601
- label: 'Selected wells',
602
- default: [...(options.selectedWells ?? ['A1', 'A2'])],
603
- },
604
- plateFormat: {
605
- label: 'Plate format',
606
- default: options.plateFormat ?? 96,
607
- options: options.plateFormats ?? [96, 384],
608
- },
609
- doseMode: {
610
- label: 'Dose mode',
611
- default: options.doseMode ?? 'serial',
612
- options: options.doseModes ?? ['serial', 'dilution', 'conversion'],
613
- },
614
- disabled: {
615
- label: 'Disable tools',
616
- default: options.disabled ?? false,
617
- },
618
- }
619
-
620
- if (options.includeMolecularWeight) {
621
- doseControls.molecularWeight = {
622
- type: 'number',
623
- label: 'Molecular weight',
624
- default: options.molecularWeight ?? 300,
625
- min: 0,
626
- }
627
- }
628
-
629
- const componentProps: WellPlateDoseControlPropsOptions = {
630
- ...options.componentProps,
631
- dose: {
632
- ...(options.componentProps?.dose ?? {}),
633
- ...(options.includeMolecularWeight && options.componentProps?.dose?.molecularWeight === undefined
634
- ? { molecularWeight: 'molecularWeight' }
635
- : {}),
636
- },
637
- }
638
-
639
- return defineControlModel({
640
- componentBindings: defineWellPlateDoseComponentBindings(componentProps),
641
- componentPropsById: defineWellPlateDoseControlProps(componentProps),
642
- views: {
643
- [viewId]: {
644
- label: options.viewLabel ?? 'Design',
645
- sections: {
646
- [sectionId]: {
647
- label: options.sectionLabel ?? 'Dose design',
648
- description: options.sectionDescription ?? 'Well selection and dose calculator controls',
649
- controls: doseControls,
650
- },
651
- },
652
- },
653
- },
654
- })
655
- }
656
-
657
90
  /** Prepare FormBuilder, SettingsModal, AppTopBar settings, AppSidebar, and initial values from one compact control model. */
658
91
  export function useControlSchema<TControls extends ControlSchema>(
659
92
  controls: TControls,
@@ -700,107 +133,3 @@ export function useControlSchema<TControls extends ControlSchema>(
700
133
  sectionSchema: (sectionId: string) => controlsToSectionFormSchema(controls, sectionId, options),
701
134
  }
702
135
  }
703
-
704
- function appendModelControls(
705
- target: ControlSchema,
706
- source: ControlSchema,
707
- viewId: string,
708
- sectionId: string,
709
- sidebar?: boolean | ControlSidebarConfig,
710
- ): void {
711
- for (const [name, input] of Object.entries(source)) {
712
- if (Object.prototype.hasOwnProperty.call(target, name)) {
713
- throw new Error(
714
- `Duplicate control "${name}" in defineControlModel(). Control names must be unique across views and sections.`,
715
- )
716
- }
717
-
718
- const definition = normalizeControlDefinition(input)
719
- target[name] = omitUndefined({
720
- ...definition,
721
- view: definition.view ?? viewId,
722
- section: definition.section ?? sectionId,
723
- sidebar: definition.sidebar ?? sidebar,
724
- })
725
- }
726
- }
727
-
728
- function controlModelSectionOptions(section: ControlModelSectionConfig): ControlSectionConfig {
729
- const { controls: _controls, sidebar: _sidebar, ...options } = section
730
- return omitUndefined(options)
731
- }
732
-
733
- function registerSectionOptions(
734
- target: Record<string, ControlSectionConfig>,
735
- sectionId: string,
736
- options: ControlSectionConfig,
737
- ): void {
738
- target[sectionId] = omitUndefined({
739
- ...(target[sectionId] ?? {}),
740
- ...options,
741
- id: sectionId,
742
- })
743
- }
744
-
745
- function compactComponentPropsMap<TValues extends Record<string, unknown>>(
746
- mapping: Record<string, ControlComponentPropSource<TValues> | undefined>,
747
- ): ControlComponentPropsMap<TValues> {
748
- return Object.fromEntries(
749
- Object.entries(mapping).filter((entry): entry is [string, ControlComponentPropSource<TValues>] =>
750
- entry[1] !== undefined
751
- ),
752
- )
753
- }
754
-
755
- function sourceKey<TValues extends Record<string, unknown>>(key: string): keyof TValues & string {
756
- return key as keyof TValues & string
757
- }
758
-
759
- function updateControlValueSource<TValues extends Record<string, unknown>>(
760
- source: ControlComponentPropSource<TValues>,
761
- ): ((values: TValues) => (value: string[]) => void) | undefined {
762
- if (typeof source !== 'string') return undefined
763
- return values => (value: string[]) => {
764
- const writableValues = values as Record<string, unknown>
765
- writableValues[source] = value
766
- }
767
- }
768
-
769
- function defaultDoseApplyHandler<TValues extends Record<string, unknown>>(
770
- wells: ControlComponentPropSource<TValues>,
771
- targetWells: ControlComponentPropSource<TValues>,
772
- ): ((values: TValues) => (results: WellConcentration[]) => void) | undefined {
773
- if (wells === targetWells) return undefined
774
- return updateWellsFromDoseResults(wells)
775
- }
776
-
777
- function updateWellsFromDoseResults<TValues extends Record<string, unknown>>(
778
- source: ControlComponentPropSource<TValues>,
779
- ): ((values: TValues) => (results: WellConcentration[]) => void) | undefined {
780
- if (typeof source !== 'string') return undefined
781
- return values => (results: WellConcentration[]) => {
782
- const writableValues = values as Record<string, unknown>
783
- const currentWells = recordValue(writableValues[source])
784
- const nextWells: Record<string, Record<string, unknown>> = {}
785
- for (const [wellId, well] of Object.entries(currentWells)) {
786
- nextWells[wellId] = recordValue(well)
787
- }
788
-
789
- for (const result of results) {
790
- const existing = recordValue(nextWells[result.wellId])
791
- const metadata = recordValue(existing.metadata)
792
- nextWells[result.wellId] = {
793
- ...existing,
794
- state: 'filled',
795
- value: result.concentration.value,
796
- metadata: {
797
- ...metadata,
798
- concentration: result.concentration,
799
- ...(result.volume === undefined ? {} : { volume: result.volume }),
800
- },
801
- }
802
- }
803
-
804
- writableValues[source] = nextWells
805
- }
806
- }