@morscherlab/mint-sdk 1.0.0-beta.1 → 1.0.0-beta.3

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 (421) hide show
  1. package/README.md +218 -6
  2. package/dist/__tests__/components/ActionItem.test.d.ts +1 -0
  3. package/dist/__tests__/components/AppAvatarMenu.test.d.ts +1 -0
  4. package/dist/__tests__/components/AppPageSelector.test.d.ts +1 -0
  5. package/dist/__tests__/components/AppPillNav.test.d.ts +1 -0
  6. package/dist/__tests__/components/AppPluginSwitcher.test.d.ts +1 -0
  7. package/dist/__tests__/components/AppToastContainer.test.d.ts +1 -0
  8. package/dist/__tests__/components/BaseRadioGroup.test.d.ts +1 -0
  9. package/dist/__tests__/components/BaseSelect.test.d.ts +1 -0
  10. package/dist/__tests__/components/BaseTabs.test.d.ts +1 -0
  11. package/dist/__tests__/components/BatchProgressList.test.d.ts +1 -0
  12. package/dist/__tests__/components/BioTemplateExperimentWorkspaceView.test.d.ts +1 -0
  13. package/dist/__tests__/components/BioTemplatePackWorkspaceView.test.d.ts +1 -0
  14. package/dist/__tests__/components/BioTemplatePresetWorkspaceView.test.d.ts +1 -0
  15. package/dist/__tests__/components/BioTemplateRenderer.test.d.ts +1 -0
  16. package/dist/__tests__/components/Breadcrumb.test.d.ts +1 -0
  17. package/dist/__tests__/components/CalendarGridPanel.test.d.ts +1 -0
  18. package/dist/__tests__/components/ConcentrationInput.test.d.ts +1 -0
  19. package/dist/__tests__/components/ControlWorkspaceView.test.d.ts +1 -0
  20. package/dist/__tests__/components/DatePicker.test.d.ts +1 -0
  21. package/dist/__tests__/components/DateTimePicker.test.d.ts +1 -0
  22. package/dist/__tests__/components/EmptyState.test.d.ts +1 -0
  23. package/dist/__tests__/components/ExperimentPopover.test.d.ts +1 -0
  24. package/dist/__tests__/components/FormBuilder.test.d.ts +1 -0
  25. package/dist/__tests__/components/FormCompatibility.test.d.ts +1 -0
  26. package/dist/__tests__/components/GroupAssigner.test.d.ts +1 -0
  27. package/dist/__tests__/components/GroupingModal.test.d.ts +1 -0
  28. package/dist/__tests__/components/MultiSelect.test.d.ts +1 -0
  29. package/dist/__tests__/components/PluginIcon.test.d.ts +1 -0
  30. package/dist/__tests__/components/ProtocolStepEditor.test.d.ts +1 -0
  31. package/dist/__tests__/components/ReagentList.test.d.ts +1 -0
  32. package/dist/__tests__/components/SampleHierarchyTree.test.d.ts +1 -0
  33. package/dist/__tests__/components/SampleSelector.test.d.ts +1 -0
  34. package/dist/__tests__/components/SegmentedControl.test.d.ts +1 -0
  35. package/dist/__tests__/components/SettingsButton.test.d.ts +1 -0
  36. package/dist/__tests__/components/SettingsModal.test.d.ts +1 -0
  37. package/dist/__tests__/components/TagsInput.test.d.ts +1 -0
  38. package/dist/__tests__/components/ThemeToggle.test.d.ts +1 -0
  39. package/dist/__tests__/components/TimePicker.test.d.ts +1 -0
  40. package/dist/__tests__/composables/useBioTemplatePackWorkspace.test.d.ts +1 -0
  41. package/dist/__tests__/composables/useBioTemplatePresetWorkspace.test.d.ts +1 -0
  42. package/dist/__tests__/composables/useBioTemplateWorkspace.test.d.ts +1 -0
  43. package/dist/__tests__/composables/useCalendarGrid.test.d.ts +1 -0
  44. package/dist/__tests__/composables/useControlSchema.test.d.ts +1 -0
  45. package/dist/__tests__/composables/useDebouncedWatch.test.d.ts +1 -0
  46. package/dist/__tests__/composables/useDropdownState.test.d.ts +1 -0
  47. package/dist/__tests__/composables/useEventListener.test.d.ts +1 -0
  48. package/dist/__tests__/composables/useExpansionSet.test.d.ts +1 -0
  49. package/dist/__tests__/composables/useExperimentData.test.d.ts +1 -0
  50. package/dist/__tests__/composables/useExperimentSelector.test.d.ts +1 -0
  51. package/dist/__tests__/composables/useGroupAssignment.test.d.ts +1 -0
  52. package/dist/__tests__/composables/useListSelection.test.d.ts +1 -0
  53. package/dist/__tests__/composables/usePluginClient.test.d.ts +1 -0
  54. package/dist/__tests__/composables/usePluginConfig.test.d.ts +1 -0
  55. package/dist/__tests__/composables/useRequestSyncState.test.d.ts +1 -0
  56. package/dist/__tests__/composables/useSampleGroups.test.d.ts +1 -0
  57. package/dist/__tests__/composables/useSelectionLimit.test.d.ts +1 -0
  58. package/dist/__tests__/composables/useSortedItems.test.d.ts +1 -0
  59. package/dist/__tests__/composables/useTemplateCollection.test.d.ts +1 -0
  60. package/dist/__tests__/composables/useTextSearch.test.d.ts +1 -0
  61. package/dist/__tests__/composables/useTheme.test.d.ts +1 -0
  62. package/dist/__tests__/composables/useTimeUtils.test.d.ts +1 -0
  63. package/dist/__tests__/docs/frontendDocsCatalog.test.d.ts +1 -0
  64. package/dist/__tests__/templates/templates.test.d.ts +1 -0
  65. package/dist/{auth-DsI0rQ7_.js → auth-QQj2kkze.js} +12 -5
  66. package/dist/auth-QQj2kkze.js.map +1 -0
  67. package/dist/components/ActionItem.vue.d.ts +32 -0
  68. package/dist/components/AppAvatarMenu.vue.d.ts +2 -7
  69. package/dist/components/AppPageSelector.vue.d.ts +3 -6
  70. package/dist/components/AppPillNav.vue.d.ts +2 -2
  71. package/dist/components/AppSidebar.vue.d.ts +56 -3
  72. package/dist/components/AppToastContainer.vue.d.ts +2 -0
  73. package/dist/components/AppTopBar.vue.d.ts +43 -10
  74. package/dist/components/BaseButton.vue.d.ts +2 -2
  75. package/dist/components/BaseCheckbox.vue.d.ts +1 -1
  76. package/dist/components/BaseInput.vue.d.ts +2 -2
  77. package/dist/components/BasePill.vue.d.ts +3 -3
  78. package/dist/components/BaseRadioGroup.vue.d.ts +4 -4
  79. package/dist/components/BaseSelect.vue.d.ts +4 -4
  80. package/dist/components/BaseSlider.vue.d.ts +1 -1
  81. package/dist/components/BaseTabs.vue.d.ts +2 -2
  82. package/dist/components/BaseTextarea.vue.d.ts +2 -2
  83. package/dist/components/BaseToggle.vue.d.ts +1 -1
  84. package/dist/components/BioTemplateExperimentWorkspaceView.vue.d.ts +117 -0
  85. package/dist/components/BioTemplatePackWorkspaceView.vue.d.ts +92 -0
  86. package/dist/components/BioTemplatePresetWorkspaceView.vue.d.ts +82 -0
  87. package/dist/components/BioTemplateRenderer.vue.d.ts +29 -0
  88. package/dist/components/Breadcrumb.vue.d.ts +2 -2
  89. package/dist/components/Calendar.vue.d.ts +1 -1
  90. package/dist/components/CalendarGridPanel.vue.d.ts +25 -0
  91. package/dist/components/CollapsibleCard.vue.d.ts +1 -1
  92. package/dist/components/ColorSlider.vue.d.ts +1 -1
  93. package/dist/components/ConcentrationInput.vue.d.ts +2 -2
  94. package/dist/components/ConfirmDialog.vue.d.ts +2 -2
  95. package/dist/components/ControlWorkspaceView.vue.d.ts +130 -0
  96. package/dist/components/DatePicker.vue.d.ts +2 -2
  97. package/dist/components/DateTimePicker.vue.d.ts +3 -3
  98. package/dist/components/DropdownButton.vue.d.ts +4 -4
  99. package/dist/components/EmptyState.vue.d.ts +1 -2
  100. package/dist/components/ExperimentDataViewer.vue.d.ts +1 -1
  101. package/dist/components/ExperimentTimeline.vue.d.ts +2 -2
  102. package/dist/components/FileUploader.vue.d.ts +2 -2
  103. package/dist/components/FitPanel.vue.d.ts +1 -1
  104. package/dist/components/FormActions.vue.d.ts +4 -4
  105. package/dist/components/FormBuilder.vue.d.ts +22 -8
  106. package/dist/components/FormFieldRenderer.vue.d.ts +7 -10
  107. package/dist/components/FormSection.vue.d.ts +11 -24
  108. package/dist/components/FormulaInput.vue.d.ts +2 -2
  109. package/dist/components/IconButton.vue.d.ts +1 -1
  110. package/dist/components/LoadingSpinner.vue.d.ts +1 -1
  111. package/dist/components/MoleculeInput.vue.d.ts +2 -2
  112. package/dist/components/MultiSelect.vue.d.ts +3 -3
  113. package/dist/components/NumberInput.vue.d.ts +2 -2
  114. package/dist/components/PluginIcon.vue.d.ts +11 -0
  115. package/dist/components/ProgressBar.vue.d.ts +2 -2
  116. package/dist/components/ProtocolStepEditor.vue.d.ts +3 -1
  117. package/dist/components/RackEditor.vue.d.ts +2 -2
  118. package/dist/components/ReagentEditor.vue.d.ts +1 -1
  119. package/dist/components/ResourceCard.vue.d.ts +1 -1
  120. package/dist/components/SampleLegend.vue.d.ts +2 -2
  121. package/dist/components/SampleSelector.vue.d.ts +1 -1
  122. package/dist/components/ScheduleCalendar.vue.d.ts +2 -2
  123. package/dist/components/ScientificNumber.vue.d.ts +1 -1
  124. package/dist/components/SegmentedControl.vue.d.ts +3 -3
  125. package/dist/components/SequenceInput.vue.d.ts +3 -3
  126. package/dist/components/SettingsButton.vue.d.ts +2 -2
  127. package/dist/components/SettingsModal.vue.d.ts +32 -4
  128. package/dist/components/StatusIndicator.vue.d.ts +1 -1
  129. package/dist/components/TagsInput.vue.d.ts +3 -2
  130. package/dist/components/TimePicker.vue.d.ts +3 -3
  131. package/dist/components/TimeRangeInput.vue.d.ts +2 -2
  132. package/dist/components/UnitInput.vue.d.ts +2 -2
  133. package/dist/components/WellPlate.vue.d.ts +8 -8
  134. package/dist/components/index.d.ts +12 -1
  135. package/dist/components/index.js +3 -3
  136. package/dist/components/internal/FormFieldRendererInternal.vue.d.ts +31 -0
  137. package/dist/components/internal/FormSectionRenderer.vue.d.ts +43 -0
  138. package/dist/{components-CzbQQPCb.js → components-D_Sr0adg.js} +9629 -8647
  139. package/dist/components-D_Sr0adg.js.map +1 -0
  140. package/dist/composables/index.d.ts +21 -2
  141. package/dist/composables/index.js +4 -3
  142. package/dist/composables/platformContextHelpers.d.ts +14 -0
  143. package/dist/composables/useBioTemplateComponents.d.ts +20 -0
  144. package/dist/composables/useBioTemplateControls.d.ts +6 -0
  145. package/dist/composables/useBioTemplatePackWorkspace.d.ts +45 -0
  146. package/dist/composables/useBioTemplatePresetWorkspace.d.ts +74 -0
  147. package/dist/composables/useBioTemplateWorkspace.d.ts +50 -0
  148. package/dist/composables/useCalendarGrid.d.ts +26 -0
  149. package/dist/composables/useControlSchema.d.ts +321 -0
  150. package/dist/composables/useDebouncedWatch.d.ts +20 -0
  151. package/dist/composables/useDropdownState.d.ts +19 -0
  152. package/dist/composables/useEventListener.d.ts +13 -0
  153. package/dist/composables/useExpansionSet.d.ts +21 -0
  154. package/dist/composables/useExperimentData.d.ts +10 -0
  155. package/dist/composables/useExperimentSave.d.ts +31 -2
  156. package/dist/composables/useExperimentSelector.d.ts +20 -0
  157. package/dist/composables/useForm.d.ts +2 -0
  158. package/dist/composables/useGroupAssignment.d.ts +31 -0
  159. package/dist/composables/useListSelection.d.ts +35 -0
  160. package/dist/composables/usePlatformContext.d.ts +24 -3
  161. package/dist/composables/usePluginApi.d.ts +7 -14
  162. package/dist/composables/usePluginClient.d.ts +109 -0
  163. package/dist/composables/usePluginConfig.d.ts +12 -0
  164. package/dist/composables/useRequestSyncState.d.ts +34 -0
  165. package/dist/composables/useSampleGroups.d.ts +32 -0
  166. package/dist/composables/useSelectionLimit.d.ts +17 -0
  167. package/dist/composables/useSortedItems.d.ts +32 -0
  168. package/dist/composables/useTemplateCollection.d.ts +58 -0
  169. package/dist/composables/useTextSearch.d.ts +18 -0
  170. package/dist/composables/useTimeUtils.d.ts +8 -0
  171. package/dist/{composables-BXklV5ii.js → composables-C3dpXQN5.js} +228 -146
  172. package/dist/composables-C3dpXQN5.js.map +1 -0
  173. package/dist/index.d.ts +12 -3
  174. package/dist/index.js +6 -5
  175. package/dist/install.d.ts +7 -2
  176. package/dist/install.js +2 -2
  177. package/dist/install.js.map +1 -1
  178. package/dist/stores/auth.d.ts +1 -1
  179. package/dist/stores/index.js +1 -1
  180. package/dist/stores/settings.d.ts +4 -1
  181. package/dist/styles.css +5255 -5654
  182. package/dist/templates/adapters.d.ts +43 -0
  183. package/dist/templates/builders.d.ts +63 -0
  184. package/dist/templates/catalog.d.ts +188 -0
  185. package/dist/templates/componentBindings.d.ts +58 -0
  186. package/dist/templates/controlSchemas.d.ts +25 -0
  187. package/dist/templates/index.d.ts +15 -0
  188. package/dist/templates/index.js +2 -0
  189. package/dist/templates/lookup.d.ts +4 -0
  190. package/dist/templates/packs.d.ts +18 -0
  191. package/dist/templates/presets.d.ts +90 -0
  192. package/dist/templates/types.d.ts +531 -0
  193. package/dist/templates-50NPjaxL.js +9333 -0
  194. package/dist/templates-50NPjaxL.js.map +1 -0
  195. package/dist/types/components.d.ts +62 -1
  196. package/dist/types/form-builder.d.ts +6 -8
  197. package/dist/types/index.d.ts +2 -2
  198. package/dist/types/platform.d.ts +8 -1
  199. package/dist/useScheduleDrag-D4oWdh41.js +4371 -0
  200. package/dist/useScheduleDrag-D4oWdh41.js.map +1 -0
  201. package/dist/utils/formModelSync.d.ts +5 -0
  202. package/dist/utils/items.d.ts +8 -0
  203. package/dist/utils/options.d.ts +6 -0
  204. package/dist/utils/pluginIcon.d.ts +9 -0
  205. package/package.json +7 -2
  206. package/src/__tests__/components/ActionItem.test.ts +99 -0
  207. package/src/__tests__/components/AppAvatarMenu.test.ts +27 -0
  208. package/src/__tests__/components/AppPageSelector.test.ts +134 -0
  209. package/src/__tests__/components/AppPillNav.test.ts +78 -0
  210. package/src/__tests__/components/AppPluginSwitcher.test.ts +44 -0
  211. package/src/__tests__/components/AppSidebar.test.ts +370 -0
  212. package/src/__tests__/components/AppToastContainer.test.ts +48 -0
  213. package/src/__tests__/components/AppTopBar.test.ts +414 -13
  214. package/src/__tests__/components/BaseRadioGroup.test.ts +25 -0
  215. package/src/__tests__/components/BaseSelect.test.ts +21 -0
  216. package/src/__tests__/components/BaseTabs.test.ts +25 -0
  217. package/src/__tests__/components/BatchProgressList.test.ts +52 -0
  218. package/src/__tests__/components/BioTemplateExperimentWorkspaceView.test.ts +153 -0
  219. package/src/__tests__/components/BioTemplatePackWorkspaceView.test.ts +161 -0
  220. package/src/__tests__/components/BioTemplatePresetWorkspaceView.test.ts +281 -0
  221. package/src/__tests__/components/BioTemplateRenderer.test.ts +71 -0
  222. package/src/__tests__/components/Breadcrumb.test.ts +23 -0
  223. package/src/__tests__/components/CalendarGridPanel.test.ts +36 -0
  224. package/src/__tests__/components/ConcentrationInput.test.ts +45 -0
  225. package/src/__tests__/components/ControlWorkspaceView.test.ts +1031 -0
  226. package/src/__tests__/components/DataFrame.test.ts +11 -0
  227. package/src/__tests__/components/DatePicker.test.ts +45 -0
  228. package/src/__tests__/components/DateTimePicker.test.ts +48 -0
  229. package/src/__tests__/components/DropdownButton.test.ts +23 -0
  230. package/src/__tests__/components/EmptyState.test.ts +23 -0
  231. package/src/__tests__/components/ExperimentPopover.test.ts +56 -0
  232. package/src/__tests__/components/FormBuilder.test.ts +296 -0
  233. package/src/__tests__/components/FormCompatibility.test.ts +94 -0
  234. package/src/__tests__/components/GroupAssigner.test.ts +30 -0
  235. package/src/__tests__/components/GroupingModal.test.ts +73 -0
  236. package/src/__tests__/components/MultiSelect.test.ts +48 -0
  237. package/src/__tests__/components/PluginIcon.test.ts +119 -0
  238. package/src/__tests__/components/ProtocolStepEditor.test.ts +33 -0
  239. package/src/__tests__/components/ReagentList.test.ts +82 -0
  240. package/src/__tests__/components/SampleHierarchyTree.test.ts +53 -0
  241. package/src/__tests__/components/SampleSelector.test.ts +60 -0
  242. package/src/__tests__/components/SegmentedControl.test.ts +24 -0
  243. package/src/__tests__/components/SettingsButton.test.ts +44 -0
  244. package/src/__tests__/components/SettingsModal.test.ts +296 -0
  245. package/src/__tests__/components/TagsInput.test.ts +75 -0
  246. package/src/__tests__/components/ThemeToggle.test.ts +47 -0
  247. package/src/__tests__/components/TimePicker.test.ts +38 -0
  248. package/src/__tests__/composables/useBioTemplatePackWorkspace.test.ts +122 -0
  249. package/src/__tests__/composables/useBioTemplatePresetWorkspace.test.ts +199 -0
  250. package/src/__tests__/composables/useBioTemplateWorkspace.test.ts +99 -0
  251. package/src/__tests__/composables/useCalendarGrid.test.ts +38 -0
  252. package/src/__tests__/composables/useControlSchema.test.ts +919 -0
  253. package/src/__tests__/composables/useDebouncedWatch.test.ts +93 -0
  254. package/src/__tests__/composables/useDropdownState.test.ts +95 -0
  255. package/src/__tests__/composables/useEventListener.test.ts +116 -0
  256. package/src/__tests__/composables/useExpansionSet.test.ts +62 -0
  257. package/src/__tests__/composables/useExperimentData.test.ts +4 -0
  258. package/src/__tests__/composables/useExperimentSave.test.ts +203 -8
  259. package/src/__tests__/composables/useExperimentSelector.test.ts +164 -0
  260. package/src/__tests__/composables/useForm.test.ts +58 -0
  261. package/src/__tests__/composables/useFormBuilder.test.ts +77 -0
  262. package/src/__tests__/composables/useGroupAssignment.test.ts +73 -0
  263. package/src/__tests__/composables/useListSelection.test.ts +66 -0
  264. package/src/__tests__/composables/usePluginClient.test.ts +444 -0
  265. package/src/__tests__/composables/usePluginConfig.test.ts +5 -0
  266. package/src/__tests__/composables/useRequestSyncState.test.ts +92 -0
  267. package/src/__tests__/composables/useSampleGroups.test.ts +66 -0
  268. package/src/__tests__/composables/useSelectionLimit.test.ts +41 -0
  269. package/src/__tests__/composables/useSortedItems.test.ts +87 -0
  270. package/src/__tests__/composables/useTemplateCollection.test.ts +147 -0
  271. package/src/__tests__/composables/useTextSearch.test.ts +55 -0
  272. package/src/__tests__/composables/useTheme.test.ts +91 -0
  273. package/src/__tests__/composables/useTimeUtils.test.ts +35 -0
  274. package/src/__tests__/docs/frontendDocsCatalog.test.ts +229 -0
  275. package/src/__tests__/fixtures/templates/dose-response.json +81 -0
  276. package/src/__tests__/fixtures/templates/plate-map.json +54 -0
  277. package/src/__tests__/fixtures/templates/qpcr-plate.json +96 -0
  278. package/src/__tests__/fixtures/templates/sample-sheet.json +71 -0
  279. package/src/__tests__/templates/templates.test.ts +1043 -0
  280. package/src/components/ActionItem.vue +82 -0
  281. package/src/components/AppAvatarMenu.vue +15 -69
  282. package/src/components/AppLayout.story.vue +25 -25
  283. package/src/components/AppPageSelector.vue +63 -94
  284. package/src/components/AppPillNav.vue +44 -39
  285. package/src/components/AppPluginSwitcher.vue +41 -145
  286. package/src/components/AppSidebar.story.vue +94 -0
  287. package/src/components/AppSidebar.vue +187 -12
  288. package/src/components/{ToastNotification.story.vue → AppToastContainer.story.vue} +6 -6
  289. package/src/components/AppToastContainer.vue +62 -0
  290. package/src/components/AppTopBar.story.vue +7 -30
  291. package/src/components/AppTopBar.vue +283 -84
  292. package/src/components/BaseModal.vue +3 -5
  293. package/src/components/BaseRadioGroup.vue +7 -3
  294. package/src/components/BaseSelect.vue +11 -7
  295. package/src/components/BaseTabs.vue +6 -4
  296. package/src/components/BatchProgressList.vue +5 -8
  297. package/src/components/BioTemplateExperimentWorkspaceView.story.vue +123 -0
  298. package/src/components/BioTemplateExperimentWorkspaceView.vue +337 -0
  299. package/src/components/BioTemplatePackWorkspaceView.story.vue +107 -0
  300. package/src/components/BioTemplatePackWorkspaceView.vue +176 -0
  301. package/src/components/BioTemplatePresetWorkspaceView.story.vue +151 -0
  302. package/src/components/BioTemplatePresetWorkspaceView.vue +392 -0
  303. package/src/components/BioTemplateRenderer.story.vue +57 -0
  304. package/src/components/BioTemplateRenderer.vue +269 -0
  305. package/src/components/Breadcrumb.vue +14 -8
  306. package/src/components/CalendarGridPanel.vue +120 -0
  307. package/src/components/ConcentrationInput.vue +27 -64
  308. package/src/components/ControlWorkspaceView.story.vue +336 -0
  309. package/src/components/ControlWorkspaceView.vue +347 -0
  310. package/src/components/DataFrame.vue +34 -50
  311. package/src/components/DatePicker.vue +59 -192
  312. package/src/components/DateTimePicker.vue +50 -171
  313. package/src/components/DropdownButton.vue +14 -32
  314. package/src/components/EmptyState.vue +4 -2
  315. package/src/components/ExperimentPopover.vue +5 -22
  316. package/src/components/FormBuilder.vue +124 -27
  317. package/src/components/FormFieldRenderer.vue +15 -38
  318. package/src/components/FormSection.vue +20 -73
  319. package/src/components/GroupAssigner.vue +24 -56
  320. package/src/components/GroupingModal.story.vue +3 -3
  321. package/src/components/GroupingModal.vue +30 -391
  322. package/src/components/MultiSelect.vue +17 -12
  323. package/src/components/PlateMapEditor.vue +3 -8
  324. package/src/components/PluginIcon.story.vue +71 -0
  325. package/src/components/PluginIcon.vue +68 -0
  326. package/src/components/ProtocolStepEditor.vue +13 -22
  327. package/src/components/ReagentList.vue +25 -33
  328. package/src/components/SampleHierarchyTree.vue +12 -23
  329. package/src/components/SampleSelector.vue +42 -122
  330. package/src/components/SegmentedControl.vue +7 -3
  331. package/src/components/SettingsButton.story.vue +1 -1
  332. package/src/components/SettingsButton.vue +15 -27
  333. package/src/components/SettingsModal.story.vue +337 -45
  334. package/src/components/SettingsModal.vue +344 -66
  335. package/src/components/TagsInput.vue +29 -14
  336. package/src/components/ThemeToggle.vue +9 -7
  337. package/src/components/TimePicker.vue +19 -41
  338. package/src/components/ToastNotification.vue +4 -57
  339. package/src/components/Tooltip.vue +7 -12
  340. package/src/components/WellEditPopup.vue +3 -8
  341. package/src/components/WellPlate.vue +4 -10
  342. package/src/components/index.ts +12 -1
  343. package/src/components/internal/FormFieldRendererInternal.vue +50 -0
  344. package/src/components/internal/FormSectionRenderer.vue +78 -0
  345. package/src/composables/index.ts +212 -0
  346. package/src/composables/platformContextHelpers.ts +74 -0
  347. package/src/composables/useBioTemplateComponents.ts +93 -0
  348. package/src/composables/useBioTemplateControls.ts +41 -0
  349. package/src/composables/useBioTemplatePackWorkspace.ts +181 -0
  350. package/src/composables/useBioTemplatePresetWorkspace.ts +337 -0
  351. package/src/composables/useBioTemplateWorkspace.ts +139 -0
  352. package/src/composables/useCalendarGrid.ts +140 -0
  353. package/src/composables/useControlSchema.ts +1274 -0
  354. package/src/composables/useDebouncedWatch.ts +119 -0
  355. package/src/composables/useDropdownState.ts +83 -0
  356. package/src/composables/useEventListener.ts +111 -0
  357. package/src/composables/useExpansionSet.ts +117 -0
  358. package/src/composables/useExperimentData.ts +20 -11
  359. package/src/composables/useExperimentSave.ts +202 -50
  360. package/src/composables/useExperimentSelector.ts +86 -72
  361. package/src/composables/useForm.ts +49 -4
  362. package/src/composables/useFormBuilder.ts +93 -42
  363. package/src/composables/useGroupAssignment.ts +148 -0
  364. package/src/composables/useListSelection.ts +158 -0
  365. package/src/composables/usePluginApi.ts +7 -14
  366. package/src/composables/usePluginClient.ts +425 -0
  367. package/src/composables/usePluginConfig.ts +34 -13
  368. package/src/composables/useRequestSyncState.ts +126 -0
  369. package/src/composables/useSampleGroups.ts +126 -0
  370. package/src/composables/useSelectionLimit.ts +57 -0
  371. package/src/composables/useSortedItems.ts +118 -0
  372. package/src/composables/useTemplateCollection.ts +229 -0
  373. package/src/composables/useTextSearch.ts +60 -0
  374. package/src/composables/useTheme.ts +2 -28
  375. package/src/composables/useTimeUtils.ts +26 -2
  376. package/src/composables/useWellPlateEditor.ts +13 -9
  377. package/src/index.ts +228 -4
  378. package/src/install.ts +11 -4
  379. package/src/stores/settings.ts +13 -9
  380. package/src/styles/components/app-page-selector.css +23 -0
  381. package/src/styles/components/app-pill-nav.css +8 -2
  382. package/src/styles/components/app-top-bar.css +35 -2
  383. package/src/styles/components/button.css +3 -7
  384. package/src/styles/components/concentration-input.css +3 -142
  385. package/src/styles/components/dropdown-button.css +4 -4
  386. package/src/styles/components/empty-state.css +0 -16
  387. package/src/styles/components/input.css +4 -5
  388. package/src/styles/components/number-input.css +3 -3
  389. package/src/styles/components/plugin-icon.css +38 -0
  390. package/src/styles/components/segmented-control.css +4 -7
  391. package/src/styles/components/settings-button.css +3 -66
  392. package/src/styles/components/settings-modal.css +184 -0
  393. package/src/styles/components/tabs.css +1 -2
  394. package/src/styles/components/textarea.css +4 -5
  395. package/src/styles/components/theme-toggle.css +3 -66
  396. package/src/styles/components/unit-input.css +3 -3
  397. package/src/styles/index.css +0 -1
  398. package/src/templates/adapters.ts +785 -0
  399. package/src/templates/builders.ts +2149 -0
  400. package/src/templates/catalog.ts +245 -0
  401. package/src/templates/componentBindings.ts +615 -0
  402. package/src/templates/controlSchemas.ts +718 -0
  403. package/src/templates/index.ts +314 -0
  404. package/src/templates/lookup.ts +18 -0
  405. package/src/templates/packs.ts +156 -0
  406. package/src/templates/presets.ts +146 -0
  407. package/src/templates/types.ts +668 -0
  408. package/src/types/components.ts +80 -1
  409. package/src/types/form-builder.ts +7 -2
  410. package/src/types/index.ts +17 -0
  411. package/src/types/platform.ts +8 -1
  412. package/src/utils/formModelSync.ts +52 -0
  413. package/src/utils/items.ts +28 -0
  414. package/src/utils/options.ts +23 -0
  415. package/src/utils/pluginIcon.ts +30 -0
  416. package/dist/auth-DsI0rQ7_.js.map +0 -1
  417. package/dist/components-CzbQQPCb.js.map +0 -1
  418. package/dist/composables-BXklV5ii.js.map +0 -1
  419. package/dist/useScheduleDrag-CxBeqYcu.js +0 -7181
  420. package/dist/useScheduleDrag-CxBeqYcu.js.map +0 -1
  421. package/src/styles/components/grouping-modal.css +0 -323
@@ -0,0 +1,336 @@
1
+ <script setup lang="ts">
2
+ import { computed, defineComponent, h, ref } from 'vue'
3
+ import ControlWorkspaceView from './ControlWorkspaceView.vue'
4
+ import DoseCalculator from './DoseCalculator.vue'
5
+ import WellPlate from './WellPlate.vue'
6
+ import {
7
+ defineControlModel,
8
+ defineControls,
9
+ defineDoseDesignControlModel,
10
+ useControlWorkspace,
11
+ type ControlComponentPropsMap,
12
+ } from '../composables/useControlSchema'
13
+
14
+ const controls = defineControls({
15
+ threshold: {
16
+ type: 'number',
17
+ label: 'Threshold',
18
+ default: 0.05,
19
+ min: 0,
20
+ max: 1,
21
+ section: 'parameters',
22
+ sectionLabel: 'Parameters',
23
+ view: 'analysis',
24
+ },
25
+ method: {
26
+ label: 'Method',
27
+ default: 'linear',
28
+ options: ['linear', 'logistic', 'spline'],
29
+ section: 'parameters',
30
+ view: 'analysis',
31
+ },
32
+ chartScale: {
33
+ label: 'Scale',
34
+ default: 'linear',
35
+ options: ['linear', 'log'],
36
+ section: 'display',
37
+ sectionLabel: 'Display',
38
+ view: 'results',
39
+ },
40
+ })
41
+
42
+ const controlOptions = {
43
+ views: {
44
+ analysis: { label: 'Run' },
45
+ results: { label: 'Results' },
46
+ },
47
+ topBarSettings: {
48
+ title: 'Workspace settings',
49
+ showAppearance: false,
50
+ },
51
+ }
52
+
53
+ const workspace = useControlWorkspace(controls, controlOptions)
54
+ const directInitialValues = {
55
+ threshold: 0.1,
56
+ method: 'logistic',
57
+ }
58
+ const directModel = ref({ ...directInitialValues })
59
+ const nestedControlModel = defineControlModel({
60
+ views: {
61
+ design: {
62
+ label: 'Design',
63
+ sections: {
64
+ dose: {
65
+ label: 'Dose design',
66
+ description: 'Dose and replicate controls',
67
+ icon: 'settings',
68
+ columns: 2,
69
+ controls: {
70
+ concentrationUnit: ['uM', 'nM', 'mM'],
71
+ replicates: { type: 'number', default: 3, min: 1, max: 12 },
72
+ },
73
+ },
74
+ display: {
75
+ label: 'Display',
76
+ sidebar: false,
77
+ controls: {
78
+ showHeatmap: true,
79
+ },
80
+ },
81
+ },
82
+ },
83
+ results: {
84
+ label: 'Results',
85
+ section: 'plots',
86
+ sectionLabel: 'Plots',
87
+ controls: {
88
+ chartScale: ['linear', 'log'],
89
+ },
90
+ },
91
+ },
92
+ })
93
+ const nestedModelValues = ref({})
94
+ const doseDesignModel = defineDoseDesignControlModel({
95
+ selectedWells: ['A1', 'A2', 'B1', 'B2'],
96
+ includeMolecularWeight: true,
97
+ })
98
+ const doseDesignValues = ref({})
99
+ const componentPropsModel = ref({
100
+ threshold: 0.42,
101
+ method: 'logistic',
102
+ chartScale: 'log',
103
+ })
104
+ const componentPropsMap: ControlComponentPropsMap = {
105
+ score: 'threshold',
106
+ scale: 'chartScale',
107
+ method: 'method',
108
+ }
109
+
110
+ const MockResultChart = defineComponent({
111
+ name: 'MockResultChart',
112
+ props: {
113
+ score: { type: Number, default: 0 },
114
+ scale: { type: String, default: 'linear' },
115
+ method: { type: String, default: 'linear' },
116
+ },
117
+ setup(props) {
118
+ const barWidth = computed(() => `${Math.max(8, Math.min(100, props.score * 100))}%`)
119
+
120
+ return () => h('div', { class: 'component-props-demo' }, [
121
+ h('div', { class: 'component-props-demo__header' }, [
122
+ h('span', { class: 'component-props-demo__title' }, 'Result preview'),
123
+ h('span', { class: 'component-props-demo__badge' }, props.scale),
124
+ ]),
125
+ h('div', { class: 'component-props-demo__metric' }, [
126
+ h('span', 'Threshold'),
127
+ h('strong', props.score.toFixed(2)),
128
+ ]),
129
+ h('div', { class: 'component-props-demo__bar' }, [
130
+ h('span', { style: { width: barWidth.value } }),
131
+ ]),
132
+ h('div', { class: 'component-props-demo__meta' }, `Method: ${props.method}`),
133
+ ])
134
+ },
135
+ })
136
+
137
+ function initState() {
138
+ return {
139
+ title: 'Analysis Workspace',
140
+ sidebarPosition: 'left',
141
+ navigation: 'pill',
142
+ floating: false,
143
+ dense: true,
144
+ showSettings: true,
145
+ formLoading: false,
146
+ formDisabled: false,
147
+ formReadonly: false,
148
+ }
149
+ }
150
+ </script>
151
+
152
+ <template>
153
+ <Story title="Layout/ControlWorkspaceView" :init-state="initState">
154
+ <Variant title="Playground">
155
+ <template #default="{ state }">
156
+ <div style="min-height: 720px; background: var(--bg-secondary, #f8fafc);">
157
+ <ControlWorkspaceView
158
+ :workspace="workspace"
159
+ :title="state.title"
160
+ :sidebar-position="state.sidebarPosition"
161
+ :navigation="state.navigation"
162
+ :floating="state.floating"
163
+ :dense="state.dense"
164
+ :show-settings="state.showSettings"
165
+ :form-loading="state.formLoading"
166
+ :form-disabled="state.formDisabled"
167
+ :form-readonly="state.formReadonly"
168
+ />
169
+ </div>
170
+ </template>
171
+
172
+ <template #controls="{ state }">
173
+ <HstText v-model="state.title" title="Title" />
174
+ <HstSelect
175
+ v-model="state.sidebarPosition"
176
+ title="Sidebar"
177
+ :options="[
178
+ { label: 'Left', value: 'left' },
179
+ { label: 'Right', value: 'right' },
180
+ ]"
181
+ />
182
+ <HstSelect
183
+ v-model="state.navigation"
184
+ title="Navigation"
185
+ :options="[
186
+ { label: 'Pill', value: 'pill' },
187
+ { label: 'Tabs', value: 'tabs' },
188
+ ]"
189
+ />
190
+ <HstCheckbox v-model="state.floating" title="Floating" />
191
+ <HstCheckbox v-model="state.dense" title="Dense" />
192
+ <HstCheckbox v-model="state.showSettings" title="Settings" />
193
+ <HstCheckbox v-model="state.formLoading" title="Form loading" />
194
+ <HstCheckbox v-model="state.formDisabled" title="Form disabled" />
195
+ <HstCheckbox v-model="state.formReadonly" title="Form readonly" />
196
+ </template>
197
+ </Variant>
198
+
199
+ <Variant title="Direct Controls">
200
+ <template #default="{ state }">
201
+ <div style="min-height: 720px; background: var(--bg-secondary, #f8fafc);">
202
+ <ControlWorkspaceView
203
+ :controls="controls"
204
+ :control-options="controlOptions"
205
+ v-model="directModel"
206
+ title="Direct Controls Workspace"
207
+ :form-loading="state.formLoading"
208
+ :form-disabled="state.formDisabled"
209
+ :form-readonly="state.formReadonly"
210
+ />
211
+ </div>
212
+ </template>
213
+ </Variant>
214
+
215
+ <Variant title="Nested Model">
216
+ <div style="min-height: 720px; background: var(--bg-secondary, #f8fafc);">
217
+ <ControlWorkspaceView
218
+ v-model="nestedModelValues"
219
+ :model="nestedControlModel"
220
+ title="Nested Control Model"
221
+ />
222
+ </div>
223
+ </Variant>
224
+
225
+ <Variant title="Dose Design">
226
+ <div style="min-height: 720px; background: var(--bg-secondary, #f8fafc);">
227
+ <ControlWorkspaceView
228
+ v-model="doseDesignValues"
229
+ :model="doseDesignModel"
230
+ title="Dose Design Workspace"
231
+ v-slot="{ componentPropsById }"
232
+ >
233
+ <div class="dose-design-demo">
234
+ <WellPlate
235
+ v-bind="componentPropsById.plate"
236
+ size="fill"
237
+ selection-mode="multiple"
238
+ :heatmap="{ enabled: true, min: 0, max: 100, colorScale: 'viridis' }"
239
+ />
240
+ <DoseCalculator v-bind="componentPropsById.dose" />
241
+ </div>
242
+ </ControlWorkspaceView>
243
+ </div>
244
+ </Variant>
245
+
246
+ <Variant title="Component Props">
247
+ <div style="min-height: 720px; background: var(--bg-secondary, #f8fafc);">
248
+ <ControlWorkspaceView
249
+ v-model="componentPropsModel"
250
+ :controls="controls"
251
+ :control-options="controlOptions"
252
+ :component-props="componentPropsMap"
253
+ title="Component Props Workspace"
254
+ dense
255
+ v-slot="{ componentProps }"
256
+ >
257
+ <MockResultChart v-bind="componentProps" />
258
+ </ControlWorkspaceView>
259
+ </div>
260
+ </Variant>
261
+ </Story>
262
+ </template>
263
+
264
+ <style scoped>
265
+ .component-props-demo {
266
+ display: flex;
267
+ flex-direction: column;
268
+ gap: 1rem;
269
+ width: min(100%, 24rem);
270
+ padding: 1.25rem;
271
+ border: 1px solid var(--border-color);
272
+ border-radius: var(--radius-lg, 0.75rem);
273
+ background: var(--bg-primary);
274
+ color: var(--text-primary);
275
+ }
276
+
277
+ .dose-design-demo {
278
+ display: grid;
279
+ grid-template-columns: minmax(0, 1.4fr) minmax(18rem, 0.8fr);
280
+ gap: 1rem;
281
+ align-items: start;
282
+ }
283
+
284
+ .component-props-demo__header,
285
+ .component-props-demo__metric {
286
+ display: flex;
287
+ align-items: center;
288
+ justify-content: space-between;
289
+ gap: 1rem;
290
+ }
291
+
292
+ .component-props-demo__title {
293
+ font-size: 0.875rem;
294
+ font-weight: 600;
295
+ }
296
+
297
+ .component-props-demo__badge {
298
+ padding: 0.25rem 0.5rem;
299
+ border-radius: var(--radius-sm, 0.375rem);
300
+ background: var(--color-primary-soft);
301
+ color: var(--color-primary-hover);
302
+ font-size: 0.75rem;
303
+ font-weight: 600;
304
+ }
305
+
306
+ .component-props-demo__metric span,
307
+ .component-props-demo__meta {
308
+ color: var(--text-secondary);
309
+ font-size: 0.8125rem;
310
+ }
311
+
312
+ .component-props-demo__metric strong {
313
+ font-family: var(--font-mono, monospace);
314
+ font-size: 1.5rem;
315
+ }
316
+
317
+ .component-props-demo__bar {
318
+ height: 0.625rem;
319
+ overflow: hidden;
320
+ border-radius: 999px;
321
+ background: var(--bg-tertiary);
322
+ }
323
+
324
+ .component-props-demo__bar span {
325
+ display: block;
326
+ height: 100%;
327
+ border-radius: inherit;
328
+ background: var(--color-primary);
329
+ }
330
+
331
+ @media (max-width: 900px) {
332
+ .dose-design-demo {
333
+ grid-template-columns: minmax(0, 1fr);
334
+ }
335
+ }
336
+ </style>
@@ -0,0 +1,347 @@
1
+ <script setup lang="ts">
2
+ /** Page shell that turns a simple controls data model into AppTopBar, AppSidebar, and FormBuilder. */
3
+ import { computed, effectScope, onScopeDispose, shallowRef, toRaw, watch, type EffectScope } from 'vue'
4
+ import type { TopBarVariant } from '../types'
5
+ import type { FormEnhancements } from '../types/form-builder'
6
+ import type {
7
+ ControlComponentPropsByIdMap,
8
+ ControlComponentPropsMap,
9
+ ControlModel,
10
+ ControlModelBinding,
11
+ ControlSchema,
12
+ ControlWorkspaceOptions,
13
+ UseControlWorkspaceReturn,
14
+ } from '../composables/useControlSchema'
15
+ import { defineControlModel, mergeControlWorkspaceOptions, useControlWorkspace } from '../composables/useControlSchema'
16
+ import AppLayout from './AppLayout.vue'
17
+ import AppSidebar from './AppSidebar.vue'
18
+ import AppTopBar from './AppTopBar.vue'
19
+ import FormBuilder from './FormBuilder.vue'
20
+
21
+ type ControlWorkspaceNavigation = 'tabs' | 'pill'
22
+ type ResolvedControlWorkspace = UseControlWorkspaceReturn<ControlSchema>
23
+
24
+ interface ControlWorkspaceDefaultSlotProps {
25
+ workspace: ResolvedControlWorkspace
26
+ bindings: ResolvedControlWorkspace['bindings']
27
+ values: ResolvedControlWorkspace['values']
28
+ componentProps: ReturnType<ResolvedControlWorkspace['getComponentProps']>
29
+ componentPropsById: ReturnType<ResolvedControlWorkspace['getComponentPropsById']>
30
+ }
31
+
32
+ interface ControlWorkspaceTopbarSlotProps {
33
+ workspace: ResolvedControlWorkspace
34
+ bindings: ResolvedControlWorkspace['bindings']
35
+ topBar: ResolvedControlWorkspace['topBar']
36
+ }
37
+
38
+ interface ControlWorkspaceSidebarSlotProps {
39
+ workspace: ResolvedControlWorkspace
40
+ bindings: ResolvedControlWorkspace['bindings']
41
+ sidebar: ResolvedControlWorkspace['sidebar']
42
+ }
43
+
44
+ interface Props {
45
+ /** Model returned by defineControlModel()/defineDoseDesignControlModel(), or a raw nested ControlModel. */
46
+ model?: ControlModel | ControlModelBinding
47
+ /** Workspace returned by useControlWorkspace(). Use for full manual control. */
48
+ workspace?: UseControlWorkspaceReturn<ControlSchema>
49
+ /** Compact controls schema. When provided without workspace, the view creates the workspace internally. */
50
+ controls?: ControlSchema
51
+ /** Options passed to the internally generated useControlWorkspace() call. */
52
+ controlOptions?: ControlWorkspaceOptions
53
+ /** Initial values for the internally generated workspace. Merged over controlOptions.initialValues. */
54
+ initialValues?: Record<string, unknown>
55
+ /** External values for the internally generated workspace. Supports default v-model. */
56
+ modelValue?: Record<string, unknown>
57
+ /** External values for the internally generated workspace. Supports v-model:values. */
58
+ values?: Record<string, unknown>
59
+ /** AppTopBar title. */
60
+ title?: string
61
+ /** AppTopBar subtitle. */
62
+ subtitle?: string
63
+ /** AppTopBar visual variant. */
64
+ topBarVariant?: TopBarVariant
65
+ /** AppTopBar generated navigation style. "pill" uses the preferred AppPillNav surface; "tabs" keeps the legacy prop surface. */
66
+ navigation?: ControlWorkspaceNavigation
67
+ /** AppSidebar/AppLayout sidebar width. */
68
+ sidebarWidth?: string
69
+ /** Sidebar position in AppLayout. */
70
+ sidebarPosition?: 'left' | 'right'
71
+ /** Floating AppLayout style. */
72
+ floating?: boolean
73
+ /** Compact AppSidebar density. */
74
+ dense?: boolean
75
+ /** Whether AppTopBar should show generated settings. */
76
+ showSettings?: boolean
77
+ /** Render FormBuilder actions in the default content. */
78
+ showFormActions?: boolean
79
+ /** Runtime FormBuilder enhancements passed to generated forms. */
80
+ formEnhancements?: FormEnhancements<Record<string, unknown>>
81
+ /** Optional mapping from workspace values to component props exposed to the default slot. */
82
+ componentProps?: ControlComponentPropsMap
83
+ /** Optional named mappings from workspace values to component props exposed to the default slot. */
84
+ componentPropsById?: ControlComponentPropsByIdMap
85
+ /** Loading/saving state passed to generated forms. */
86
+ formLoading?: boolean
87
+ /** Disabled state passed to generated forms. */
88
+ formDisabled?: boolean
89
+ /** Readonly state passed to generated forms. */
90
+ formReadonly?: boolean
91
+ /** FormBuilder size in the default content. */
92
+ formSize?: 'sm' | 'md' | 'lg'
93
+ }
94
+
95
+ const emit = defineEmits<{
96
+ /** Emitted when generated workspace values change through FormBuilder, AppSidebar, or AppTopBar settings. */
97
+ 'update:modelValue': [values: Record<string, unknown>]
98
+ /** Emitted when generated workspace values change through FormBuilder, AppSidebar, or AppTopBar settings. */
99
+ 'update:values': [values: Record<string, unknown>]
100
+ /** Forwarded from the default FormBuilder when showFormActions is enabled. */
101
+ submit: [values: Record<string, unknown>]
102
+ /** Forwarded from the default FormBuilder when showFormActions is enabled. */
103
+ cancel: []
104
+ }>()
105
+
106
+ defineSlots<{
107
+ default?: (props: ControlWorkspaceDefaultSlotProps) => unknown
108
+ topbar?: (props: ControlWorkspaceTopbarSlotProps) => unknown
109
+ sidebar?: (props: ControlWorkspaceSidebarSlotProps) => unknown
110
+ }>()
111
+
112
+ const props = withDefaults(defineProps<Props>(), {
113
+ model: undefined,
114
+ workspace: undefined,
115
+ controls: undefined,
116
+ controlOptions: () => ({}),
117
+ initialValues: undefined,
118
+ modelValue: undefined,
119
+ values: undefined,
120
+ title: 'Workspace',
121
+ subtitle: undefined,
122
+ topBarVariant: 'card',
123
+ navigation: 'pill',
124
+ sidebarWidth: '320px',
125
+ sidebarPosition: 'left',
126
+ floating: false,
127
+ dense: true,
128
+ showSettings: true,
129
+ showFormActions: false,
130
+ formEnhancements: undefined,
131
+ componentProps: undefined,
132
+ componentPropsById: undefined,
133
+ formLoading: false,
134
+ formDisabled: false,
135
+ formReadonly: false,
136
+ formSize: 'md',
137
+ })
138
+
139
+ const externalValues = computed(() => props.modelValue ?? props.values)
140
+ const resolvedModel = computed<ControlModelBinding | undefined>(() => {
141
+ if (props.model === undefined) return undefined
142
+ return isControlModelBinding(props.model) ? props.model : defineControlModel(props.model)
143
+ })
144
+ const resolvedControls = computed<ControlSchema>(() => props.controls ?? resolvedModel.value?.controls ?? {})
145
+ const baseControlOptions = computed<ControlWorkspaceOptions>(() =>
146
+ mergeControlWorkspaceOptions(resolvedModel.value?.controlOptions ?? {}, props.controlOptions)
147
+ )
148
+
149
+ const resolvedControlOptions = computed<ControlWorkspaceOptions>(() => {
150
+ if (props.initialValues === undefined && externalValues.value === undefined) return baseControlOptions.value
151
+
152
+ return {
153
+ ...baseControlOptions.value,
154
+ initialValues: {
155
+ ...(baseControlOptions.value.initialValues ?? {}),
156
+ ...(props.initialValues ?? {}),
157
+ ...(externalValues.value ?? {}),
158
+ },
159
+ }
160
+ })
161
+
162
+ let generatedWorkspaceScope: EffectScope | undefined
163
+
164
+ function createGeneratedWorkspace(seedValues: Record<string, unknown> = {}) {
165
+ generatedWorkspaceScope?.stop()
166
+ generatedWorkspaceScope = effectScope()
167
+ return generatedWorkspaceScope.run(() =>
168
+ useControlWorkspace(resolvedControls.value, {
169
+ ...resolvedControlOptions.value,
170
+ initialValues: {
171
+ ...seedValues,
172
+ ...(resolvedControlOptions.value.initialValues ?? {}),
173
+ },
174
+ })
175
+ )!
176
+ }
177
+
178
+ const generatedWorkspace = shallowRef<UseControlWorkspaceReturn<ControlSchema>>(createGeneratedWorkspace())
179
+ const resolvedWorkspace = computed<UseControlWorkspaceReturn<ControlSchema>>(() => props.workspace ?? generatedWorkspace.value)
180
+ const resolvedComponentProps = computed(() =>
181
+ resolvedWorkspace.value.getComponentProps(props.componentProps ?? resolvedModel.value?.componentProps)
182
+ )
183
+ const resolvedComponentPropsById = computed(() =>
184
+ resolvedWorkspace.value.getComponentPropsById(props.componentPropsById ?? resolvedModel.value?.componentPropsById)
185
+ )
186
+ const resolvedBindings = computed<ResolvedControlWorkspace['bindings']>(() => ({
187
+ ...resolvedWorkspace.value.bindings,
188
+ componentProps: resolvedComponentProps,
189
+ componentPropsById: resolvedComponentPropsById,
190
+ }))
191
+
192
+ watch(
193
+ [() => props.model, () => props.controls, () => props.controlOptions, () => props.initialValues],
194
+ () => {
195
+ const previousWorkspace = generatedWorkspace.value
196
+ const previousActiveView = previousWorkspace.activeView.value
197
+ generatedWorkspace.value = createGeneratedWorkspace({ ...previousWorkspace.values })
198
+ generatedWorkspace.value.setActiveView(previousActiveView)
199
+ },
200
+ { deep: true },
201
+ )
202
+
203
+ onScopeDispose(() => generatedWorkspaceScope?.stop())
204
+
205
+ watch(
206
+ externalValues,
207
+ (values) => {
208
+ if (values === undefined || props.workspace !== undefined) return
209
+ if (recordsEqual(generatedWorkspace.value.values, values)) return
210
+ generatedWorkspace.value.setValues(values)
211
+ },
212
+ { deep: true },
213
+ )
214
+
215
+ watch(
216
+ () => generatedWorkspace.value.values,
217
+ (values) => {
218
+ if (props.workspace !== undefined) return
219
+ const nextValues = { ...values }
220
+ if (externalValues.value !== undefined && recordsEqual(externalValues.value, nextValues)) return
221
+ emit('update:modelValue', nextValues)
222
+ emit('update:values', nextValues)
223
+ },
224
+ { deep: true },
225
+ )
226
+
227
+ function recordsEqual(left: Record<string, unknown>, right: Record<string, unknown>): boolean {
228
+ const leftKeys = Object.keys(left)
229
+ const rightKeys = Object.keys(right)
230
+ if (leftKeys.length !== rightKeys.length) return false
231
+ return leftKeys.every(key => valuesEqual(left[key], right[key]))
232
+ }
233
+
234
+ function valuesEqual(left: unknown, right: unknown): boolean {
235
+ const leftRaw = toRaw(left)
236
+ const rightRaw = toRaw(right)
237
+
238
+ if (Object.is(leftRaw, rightRaw)) return true
239
+
240
+ if (Array.isArray(leftRaw) || Array.isArray(rightRaw)) {
241
+ if (!Array.isArray(leftRaw) || !Array.isArray(rightRaw)) return false
242
+ if (leftRaw.length !== rightRaw.length) return false
243
+ return leftRaw.every((item, index) => valuesEqual(item, rightRaw[index]))
244
+ }
245
+
246
+ if (isPlainRecord(leftRaw) || isPlainRecord(rightRaw)) {
247
+ if (!isPlainRecord(leftRaw) || !isPlainRecord(rightRaw)) return false
248
+ return recordsEqual(leftRaw, rightRaw)
249
+ }
250
+
251
+ return false
252
+ }
253
+
254
+ function isPlainRecord(value: unknown): value is Record<string, unknown> {
255
+ return typeof value === 'object' && value !== null && !Array.isArray(value)
256
+ }
257
+
258
+ function isControlModelBinding(model: ControlModel | ControlModelBinding): model is ControlModelBinding {
259
+ return 'controlOptions' in model
260
+ }
261
+ </script>
262
+
263
+ <template>
264
+ <AppLayout
265
+ class="mint-control-workspace-view"
266
+ :sidebar-position="sidebarPosition"
267
+ :sidebar-width="sidebarWidth"
268
+ :floating="floating"
269
+ >
270
+ <template #topbar>
271
+ <slot
272
+ name="topbar"
273
+ :workspace="resolvedWorkspace"
274
+ :bindings="resolvedBindings"
275
+ :top-bar="resolvedWorkspace.topBar"
276
+ >
277
+ <AppTopBar
278
+ :title="title"
279
+ :subtitle="subtitle"
280
+ :variant="topBarVariant"
281
+ :tabs="navigation === 'tabs' ? resolvedWorkspace.topBar.tabs : undefined"
282
+ :current-tab-id="navigation === 'tabs' ? resolvedWorkspace.topBar.currentTabId : undefined"
283
+ :pill-nav="navigation === 'pill' ? resolvedWorkspace.pillNav.items : undefined"
284
+ :current-pill-id="navigation === 'pill' ? resolvedWorkspace.pillNav.currentItemId : undefined"
285
+ :show-settings="showSettings"
286
+ :settings-config="resolvedWorkspace.topBarSettings.settingsConfig"
287
+ @tab-select="resolvedWorkspace.topBar.onTabSelect"
288
+ @pill-select="resolvedWorkspace.pillNav.onSelect"
289
+ @settings-values-change="resolvedWorkspace.topBarSettings.onSettingsValuesChange"
290
+ />
291
+ </slot>
292
+ </template>
293
+
294
+ <template #sidebar>
295
+ <slot
296
+ name="sidebar"
297
+ :workspace="resolvedWorkspace"
298
+ :bindings="resolvedBindings"
299
+ :sidebar="resolvedWorkspace.sidebar"
300
+ >
301
+ <AppSidebar
302
+ v-bind="resolvedWorkspace.sidebar"
303
+ :floating="false"
304
+ :dense="dense"
305
+ :width="sidebarWidth"
306
+ :form-enhancements="formEnhancements"
307
+ :form-loading="formLoading"
308
+ :form-disabled="formDisabled"
309
+ :form-readonly="formReadonly"
310
+ />
311
+ </slot>
312
+ </template>
313
+
314
+ <main class="mint-control-workspace-view__content">
315
+ <slot
316
+ :workspace="resolvedWorkspace"
317
+ :bindings="resolvedBindings"
318
+ :values="resolvedWorkspace.values"
319
+ :component-props="resolvedComponentProps"
320
+ :component-props-by-id="resolvedComponentPropsById"
321
+ >
322
+ <FormBuilder
323
+ v-bind="resolvedWorkspace.form"
324
+ :enhancements="formEnhancements"
325
+ :loading="formLoading"
326
+ :disabled="formDisabled"
327
+ :readonly="formReadonly"
328
+ :show-actions="showFormActions"
329
+ :size="formSize"
330
+ @submit="emit('submit', $event)"
331
+ @cancel="emit('cancel')"
332
+ />
333
+ </slot>
334
+ </main>
335
+ </AppLayout>
336
+ </template>
337
+
338
+ <style scoped>
339
+ .mint-control-workspace-view {
340
+ min-width: 0;
341
+ }
342
+
343
+ .mint-control-workspace-view__content {
344
+ min-width: 0;
345
+ padding: 1rem;
346
+ }
347
+ </style>