@morscherlab/mint-sdk 1.0.0-beta.3 → 1.0.0-beta.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 (181) hide show
  1. package/README.md +9 -2
  2. package/dist/__tests__/composables/experiment-utils.test.d.ts +1 -0
  3. package/dist/__tests__/composables/useApi.test.d.ts +1 -0
  4. package/dist/components/AppContainer.vue.d.ts +1 -1
  5. package/dist/components/AppLayout.vue.d.ts +20 -1
  6. package/dist/components/AppSidebar.vue.d.ts +57 -5
  7. package/dist/components/AppTopBar.vue.d.ts +7 -25
  8. package/dist/components/BioTemplateExperimentWorkspaceView.vue.d.ts +3 -1
  9. package/dist/components/BioTemplatePackWorkspaceView.vue.d.ts +1 -0
  10. package/dist/components/BioTemplatePresetWorkspaceView.vue.d.ts +5 -0
  11. package/dist/components/ComponentBindingRenderer.vue.d.ts +44 -0
  12. package/dist/components/ControlWorkspaceView.vue.d.ts +24 -7
  13. package/dist/components/DoseDesignWorkspaceView.vue.d.ts +149 -0
  14. package/dist/components/ExperimentTimeline.vue.d.ts +1 -1
  15. package/dist/components/FormBuilder.vue.d.ts +9 -9
  16. package/dist/components/PlateMapEditor.vue.d.ts +1 -1
  17. package/dist/components/PluginWorkspaceView.vue.d.ts +310 -0
  18. package/dist/components/SettingsModal.vue.d.ts +1 -1
  19. package/dist/components/WellPlate.vue.d.ts +2 -2
  20. package/dist/components/index.d.ts +3 -12
  21. package/dist/components/index.js +3 -3
  22. package/dist/components/{AppPageSelector.vue.d.ts → internal/AppTopBarPageSelectorInternal.vue.d.ts} +1 -1
  23. package/dist/components/{AppPillNav.vue.d.ts → internal/AppTopBarPillNavInternal.vue.d.ts} +3 -1
  24. package/dist/components/{CalendarGridPanel.vue.d.ts → internal/CalendarGridPanelInternal.vue.d.ts} +1 -1
  25. package/dist/components/internal/FormSectionRenderer.vue.d.ts +4 -4
  26. package/dist/components/{WellEditPopup.vue.d.ts → internal/WellEditPopupInternal.vue.d.ts} +1 -1
  27. package/dist/{components-D_Sr0adg.js → components-DihbSJjU.js} +5932 -5408
  28. package/dist/components-DihbSJjU.js.map +1 -0
  29. package/dist/composables/experiment-utils.d.ts +8 -0
  30. package/dist/composables/index.d.ts +5 -7
  31. package/dist/composables/index.js +4 -4
  32. package/dist/composables/useAppExperiment.d.ts +31 -2
  33. package/dist/composables/useBioTemplateComponents.d.ts +5 -3
  34. package/dist/composables/useBioTemplatePackWorkspace.d.ts +3 -2
  35. package/dist/composables/useBioTemplatePresetWorkspace.d.ts +6 -5
  36. package/dist/composables/useBioTemplateWorkspace.d.ts +5 -4
  37. package/dist/composables/useControlSchema.d.ts +43 -21
  38. package/dist/composables/usePluginClient.d.ts +5 -2
  39. package/dist/{composables-C3dpXQN5.js → composables-BcgZ6diz.js} +40 -28
  40. package/dist/composables-BcgZ6diz.js.map +1 -0
  41. package/dist/index.d.ts +5 -12
  42. package/dist/index.js +5 -5
  43. package/dist/install.js +2 -2
  44. package/dist/styles.css +5637 -5663
  45. package/dist/templates/adapters.d.ts +7 -1
  46. package/dist/templates/catalog.d.ts +5 -5
  47. package/dist/templates/componentBindings.d.ts +13 -0
  48. package/dist/templates/index.d.ts +5 -5
  49. package/dist/templates/index.js +2 -2
  50. package/dist/templates/presets.d.ts +4 -4
  51. package/dist/templates/types.d.ts +4 -1
  52. package/dist/{templates-50NPjaxL.js → templates-Cyt0Suwf.js} +322 -73
  53. package/dist/templates-Cyt0Suwf.js.map +1 -0
  54. package/dist/types/components.d.ts +6 -25
  55. package/dist/types/index.d.ts +1 -1
  56. package/dist/{useScheduleDrag-D4oWdh41.js → useExperimentData-CM6Y0u5L.js} +400 -357
  57. package/dist/useExperimentData-CM6Y0u5L.js.map +1 -0
  58. package/package.json +1 -1
  59. package/src/__tests__/components/ActionItem.test.ts +6 -6
  60. package/src/__tests__/components/AppLayout.test.ts +44 -0
  61. package/src/__tests__/components/AppSidebar.test.ts +130 -2
  62. package/src/__tests__/components/AppToastContainer.test.ts +0 -11
  63. package/src/__tests__/components/AppTopBar.test.ts +189 -120
  64. package/src/__tests__/components/{AppPageSelector.test.ts → AppTopBarPageSelector.test.ts} +8 -8
  65. package/src/__tests__/components/{AppPillNav.test.ts → AppTopBarPillNav.test.ts} +53 -6
  66. package/src/__tests__/components/BioTemplateExperimentWorkspaceView.test.ts +7 -1
  67. package/src/__tests__/components/BioTemplatePackWorkspaceView.test.ts +32 -1
  68. package/src/__tests__/components/BioTemplatePresetWorkspaceView.test.ts +48 -1
  69. package/src/__tests__/components/BioTemplateRenderer.test.ts +25 -0
  70. package/src/__tests__/components/CalendarGridPanel.test.ts +3 -3
  71. package/src/__tests__/components/ComponentBindingRenderer.test.ts +278 -0
  72. package/src/__tests__/components/ControlWorkspaceView.test.ts +134 -63
  73. package/src/__tests__/components/DateTimePicker.test.ts +2 -2
  74. package/src/__tests__/components/DoseDesignWorkspaceView.test.ts +185 -0
  75. package/src/__tests__/components/PluginWorkspaceView.test.ts +548 -0
  76. package/src/__tests__/composables/experiment-utils.test.ts +30 -0
  77. package/src/__tests__/composables/useApi.test.ts +30 -0
  78. package/src/__tests__/composables/useAppExperiment.test.ts +100 -1
  79. package/src/__tests__/composables/useBioTemplatePackWorkspace.test.ts +7 -4
  80. package/src/__tests__/composables/useBioTemplatePresetWorkspace.test.ts +7 -7
  81. package/src/__tests__/composables/useBioTemplateWorkspace.test.ts +6 -1
  82. package/src/__tests__/composables/useControlSchema.test.ts +151 -37
  83. package/src/__tests__/composables/usePluginClient.test.ts +99 -2
  84. package/src/__tests__/docs/frontendDocsCatalog.test.ts +120 -25
  85. package/src/__tests__/templates/templates.test.ts +56 -0
  86. package/src/components/AppAvatarMenu.vue +3 -3
  87. package/src/components/AppLayout.story.vue +39 -0
  88. package/src/components/AppLayout.vue +83 -2
  89. package/src/components/AppPluginSwitcher.vue +5 -5
  90. package/src/components/AppSidebar.story.vue +113 -5
  91. package/src/components/AppSidebar.vue +147 -27
  92. package/src/components/AppTopBar.story.vue +2 -5
  93. package/src/components/AppTopBar.vue +35 -425
  94. package/src/components/BioTemplateExperimentWorkspaceView.story.vue +2 -2
  95. package/src/components/BioTemplateExperimentWorkspaceView.vue +6 -0
  96. package/src/components/BioTemplatePackWorkspaceView.story.vue +4 -4
  97. package/src/components/BioTemplatePackWorkspaceView.vue +1 -0
  98. package/src/components/BioTemplatePresetWorkspaceView.story.vue +14 -2
  99. package/src/components/BioTemplatePresetWorkspaceView.vue +12 -3
  100. package/src/components/BioTemplateRenderer.story.vue +2 -2
  101. package/src/components/BioTemplateRenderer.vue +15 -227
  102. package/src/components/ComponentBindingRenderer.story.vue +87 -0
  103. package/src/components/ComponentBindingRenderer.vue +317 -0
  104. package/src/components/ControlWorkspaceView.story.vue +20 -9
  105. package/src/components/ControlWorkspaceView.vue +43 -12
  106. package/src/components/DatePicker.vue +2 -2
  107. package/src/components/DateTimePicker.vue +2 -2
  108. package/src/components/DoseDesignWorkspaceView.story.vue +77 -0
  109. package/src/components/DoseDesignWorkspaceView.vue +255 -0
  110. package/src/components/ExperimentPopover.story.vue +2 -2
  111. package/src/components/ExperimentPopover.vue +2 -6
  112. package/src/components/ExperimentSelectorModal.vue +6 -5
  113. package/src/components/FormBuilder.story.vue +190 -0
  114. package/src/components/PluginWorkspaceView.story.vue +334 -0
  115. package/src/components/PluginWorkspaceView.vue +708 -0
  116. package/src/components/SettingsModal.story.vue +87 -0
  117. package/src/components/WellPlate.vue +2 -2
  118. package/src/components/index.ts +3 -12
  119. package/src/components/{AppPageSelector.vue → internal/AppTopBarPageSelectorInternal.vue} +9 -9
  120. package/src/components/internal/AppTopBarPillNavInternal.vue +194 -0
  121. package/src/components/{CalendarGridPanel.vue → internal/CalendarGridPanelInternal.vue} +1 -1
  122. package/src/components/{WellEditPopup.vue → internal/WellEditPopupInternal.vue} +3 -3
  123. package/src/composables/experiment-utils.ts +26 -0
  124. package/src/composables/index.ts +21 -7
  125. package/src/composables/useApi.ts +9 -2
  126. package/src/composables/useAppExperiment.ts +85 -13
  127. package/src/composables/useBioTemplateComponents.ts +12 -0
  128. package/src/composables/useBioTemplatePackWorkspace.ts +6 -2
  129. package/src/composables/useBioTemplatePresetWorkspace.ts +10 -21
  130. package/src/composables/useBioTemplateWorkspace.ts +6 -4
  131. package/src/composables/useControlSchema.ts +157 -69
  132. package/src/composables/usePluginClient.ts +50 -9
  133. package/src/index.ts +6 -563
  134. package/src/styles/components/app-layout.css +82 -0
  135. package/src/styles/components/app-page-selector.css +1 -1
  136. package/src/styles/components/app-pill-nav.css +71 -1
  137. package/src/styles/components/app-sidebar.css +119 -0
  138. package/src/styles/components/app-top-bar.css +0 -235
  139. package/src/styles/components/experiment-popover.css +2 -2
  140. package/src/styles/index.css +0 -1
  141. package/src/templates/adapters.ts +193 -0
  142. package/src/templates/catalog.ts +5 -5
  143. package/src/templates/componentBindings.ts +90 -3
  144. package/src/templates/index.ts +10 -0
  145. package/src/templates/packs.ts +10 -1
  146. package/src/templates/presets.ts +14 -4
  147. package/src/templates/types.ts +4 -0
  148. package/src/types/components.ts +6 -31
  149. package/src/types/index.ts +2 -6
  150. package/dist/__tests__/composables/usePluginApi.test.d.ts +0 -13
  151. package/dist/components/FormFieldRenderer.vue.d.ts +0 -28
  152. package/dist/components/FormSection.vue.d.ts +0 -30
  153. package/dist/components/GroupingModal.vue.d.ts +0 -12
  154. package/dist/components/SettingsButton.vue.d.ts +0 -30
  155. package/dist/components/ToastNotification.vue.d.ts +0 -2
  156. package/dist/components-D_Sr0adg.js.map +0 -1
  157. package/dist/composables/usePluginApi.d.ts +0 -22
  158. package/dist/composables-C3dpXQN5.js.map +0 -1
  159. package/dist/templates-50NPjaxL.js.map +0 -1
  160. package/dist/useScheduleDrag-D4oWdh41.js.map +0 -1
  161. package/src/__tests__/components/FormCompatibility.test.ts +0 -94
  162. package/src/__tests__/components/GroupingModal.test.ts +0 -73
  163. package/src/__tests__/components/SettingsButton.test.ts +0 -44
  164. package/src/__tests__/composables/usePluginApi.test.ts +0 -81
  165. package/src/components/AppPillNav.vue +0 -71
  166. package/src/components/FormFieldRenderer.vue +0 -35
  167. package/src/components/FormSection.vue +0 -37
  168. package/src/components/GroupingModal.story.vue +0 -52
  169. package/src/components/GroupingModal.vue +0 -61
  170. package/src/components/SettingsButton.story.vue +0 -58
  171. package/src/components/SettingsButton.vue +0 -64
  172. package/src/components/ToastNotification.vue +0 -9
  173. package/src/composables/usePluginApi.ts +0 -32
  174. package/src/styles/components/settings-button.css +0 -31
  175. /package/dist/__tests__/components/{AppPageSelector.test.d.ts → AppTopBarPageSelector.test.d.ts} +0 -0
  176. /package/dist/__tests__/components/{AppPillNav.test.d.ts → AppTopBarPillNav.test.d.ts} +0 -0
  177. /package/dist/__tests__/components/{FormCompatibility.test.d.ts → ComponentBindingRenderer.test.d.ts} +0 -0
  178. /package/dist/__tests__/components/{GroupingModal.test.d.ts → DoseDesignWorkspaceView.test.d.ts} +0 -0
  179. /package/dist/__tests__/components/{SettingsButton.test.d.ts → PluginWorkspaceView.test.d.ts} +0 -0
  180. /package/dist/components/{ActionItem.vue.d.ts → internal/ActionItemInternal.vue.d.ts} +0 -0
  181. /package/src/components/{ActionItem.vue → internal/ActionItemInternal.vue} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@morscherlab/mint-sdk",
3
- "version": "1.0.0-beta.3",
3
+ "version": "1.0.0-beta.5",
4
4
  "description": "MINT Platform SDK — Vue 3 components, composables, and types for plugin development. MINT = Mass-spec INtegrated Toolkit.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,7 +1,7 @@
1
1
  import { mount } from '@vue/test-utils'
2
2
  import { defineComponent, h } from 'vue'
3
3
  import { describe, expect, it, vi } from 'vitest'
4
- import ActionItem from '../../components/ActionItem.vue'
4
+ import ActionItemInternal from '../../components/internal/ActionItemInternal.vue'
5
5
 
6
6
  function createRouterLinkStub(navigate = vi.fn()) {
7
7
  return defineComponent({
@@ -18,9 +18,9 @@ function createRouterLinkStub(navigate = vi.fn()) {
18
18
  })
19
19
  }
20
20
 
21
- describe('ActionItem', () => {
21
+ describe('ActionItemInternal', () => {
22
22
  it('renders a normal button action and emits clicks', async () => {
23
- const wrapper = mount(ActionItem, {
23
+ const wrapper = mount(ActionItemInternal, {
24
24
  slots: { default: 'Run' },
25
25
  })
26
26
 
@@ -33,7 +33,7 @@ describe('ActionItem', () => {
33
33
  })
34
34
 
35
35
  it('renders disabled href actions without navigating or emitting', async () => {
36
- const wrapper = mount(ActionItem, {
36
+ const wrapper = mount(ActionItemInternal, {
37
37
  props: {
38
38
  href: '/disabled',
39
39
  disabled: true,
@@ -52,7 +52,7 @@ describe('ActionItem', () => {
52
52
 
53
53
  it('renders router actions through router-link and navigates after emitting', async () => {
54
54
  const navigate = vi.fn()
55
- const wrapper = mount(ActionItem, {
55
+ const wrapper = mount(ActionItemInternal, {
56
56
  props: { to: '/settings' },
57
57
  slots: { default: 'Settings' },
58
58
  global: {
@@ -73,7 +73,7 @@ describe('ActionItem', () => {
73
73
 
74
74
  it('renders disabled router actions without href, navigation, or emitted clicks', async () => {
75
75
  const navigate = vi.fn()
76
- const wrapper = mount(ActionItem, {
76
+ const wrapper = mount(ActionItemInternal, {
77
77
  props: {
78
78
  to: '/settings',
79
79
  disabled: true,
@@ -124,6 +124,50 @@ describe('AppLayout', () => {
124
124
  })
125
125
  })
126
126
 
127
+ describe('responsive sidebar shell', () => {
128
+ it('does not render mobile toggle by default', () => {
129
+ const wrapper = mount(AppLayout, {
130
+ slots: { sidebar: '<div>Sidebar</div>' },
131
+ })
132
+
133
+ expect(wrapper.find('.mint-layout__sidebar-toggle').exists()).toBe(false)
134
+ expect(wrapper.find('.mint-layout--responsive-sidebar').exists()).toBe(false)
135
+ })
136
+
137
+ it('renders a mobile toggle when responsiveSidebar is enabled', async () => {
138
+ const wrapper = mount(AppLayout, {
139
+ props: { responsiveSidebar: true },
140
+ slots: { sidebar: '<div>Sidebar</div>' },
141
+ })
142
+
143
+ const toggle = wrapper.get('.mint-layout__sidebar-toggle')
144
+ expect(toggle.attributes('aria-expanded')).toBe('false')
145
+ expect(wrapper.find('.mint-layout__sidebar-backdrop').exists()).toBe(false)
146
+
147
+ await toggle.trigger('click')
148
+
149
+ expect(wrapper.find('.mint-layout--sidebar-open').exists()).toBe(true)
150
+ expect(wrapper.get('.mint-layout__sidebar-toggle').attributes('aria-expanded')).toBe('true')
151
+ expect(wrapper.find('.mint-layout__sidebar-backdrop').exists()).toBe(true)
152
+ expect(wrapper.emitted('update:sidebarOpen')).toEqual([[true]])
153
+ })
154
+
155
+ it('supports controlled mobile sidebar open state and closes from backdrop', async () => {
156
+ const wrapper = mount(AppLayout, {
157
+ props: {
158
+ responsiveSidebar: true,
159
+ sidebarOpen: true,
160
+ },
161
+ slots: { sidebar: '<div>Sidebar</div>' },
162
+ })
163
+
164
+ expect(wrapper.find('.mint-layout--sidebar-open').exists()).toBe(true)
165
+ await wrapper.get('.mint-layout__sidebar-backdrop').trigger('click')
166
+
167
+ expect(wrapper.emitted('update:sidebarOpen')).toEqual([[false]])
168
+ })
169
+ })
170
+
127
171
  describe('integration: all slots', () => {
128
172
  it('should render topbar, sidebar, and main content together', () => {
129
173
  const wrapper = mount(AppLayout, {
@@ -145,6 +145,120 @@ describe('AppSidebar', () => {
145
145
  })
146
146
  })
147
147
 
148
+ describe('sidebar chrome and collapse state', () => {
149
+ it('applies analysis variant defaults for common plugin sidebars', () => {
150
+ const wrapper = mount(AppSidebar, {
151
+ props: {
152
+ panels: samplePanels,
153
+ activeView: 'analysis',
154
+ variant: 'analysis',
155
+ title: 'Peak Picking',
156
+ },
157
+ })
158
+
159
+ expect(wrapper.find('.mint-sidebar--analysis').exists()).toBe(true)
160
+ expect(wrapper.find('.mint-sidebar--static').exists()).toBe(true)
161
+ expect(wrapper.find('.mint-sidebar--floating').exists()).toBe(false)
162
+ expect(wrapper.find('.mint-sidebar').attributes('style')).toContain('width: 20rem')
163
+ expect(wrapper.find('.mint-sidebar__collapse-button').exists()).toBe(true)
164
+ })
165
+
166
+ it('lets explicit props override analysis variant defaults', () => {
167
+ const wrapper = mount(AppSidebar, {
168
+ props: {
169
+ panels: samplePanels,
170
+ activeView: 'analysis',
171
+ variant: 'analysis',
172
+ floating: true,
173
+ width: '18rem',
174
+ collapsible: false,
175
+ },
176
+ })
177
+
178
+ expect(wrapper.find('.mint-sidebar--analysis').exists()).toBe(true)
179
+ expect(wrapper.find('.mint-sidebar--floating').exists()).toBe(true)
180
+ expect(wrapper.find('.mint-sidebar').attributes('style')).toContain('width: 18rem')
181
+ expect(wrapper.find('.mint-sidebar__collapse-button').exists()).toBe(false)
182
+ })
183
+
184
+ it('renders title, subtitle, and badge in the built-in header', () => {
185
+ const wrapper = mount(AppSidebar, {
186
+ props: {
187
+ panels: samplePanels,
188
+ activeView: 'analysis',
189
+ title: 'Peak Picking',
190
+ subtitle: 'run-001.msd',
191
+ badge: 3,
192
+ },
193
+ })
194
+
195
+ expect(wrapper.find('.mint-sidebar__title').text()).toBe('Peak Picking')
196
+ expect(wrapper.find('.mint-sidebar__subtitle').text()).toBe('run-001.msd')
197
+ expect(wrapper.find('.mint-sidebar__badge').text()).toBe('3')
198
+ })
199
+
200
+ it('toggles uncontrolled collapsed state and emits the update', async () => {
201
+ const wrapper = mount(AppSidebar, {
202
+ props: {
203
+ panels: samplePanels,
204
+ activeView: 'analysis',
205
+ title: 'Peak Picking',
206
+ collapsible: true,
207
+ width: '18rem',
208
+ collapsedWidth: '3rem',
209
+ },
210
+ })
211
+
212
+ expect(wrapper.find('.mint-sidebar').attributes('style')).toContain('width: 18rem')
213
+ expect(wrapper.findAllComponents(CollapsibleCard)).toHaveLength(2)
214
+
215
+ await wrapper.get('.mint-sidebar__collapse-button').trigger('click')
216
+
217
+ expect(wrapper.find('.mint-sidebar--collapsed').exists()).toBe(true)
218
+ expect(wrapper.find('.mint-sidebar').attributes('style')).toContain('width: 3rem')
219
+ expect(wrapper.findAllComponents(CollapsibleCard)).toHaveLength(0)
220
+ expect(wrapper.emitted('update:collapsed')).toEqual([[true]])
221
+ })
222
+
223
+ it('supports controlled collapsed state and a collapsed slot', () => {
224
+ const wrapper = mount(AppSidebar, {
225
+ props: {
226
+ panels: samplePanels,
227
+ activeView: 'analysis',
228
+ collapsible: true,
229
+ collapsed: true,
230
+ },
231
+ slots: {
232
+ collapsed: '<button class="collapsed-action">2</button>',
233
+ },
234
+ })
235
+
236
+ expect(wrapper.find('.mint-sidebar--collapsed').exists()).toBe(true)
237
+ expect(wrapper.find('.collapsed-action').text()).toBe('2')
238
+ expect(wrapper.findAllComponents(CollapsibleCard)).toHaveLength(0)
239
+ })
240
+
241
+ it('renders an empty analysis shell for route-owned sidebar content', () => {
242
+ const wrapper = mount(AppSidebar, {
243
+ props: {
244
+ variant: 'analysis',
245
+ title: 'Sequence',
246
+ contentId: 'seqgen-sidebar',
247
+ showWhenEmpty: true,
248
+ },
249
+ slots: {
250
+ footer: '<button class="generate-action">Generate</button>',
251
+ },
252
+ })
253
+
254
+ expect(wrapper.find('.mint-sidebar--hidden').exists()).toBe(false)
255
+ expect(wrapper.find('.mint-sidebar--analysis').exists()).toBe(true)
256
+ expect(wrapper.find('.mint-sidebar__sections').attributes('id')).toBe('seqgen-sidebar')
257
+ expect(wrapper.findAllComponents(CollapsibleCard)).toHaveLength(0)
258
+ expect(wrapper.find('.generate-action').exists()).toBe(true)
259
+ })
260
+ })
261
+
148
262
  describe('panels and activeView', () => {
149
263
  it('should render sections for active view', () => {
150
264
  const wrapper = mount(AppSidebar, {
@@ -569,6 +683,18 @@ describe('AppSidebar', () => {
569
683
  })
570
684
 
571
685
  describe('slots', () => {
686
+ it('renders the default slot as sidebar content without panels', () => {
687
+ const wrapper = mount(AppSidebar, {
688
+ props: { variant: 'analysis' },
689
+ slots: {
690
+ default: '<div class="route-sidebar-content">Route controls</div>',
691
+ },
692
+ })
693
+
694
+ expect(wrapper.find('.mint-sidebar--hidden').exists()).toBe(false)
695
+ expect(wrapper.find('.route-sidebar-content').text()).toBe('Route controls')
696
+ })
697
+
572
698
  it('should render header slot', () => {
573
699
  const wrapper = mount(AppSidebar, {
574
700
  props: { panels: samplePanels, activeView: 'analysis' },
@@ -621,11 +747,13 @@ describe('AppSidebar', () => {
621
747
  expect(wrapper.find('.mint-sidebar--hidden').exists()).toBe(true)
622
748
  })
623
749
 
624
- it('should handle undefined activeView', () => {
750
+ it('uses the first non-empty panel view when activeView is omitted', () => {
625
751
  const wrapper = mount(AppSidebar, {
626
752
  props: { panels: samplePanels },
627
753
  })
628
- expect(wrapper.find('.mint-sidebar--hidden').exists()).toBe(true)
754
+ expect(wrapper.find('.mint-sidebar--hidden').exists()).toBe(false)
755
+ expect(wrapper.findAllComponents(CollapsibleCard)).toHaveLength(2)
756
+ expect(wrapper.find('.mint-sidebar__sections').exists()).toBe(true)
629
757
  })
630
758
  })
631
759
 
@@ -2,7 +2,6 @@ import { mount } from '@vue/test-utils'
2
2
  import { afterEach, describe, expect, it } from 'vitest'
3
3
  import { nextTick } from 'vue'
4
4
  import AppToastContainer from '../../components/AppToastContainer.vue'
5
- import ToastNotification from '../../components/ToastNotification.vue'
6
5
  import { useToast } from '../../composables/useToast'
7
6
 
8
7
  describe('AppToastContainer', () => {
@@ -35,14 +34,4 @@ describe('AppToastContainer', () => {
35
34
 
36
35
  expect(toast.toasts.value).toHaveLength(0)
37
36
  })
38
-
39
- it('keeps ToastNotification as a compatibility wrapper', async () => {
40
- const wrapper = mountContainer(ToastNotification)
41
-
42
- toast.info('Legacy import still works', 10000)
43
- await nextTick()
44
-
45
- expect(wrapper.findComponent(AppToastContainer).exists()).toBe(true)
46
- expect(wrapper.find('.mint-toast__message').text()).toBe('Legacy import still works')
47
- })
48
37
  })