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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (304) 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 +3 -3
  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 +1 -1
  44. package/dist/components/BaseInput.vue.d.ts +2 -2
  45. package/dist/components/BasePill.vue.d.ts +1 -1
  46. package/dist/components/BaseRadioGroup.vue.d.ts +1 -1
  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 +1 -1
  51. package/dist/components/BioTemplateExperimentWorkspaceView.vue.d.ts +2 -2
  52. package/dist/components/BioTemplatePackWorkspaceView.vue.d.ts +1 -1
  53. package/dist/components/ColorSlider.vue.d.ts +2 -2
  54. package/dist/components/ConcentrationInput.vue.d.ts +2 -2
  55. package/dist/components/ControlWorkspaceView.vue.d.ts +3 -3
  56. package/dist/components/DatePicker.vue.d.ts +1 -1
  57. package/dist/components/DateTimePicker.vue.d.ts +2 -2
  58. package/dist/components/DoseCalculatorVolumeField.vue.d.ts +15 -0
  59. package/dist/components/DoseDesignWorkspaceView.vue.d.ts +1 -1
  60. package/dist/components/DropdownButton.vue.d.ts +1 -1
  61. package/dist/components/FileUploader.vue.d.ts +2 -2
  62. package/dist/components/FormulaInput.vue.d.ts +2 -2
  63. package/dist/components/IconButton.vue.d.ts +1 -1
  64. package/dist/components/LoadingSpinner.vue.d.ts +1 -1
  65. package/dist/components/MoleculeInput.vue.d.ts +2 -2
  66. package/dist/components/MultiSelect.vue.d.ts +1 -1
  67. package/dist/components/NumberInput.vue.d.ts +1 -1
  68. package/dist/components/PlateMapEditor.vue.d.ts +6 -6
  69. package/dist/components/PluginWorkspaceView.controls.d.ts +28 -0
  70. package/dist/components/PluginWorkspaceView.navigation.d.ts +29 -0
  71. package/dist/components/PluginWorkspaceView.props.d.ts +151 -0
  72. package/dist/components/PluginWorkspaceView.shell.d.ts +19 -0
  73. package/dist/components/PluginWorkspaceView.vue.d.ts +46 -195
  74. package/dist/components/ProgressBar.vue.d.ts +1 -1
  75. package/dist/components/ProtocolStep.presentation.d.ts +4 -0
  76. package/dist/components/ProtocolStepEditor.state.d.ts +18 -0
  77. package/dist/components/ProtocolStepParameterField.vue.d.ts +12 -0
  78. package/dist/components/ReagentList.presentation.d.ts +16 -0
  79. package/dist/components/ResourceCard.vue.d.ts +1 -1
  80. package/dist/components/SampleSelector.colors.d.ts +13 -0
  81. package/dist/components/SampleSelector.drag.d.ts +24 -0
  82. package/dist/components/SampleSelector.groups.d.ts +15 -0
  83. package/dist/components/SampleSelector.selection.d.ts +26 -0
  84. package/dist/components/SampleSelector.vue.d.ts +4 -1
  85. package/dist/components/SampleSelectorSampleRow.vue.d.ts +21 -0
  86. package/dist/components/SegmentedControl.vue.d.ts +1 -1
  87. package/dist/components/SequenceInput.vue.d.ts +2 -2
  88. package/dist/components/SequenceProgressBar.vue.d.ts +1 -1
  89. package/dist/components/SettingsModal.schema.d.ts +9 -0
  90. package/dist/components/StatusIndicator.vue.d.ts +1 -1
  91. package/dist/components/TagsInput.vue.d.ts +2 -2
  92. package/dist/components/TimePicker.vue.d.ts +2 -2
  93. package/dist/components/TimeRangeInput.vue.d.ts +1 -1
  94. package/dist/components/UnitInput.vue.d.ts +2 -2
  95. package/dist/components/WellPlate.colors.d.ts +9 -0
  96. package/dist/components/WellPlate.conditions.d.ts +26 -0
  97. package/dist/components/WellPlate.geometry.d.ts +23 -0
  98. package/dist/components/WellPlate.interaction.d.ts +71 -0
  99. package/dist/components/WellPlate.legend.d.ts +2 -0
  100. package/dist/components/WellPlate.rendering.d.ts +24 -0
  101. package/dist/components/WellPlate.sampleDrop.d.ts +8 -0
  102. package/dist/components/WellPlate.vue.d.ts +1 -1
  103. package/dist/components/index.js +2 -2
  104. package/dist/components/internal/ActionItemInternal.vue.d.ts +1 -1
  105. package/dist/components/internal/PlateMapEditorToolbarInternal.vue.d.ts +28 -0
  106. package/dist/{components-DafPc4rM.js → components-DtHA2bgp.js} +3754 -2991
  107. package/dist/components-DtHA2bgp.js.map +1 -0
  108. package/dist/composables/autoGroup/classKey.d.ts +4 -0
  109. package/dist/composables/autoGroup/classify.d.ts +28 -0
  110. package/dist/composables/autoGroup/colors.d.ts +2 -0
  111. package/dist/composables/autoGroup/columns.d.ts +10 -0
  112. package/dist/composables/autoGroup/compose.d.ts +8 -0
  113. package/dist/composables/autoGroup/cooccurrence.d.ts +2 -0
  114. package/dist/composables/autoGroup/csv-shim.d.ts +2 -0
  115. package/dist/composables/autoGroup/fingerprint.d.ts +3 -0
  116. package/dist/composables/autoGroup/index.d.ts +16 -0
  117. package/dist/composables/autoGroup/replicatePreGroup.d.ts +38 -0
  118. package/dist/composables/autoGroup/template.d.ts +15 -0
  119. package/dist/composables/autoGroup/tokenize.d.ts +8 -0
  120. package/dist/composables/autoGroupConstants.d.ts +1 -0
  121. package/dist/composables/autoGroupGrouping.d.ts +3 -0
  122. package/dist/composables/controlComponentBindings.d.ts +1 -1
  123. package/dist/composables/controlSchemaAdapters.d.ts +1 -1
  124. package/dist/composables/controlSchemaDoseDesign.d.ts +11 -0
  125. package/dist/composables/controlSchemaLayout.d.ts +1 -1
  126. package/dist/composables/controlSchemaModel.d.ts +5 -0
  127. package/dist/composables/controlSchemaNormalize.d.ts +1 -1
  128. package/dist/composables/controlSchemaTypes.d.ts +305 -0
  129. package/dist/composables/controlWorkspaceOptions.d.ts +1 -1
  130. package/dist/composables/formBuilderSchema.d.ts +18 -0
  131. package/dist/composables/index.js +3 -3
  132. package/dist/composables/pluginEndpointBuilder.d.ts +13 -0
  133. package/dist/composables/protocolTemplateCatalog.d.ts +26 -0
  134. package/dist/composables/useAutoGroup.d.ts +61 -74
  135. package/dist/composables/useAutoGroupInputSources.d.ts +32 -0
  136. package/dist/composables/useBioTemplateControls.d.ts +1 -1
  137. package/dist/composables/useBioTemplatePresetWorkspace.d.ts +1 -1
  138. package/dist/composables/useBioTemplateWorkspace.d.ts +1 -1
  139. package/dist/composables/useControlSchema.d.ts +4 -316
  140. package/dist/composables/useControlWorkspace.d.ts +1 -1
  141. package/dist/composables/useForm.d.ts +2 -33
  142. package/dist/composables/useFormBuilder.d.ts +2 -9
  143. package/dist/composables/useFormValidation.d.ts +34 -0
  144. package/dist/composables/usePluginClient.d.ts +1 -4
  145. package/dist/composables/useProtocolTemplates.d.ts +2 -24
  146. package/dist/composables/useScheduleCalendarLayout.d.ts +49 -0
  147. package/dist/{composables-BMkPQhVK.js → composables-Dlg8jenH.js} +33 -31
  148. package/dist/composables-Dlg8jenH.js.map +1 -0
  149. package/dist/index.js +4 -4
  150. package/dist/install.js +2 -2
  151. package/dist/styles.css +547 -516
  152. package/dist/templates/controlSchemaTypes.d.ts +1 -1
  153. package/dist/templates/index.js +1 -1
  154. package/dist/templates/templateAdapterTypes.d.ts +48 -0
  155. package/dist/templates/templateCreateOptions.d.ts +165 -0
  156. package/dist/templates/templateQpcrTypes.d.ts +42 -0
  157. package/dist/templates/types.d.ts +5 -250
  158. package/dist/{templates-bUAWMn5L.js → templates-DtdUvJ4c.js} +144 -136
  159. package/dist/templates-DtdUvJ4c.js.map +1 -0
  160. package/dist/types/auto-group.d.ts +79 -9
  161. package/dist/types/componentLabTypes.d.ts +161 -0
  162. package/dist/types/componentWorkflowTypes.d.ts +150 -0
  163. package/dist/types/components.d.ts +2 -311
  164. package/dist/{useProtocolTemplates-QZtHFFH2.js → useProtocolTemplates-Bm5vyH4_.js} +1220 -454
  165. package/dist/useProtocolTemplates-Bm5vyH4_.js.map +1 -0
  166. package/package.json +1 -1
  167. package/src/__tests__/components/AppTopBar.navigation.test.ts +70 -0
  168. package/src/__tests__/components/DoseCalculatorVolumeField.test.ts +53 -0
  169. package/src/__tests__/components/PlateMapEditorToolbarInternal.test.ts +54 -0
  170. package/src/__tests__/components/PluginWorkspaceView.controls.test.ts +156 -0
  171. package/src/__tests__/components/PluginWorkspaceView.navigation.test.ts +102 -0
  172. package/src/__tests__/components/PluginWorkspaceView.shell.test.ts +41 -0
  173. package/src/__tests__/components/ProtocolStep.presentation.test.ts +31 -0
  174. package/src/__tests__/components/ProtocolStepEditor.state.test.ts +165 -0
  175. package/src/__tests__/components/ProtocolStepParameterField.test.ts +44 -0
  176. package/src/__tests__/components/ReagentList.presentation.test.ts +68 -0
  177. package/src/__tests__/components/SampleSelector.colors.test.ts +49 -0
  178. package/src/__tests__/components/SampleSelector.drag.test.ts +100 -0
  179. package/src/__tests__/components/SampleSelector.groups.test.ts +81 -0
  180. package/src/__tests__/components/SampleSelector.selection.test.ts +70 -0
  181. package/src/__tests__/components/SampleSelector.test.ts +32 -0
  182. package/src/__tests__/components/SampleSelectorSampleRow.test.ts +37 -0
  183. package/src/__tests__/components/ScheduleCalendar.test.ts +44 -0
  184. package/src/__tests__/components/SettingsModal.schema.test.ts +97 -0
  185. package/src/__tests__/components/WellPlate.colors.test.ts +28 -0
  186. package/src/__tests__/components/WellPlate.conditions.test.ts +68 -0
  187. package/src/__tests__/components/WellPlate.geometry.test.ts +54 -0
  188. package/src/__tests__/components/WellPlate.interaction.test.ts +171 -0
  189. package/src/__tests__/components/WellPlate.legend.test.ts +13 -0
  190. package/src/__tests__/components/WellPlate.rendering.test.ts +122 -0
  191. package/src/__tests__/components/WellPlate.sampleDrop.test.ts +70 -0
  192. package/src/__tests__/composables/autoGroup/classify.test.ts +107 -0
  193. package/src/__tests__/composables/autoGroup/columns.test.ts +135 -0
  194. package/src/__tests__/composables/autoGroup/compose.test.ts +227 -0
  195. package/src/__tests__/composables/autoGroup/cooccurrence.test.ts +91 -0
  196. package/src/__tests__/composables/autoGroup/fingerprint.test.ts +50 -0
  197. package/src/__tests__/composables/autoGroup/integration.test.ts +79 -0
  198. package/src/__tests__/composables/autoGroup/template.test.ts +70 -0
  199. package/src/__tests__/composables/autoGroup/tokenize.test.ts +33 -0
  200. package/src/__tests__/composables/useAutoGroup.test.ts +129 -625
  201. package/src/__tests__/composables/useAutoGroupInputSources.test.ts +107 -0
  202. package/src/__tests__/composables/useControlSchema.test.ts +23 -0
  203. package/src/__tests__/composables/useScheduleCalendarLayout.test.ts +89 -0
  204. package/src/__tests__/docs/extractDocsComponents.test.ts +142 -0
  205. package/src/__tests__/docs/extractDocsExports.test.ts +77 -0
  206. package/src/__tests__/docs/extractDocsParsing.test.ts +69 -0
  207. package/src/__tests__/docs/extractDocsTemplates.test.ts +54 -0
  208. package/src/__tests__/docs/extractDocsTheme.test.ts +89 -0
  209. package/src/__tests__/docs/frontendDocsCatalog.test.ts +1 -1
  210. package/src/__tests__/fixtures/auto-group/mixed-lc-ms-batch.txt +187 -0
  211. package/src/components/AppSidebar.vue +2 -6
  212. package/src/components/AppTopBar.navigation.ts +62 -0
  213. package/src/components/AppTopBar.vue +17 -44
  214. package/src/components/AutoGroupModal.story.vue +50 -0
  215. package/src/components/AutoGroupModal.vue +441 -158
  216. package/src/components/ControlWorkspaceView.vue +2 -6
  217. package/src/components/DoseCalculator.vue +13 -73
  218. package/src/components/DoseCalculatorVolumeField.vue +61 -0
  219. package/src/components/ExperimentTimeline.vue +6 -31
  220. package/src/components/FormBuilder.vue +2 -7
  221. package/src/components/PlateMapEditor.vue +32 -106
  222. package/src/components/PluginWorkspaceView.controls.ts +182 -0
  223. package/src/components/PluginWorkspaceView.navigation.ts +106 -0
  224. package/src/components/PluginWorkspaceView.props.ts +174 -0
  225. package/src/components/PluginWorkspaceView.shell.ts +66 -0
  226. package/src/components/PluginWorkspaceView.vue +85 -404
  227. package/src/components/ProtocolStep.presentation.ts +31 -0
  228. package/src/components/ProtocolStepEditor.state.ts +104 -0
  229. package/src/components/ProtocolStepEditor.vue +48 -179
  230. package/src/components/ProtocolStepParameterField.vue +134 -0
  231. package/src/components/ReagentList.presentation.ts +105 -0
  232. package/src/components/ReagentList.vue +16 -79
  233. package/src/components/SampleSelector.colors.ts +43 -0
  234. package/src/components/SampleSelector.drag.ts +164 -0
  235. package/src/components/SampleSelector.groups.ts +109 -0
  236. package/src/components/SampleSelector.selection.ts +103 -0
  237. package/src/components/SampleSelector.vue +82 -349
  238. package/src/components/SampleSelectorSampleRow.vue +64 -0
  239. package/src/components/ScheduleCalendar.vue +44 -199
  240. package/src/components/SettingsModal.schema.ts +71 -0
  241. package/src/components/SettingsModal.vue +16 -46
  242. package/src/components/WellPlate.colors.ts +56 -0
  243. package/src/components/WellPlate.conditions.ts +100 -0
  244. package/src/components/WellPlate.geometry.ts +91 -0
  245. package/src/components/WellPlate.interaction.ts +272 -0
  246. package/src/components/WellPlate.legend.ts +8 -0
  247. package/src/components/WellPlate.rendering.ts +105 -0
  248. package/src/components/WellPlate.sampleDrop.ts +73 -0
  249. package/src/components/WellPlate.vue +102 -550
  250. package/src/components/internal/PlateMapEditorToolbarInternal.vue +128 -0
  251. package/src/composables/autoGroup/classKey.ts +5 -0
  252. package/src/composables/autoGroup/classify.ts +205 -0
  253. package/src/composables/autoGroup/colors.ts +6 -0
  254. package/src/composables/autoGroup/columns.ts +226 -0
  255. package/src/composables/autoGroup/compose.ts +156 -0
  256. package/src/composables/autoGroup/cooccurrence.ts +46 -0
  257. package/src/composables/autoGroup/csv-shim.ts +44 -0
  258. package/src/composables/autoGroup/fingerprint.ts +49 -0
  259. package/src/composables/autoGroup/index.ts +20 -0
  260. package/src/composables/autoGroup/replicatePreGroup.ts +90 -0
  261. package/src/composables/autoGroup/template.ts +126 -0
  262. package/src/composables/autoGroup/tokenize.ts +41 -0
  263. package/src/composables/autoGroup/vocab.json +67 -0
  264. package/src/composables/autoGroupConstants.ts +4 -0
  265. package/src/composables/autoGroupGrouping.ts +148 -0
  266. package/src/composables/controlComponentBindings.ts +1 -1
  267. package/src/composables/controlSchemaAdapters.ts +1 -1
  268. package/src/composables/controlSchemaDoseDesign.ts +215 -0
  269. package/src/composables/controlSchemaFormFields.ts +1 -1
  270. package/src/composables/controlSchemaLayout.ts +1 -1
  271. package/src/composables/controlSchemaModel.ts +163 -0
  272. package/src/composables/controlSchemaNormalize.ts +1 -1
  273. package/src/composables/controlSchemaTypes.ts +364 -0
  274. package/src/composables/controlWorkspaceOptions.ts +1 -1
  275. package/src/composables/formBuilderSchema.ts +153 -0
  276. package/src/composables/pluginEndpointBuilder.ts +203 -0
  277. package/src/composables/protocolTemplateCatalog.ts +325 -0
  278. package/src/composables/useAutoGroup.ts +395 -549
  279. package/src/composables/useAutoGroupInputSources.ts +147 -0
  280. package/src/composables/useBioTemplateControls.ts +1 -1
  281. package/src/composables/useBioTemplatePresetWorkspace.ts +1 -1
  282. package/src/composables/useBioTemplateWorkspace.ts +1 -1
  283. package/src/composables/useControlSchema.ts +21 -692
  284. package/src/composables/useControlWorkspace.ts +7 -13
  285. package/src/composables/useForm.ts +5 -187
  286. package/src/composables/useFormBuilder.ts +11 -153
  287. package/src/composables/useFormValidation.ts +154 -0
  288. package/src/composables/usePluginClient.ts +10 -193
  289. package/src/composables/useProtocolTemplates.ts +10 -328
  290. package/src/composables/useScheduleCalendarLayout.ts +287 -0
  291. package/src/styles/components/auto-group-modal.css +248 -310
  292. package/src/templates/controlSchemaTypes.ts +1 -1
  293. package/src/templates/templateAdapterTypes.ts +58 -0
  294. package/src/templates/templateCreateOptions.ts +208 -0
  295. package/src/templates/templateQpcrTypes.ts +48 -0
  296. package/src/templates/types.ts +79 -275
  297. package/src/types/auto-group.ts +107 -9
  298. package/src/types/componentLabTypes.ts +235 -0
  299. package/src/types/componentWorkflowTypes.ts +190 -0
  300. package/src/types/components.ts +74 -424
  301. package/dist/components-DafPc4rM.js.map +0 -1
  302. package/dist/composables-BMkPQhVK.js.map +0 -1
  303. package/dist/templates-bUAWMn5L.js.map +0 -1
  304. package/dist/useProtocolTemplates-QZtHFFH2.js.map +0 -1
@@ -0,0 +1,164 @@
1
+ import { ref } from 'vue'
2
+ import type { SampleGroup } from '../types'
3
+ import {
4
+ detectSampleGroupSeparator,
5
+ getSampleGroupMajorPrefix,
6
+ moveSampleToGroup,
7
+ reorderSampleGroup,
8
+ reorderSampleMajorGroup,
9
+ type GroupDragKind,
10
+ type GroupReorderPosition,
11
+ } from './SampleSelector.groups'
12
+
13
+ interface MutableSampleGroups {
14
+ value: SampleGroup[]
15
+ }
16
+
17
+ export function useSampleSelectorDrag(groups: MutableSampleGroups) {
18
+ const draggingSample = ref<string | null>(null)
19
+ const dragSourceGroup = ref<string | null>(null)
20
+ const dragOverGroup = ref<string | null>(null)
21
+
22
+ const draggingGroup = ref<string | null>(null)
23
+ const draggingGroupKind = ref<GroupDragKind | null>(null)
24
+ const reorderTarget = ref<string | null>(null)
25
+ const reorderPosition = ref<GroupReorderPosition | null>(null)
26
+
27
+ function handleDragStart(sample: string, sourceGroup: string | null, event: DragEvent) {
28
+ draggingSample.value = sample
29
+ dragSourceGroup.value = sourceGroup
30
+ if (event.dataTransfer) {
31
+ event.dataTransfer.effectAllowed = 'move'
32
+ event.dataTransfer.setData('text/plain', sample)
33
+ }
34
+ }
35
+
36
+ function resetDragState() {
37
+ draggingSample.value = null
38
+ dragSourceGroup.value = null
39
+ dragOverGroup.value = null
40
+ }
41
+
42
+ function handleDragEnd() {
43
+ resetDragState()
44
+ }
45
+
46
+ function handleDragOver(groupName: string, event: DragEvent) {
47
+ // Only accept this drop target when a sample is being dragged; group drags are handled separately.
48
+ if (!draggingSample.value) return
49
+ event.preventDefault()
50
+ if (event.dataTransfer) {
51
+ event.dataTransfer.dropEffect = 'move'
52
+ }
53
+ dragOverGroup.value = groupName
54
+ }
55
+
56
+ function handleDragLeave() {
57
+ dragOverGroup.value = null
58
+ }
59
+
60
+ function handleDrop(targetGroupName: string, event: DragEvent) {
61
+ if (!draggingSample.value) return
62
+ event.preventDefault()
63
+
64
+ const sample = draggingSample.value
65
+ const sourceGroup = dragSourceGroup.value
66
+
67
+ if (sourceGroup === targetGroupName) {
68
+ resetDragState()
69
+ return
70
+ }
71
+
72
+ groups.value = moveSampleToGroup(groups.value, sample, sourceGroup, targetGroupName)
73
+ resetDragState()
74
+ }
75
+
76
+ function handleGroupDragStart(name: string, kind: GroupDragKind, event: DragEvent) {
77
+ draggingGroup.value = name
78
+ draggingGroupKind.value = kind
79
+ if (event.dataTransfer) {
80
+ event.dataTransfer.effectAllowed = 'move'
81
+ event.dataTransfer.setData('text/plain', `mint-group:${name}`)
82
+ }
83
+ }
84
+
85
+ function handleGroupDragEnd() {
86
+ draggingGroup.value = null
87
+ draggingGroupKind.value = null
88
+ reorderTarget.value = null
89
+ reorderPosition.value = null
90
+ }
91
+
92
+ function handleGroupDragOver(name: string, kind: GroupDragKind, event: DragEvent) {
93
+ if (!draggingGroup.value || draggingGroupKind.value !== kind) return
94
+ if (draggingGroup.value === name) return
95
+
96
+ // Sub-group reorder is restricted to siblings under the same major prefix;
97
+ // crossing majors would silently rename the group, which is too magical.
98
+ if (kind === 'sub') {
99
+ const separator = detectSampleGroupSeparator(groups.value)
100
+ if (
101
+ getSampleGroupMajorPrefix(draggingGroup.value, separator) !==
102
+ getSampleGroupMajorPrefix(name, separator)
103
+ ) return
104
+ }
105
+
106
+ event.preventDefault()
107
+ if (event.dataTransfer) event.dataTransfer.dropEffect = 'move'
108
+
109
+ const rect = (event.currentTarget as HTMLElement).getBoundingClientRect()
110
+ reorderTarget.value = name
111
+ reorderPosition.value = event.clientY < rect.top + rect.height / 2 ? 'before' : 'after'
112
+ }
113
+
114
+ function handleGroupDragLeave(event: DragEvent) {
115
+ const cur = event.currentTarget as HTMLElement
116
+ const rel = event.relatedTarget as Node | null
117
+ if (rel && cur.contains(rel)) return
118
+ reorderTarget.value = null
119
+ reorderPosition.value = null
120
+ }
121
+
122
+ function handleGroupDrop(name: string, kind: GroupDragKind, event: DragEvent) {
123
+ if (!draggingGroup.value || draggingGroupKind.value !== kind) {
124
+ handleGroupDragEnd()
125
+ return
126
+ }
127
+ const position = reorderPosition.value
128
+ if (!position || draggingGroup.value === name) {
129
+ handleGroupDragEnd()
130
+ return
131
+ }
132
+
133
+ event.preventDefault()
134
+
135
+ if (kind === 'major') {
136
+ const nextGroups = reorderSampleMajorGroup(groups.value, draggingGroup.value, name, position)
137
+ if (nextGroups !== groups.value) groups.value = nextGroups
138
+ } else {
139
+ const nextGroups = reorderSampleGroup(groups.value, draggingGroup.value, name, position)
140
+ if (nextGroups !== groups.value) groups.value = nextGroups
141
+ }
142
+
143
+ handleGroupDragEnd()
144
+ }
145
+
146
+ return {
147
+ draggingSample,
148
+ dragOverGroup,
149
+ draggingGroup,
150
+ draggingGroupKind,
151
+ reorderTarget,
152
+ reorderPosition,
153
+ handleDragStart,
154
+ handleDragEnd,
155
+ handleDragOver,
156
+ handleDragLeave,
157
+ handleDrop,
158
+ handleGroupDragStart,
159
+ handleGroupDragEnd,
160
+ handleGroupDragOver,
161
+ handleGroupDragLeave,
162
+ handleGroupDrop,
163
+ }
164
+ }
@@ -0,0 +1,109 @@
1
+ import type { SampleGroup } from '../types'
2
+
3
+ export type GroupDragKind = 'major' | 'sub' | 'flat'
4
+ export type GroupReorderPosition = 'before' | 'after'
5
+
6
+ export function detectSampleGroupSeparator(groups: SampleGroup[]): string {
7
+ return groups.some(group => group.name.includes('/')) ? '/' : '_'
8
+ }
9
+
10
+ export function getSampleGroupMajorPrefix(groupName: string, separator: string): string {
11
+ const parts = groupName.split(separator)
12
+ return parts.length > 1 ? parts[0] : groupName
13
+ }
14
+
15
+ export function moveSampleToGroup(
16
+ groups: SampleGroup[],
17
+ sample: string,
18
+ sourceGroup: string | null,
19
+ targetGroup: string,
20
+ ): SampleGroup[] {
21
+ if (sourceGroup === targetGroup) return groups
22
+
23
+ return groups.map(group => {
24
+ if (sourceGroup && group.name === sourceGroup) {
25
+ return { ...group, samples: group.samples.filter(item => item !== sample) }
26
+ }
27
+ if (group.name === targetGroup && !group.samples.includes(sample)) {
28
+ return { ...group, samples: [...group.samples, sample] }
29
+ }
30
+ return group
31
+ })
32
+ }
33
+
34
+ export function removeSampleGroup(groups: SampleGroup[], groupName: string): SampleGroup[] {
35
+ return groups.filter(group => group.name !== groupName)
36
+ }
37
+
38
+ export function removeSampleMajorGroup(
39
+ groups: SampleGroup[],
40
+ majorGroup: { subGroups: Array<{ name: string }> },
41
+ ): SampleGroup[] {
42
+ const groupNames = new Set(majorGroup.subGroups.map(group => group.name))
43
+ return groups.filter(group => !groupNames.has(group.name))
44
+ }
45
+
46
+ export function removeSampleFromGroup(
47
+ groups: SampleGroup[],
48
+ sample: string,
49
+ groupName: string,
50
+ ): SampleGroup[] {
51
+ return groups.map(group =>
52
+ group.name === groupName
53
+ ? { ...group, samples: group.samples.filter(item => item !== sample) }
54
+ : group,
55
+ )
56
+ }
57
+
58
+ export function reorderSampleGroup(
59
+ groups: SampleGroup[],
60
+ source: string,
61
+ target: string,
62
+ position: GroupReorderPosition,
63
+ ): SampleGroup[] {
64
+ if (source === target) return groups
65
+
66
+ const nextGroups = [...groups]
67
+ const sourceIndex = nextGroups.findIndex(group => group.name === source)
68
+ if (sourceIndex === -1) return groups
69
+
70
+ const [item] = nextGroups.splice(sourceIndex, 1)
71
+ const targetIndex = nextGroups.findIndex(group => group.name === target)
72
+ if (targetIndex === -1) return groups
73
+
74
+ nextGroups.splice(position === 'before' ? targetIndex : targetIndex + 1, 0, item)
75
+ return nextGroups
76
+ }
77
+
78
+ export function reorderSampleMajorGroup(
79
+ groups: SampleGroup[],
80
+ source: string,
81
+ target: string,
82
+ position: GroupReorderPosition,
83
+ ): SampleGroup[] {
84
+ if (source === target) return groups
85
+
86
+ const separator = detectSampleGroupSeparator(groups)
87
+ const isSource = (group: SampleGroup) => getSampleGroupMajorPrefix(group.name, separator) === source
88
+ const isTarget = (group: SampleGroup) => getSampleGroupMajorPrefix(group.name, separator) === target
89
+
90
+ const sourceGroups = groups.filter(isSource)
91
+ if (sourceGroups.length === 0) return groups
92
+
93
+ const remainingGroups = groups.filter(group => !isSource(group))
94
+ let firstTargetIndex = -1
95
+ let lastTargetIndex = -1
96
+
97
+ remainingGroups.forEach((group, index) => {
98
+ if (isTarget(group)) {
99
+ if (firstTargetIndex === -1) firstTargetIndex = index
100
+ lastTargetIndex = index
101
+ }
102
+ })
103
+
104
+ if (firstTargetIndex === -1) return groups
105
+
106
+ const insertIndex = position === 'before' ? firstTargetIndex : lastTargetIndex + 1
107
+ remainingGroups.splice(insertIndex, 0, ...sourceGroups)
108
+ return remainingGroups
109
+ }
@@ -0,0 +1,103 @@
1
+ import type { ComputedRef } from 'vue'
2
+ import { useListSelection } from '../composables/useListSelection'
3
+ import type { SampleMajorGroup } from '../composables/useSampleGroups'
4
+
5
+ interface SampleGroupSelectionSource {
6
+ samples: string[]
7
+ }
8
+
9
+ export interface UseSampleSelectorSelectionOptions {
10
+ selected: () => string[]
11
+ samples: () => string[]
12
+ findGroup: (groupName: string) => SampleGroupSelectionSource | undefined
13
+ emitSelected: (samples: string[]) => void
14
+ }
15
+
16
+ export interface UseSampleSelectorSelectionReturn {
17
+ isAllSelected: ComputedRef<boolean>
18
+ toggleSelectAll: () => void
19
+ toggleSample: (sample: string) => void
20
+ toggleGroupSamples: (groupName: string) => void
21
+ toggleMajorGroupSamples: (majorGroup: SampleMajorGroup) => void
22
+ isFullySelected: (samples: string[]) => boolean
23
+ isPartiallySelected: (samples: string[]) => boolean
24
+ isGroupFullySelected: (groupName: string) => boolean
25
+ isGroupPartiallySelected: (groupName: string) => boolean
26
+ isMajorGroupFullySelected: (majorGroup: SampleMajorGroup) => boolean
27
+ isMajorGroupPartiallySelected: (majorGroup: SampleMajorGroup) => boolean
28
+ }
29
+
30
+ export function useSampleSelectorSelection(
31
+ options: UseSampleSelectorSelectionOptions,
32
+ ): UseSampleSelectorSelectionReturn {
33
+ const sampleSelection = useListSelection({
34
+ selected: options.selected,
35
+ items: options.samples,
36
+ })
37
+
38
+ function emitSelection(samples: string[]) {
39
+ options.emitSelected(samples)
40
+ }
41
+
42
+ function toggleSelectAll() {
43
+ emitSelection(sampleSelection.toggleAll())
44
+ }
45
+
46
+ function toggleSample(sample: string) {
47
+ emitSelection(sampleSelection.toggleValue(sample))
48
+ }
49
+
50
+ function toggleSamplesSelection(samples: string[]) {
51
+ emitSelection(sampleSelection.toggleValues(samples))
52
+ }
53
+
54
+ function toggleGroupSamples(groupName: string) {
55
+ const group = options.findGroup(groupName)
56
+ if (!group) return
57
+ toggleSamplesSelection(group.samples)
58
+ }
59
+
60
+ function toggleMajorGroupSamples(majorGroup: SampleMajorGroup) {
61
+ toggleSamplesSelection(majorGroup.allSamples)
62
+ }
63
+
64
+ function isFullySelected(samples: string[]): boolean {
65
+ return sampleSelection.isFullySelected(samples)
66
+ }
67
+
68
+ function isPartiallySelected(samples: string[]): boolean {
69
+ return sampleSelection.isPartiallySelected(samples)
70
+ }
71
+
72
+ function isGroupFullySelected(groupName: string): boolean {
73
+ const group = options.findGroup(groupName)
74
+ return group ? isFullySelected(group.samples) : false
75
+ }
76
+
77
+ function isGroupPartiallySelected(groupName: string): boolean {
78
+ const group = options.findGroup(groupName)
79
+ return group ? isPartiallySelected(group.samples) : false
80
+ }
81
+
82
+ function isMajorGroupFullySelected(majorGroup: SampleMajorGroup): boolean {
83
+ return isFullySelected(majorGroup.allSamples)
84
+ }
85
+
86
+ function isMajorGroupPartiallySelected(majorGroup: SampleMajorGroup): boolean {
87
+ return isPartiallySelected(majorGroup.allSamples)
88
+ }
89
+
90
+ return {
91
+ isAllSelected: sampleSelection.isAllSelected,
92
+ toggleSelectAll,
93
+ toggleSample,
94
+ toggleGroupSamples,
95
+ toggleMajorGroupSamples,
96
+ isFullySelected,
97
+ isPartiallySelected,
98
+ isGroupFullySelected,
99
+ isGroupPartiallySelected,
100
+ isMajorGroupFullySelected,
101
+ isMajorGroupPartiallySelected,
102
+ }
103
+ }