@morscherlab/mint-sdk 1.0.0-beta.3 → 1.0.0-beta.4
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.
- package/README.md +9 -2
- package/dist/__tests__/composables/experiment-utils.test.d.ts +1 -0
- package/dist/__tests__/composables/useApi.test.d.ts +1 -0
- package/dist/components/AppContainer.vue.d.ts +1 -1
- package/dist/components/AppLayout.vue.d.ts +20 -1
- package/dist/components/AppSidebar.vue.d.ts +56 -4
- package/dist/components/AppTopBar.vue.d.ts +7 -25
- package/dist/components/BioTemplateExperimentWorkspaceView.vue.d.ts +3 -1
- package/dist/components/BioTemplatePackWorkspaceView.vue.d.ts +1 -0
- package/dist/components/BioTemplatePresetWorkspaceView.vue.d.ts +5 -0
- package/dist/components/ComponentBindingRenderer.vue.d.ts +44 -0
- package/dist/components/ControlWorkspaceView.vue.d.ts +24 -7
- package/dist/components/DoseDesignWorkspaceView.vue.d.ts +149 -0
- package/dist/components/ExperimentTimeline.vue.d.ts +1 -1
- package/dist/components/FormBuilder.vue.d.ts +9 -9
- package/dist/components/PlateMapEditor.vue.d.ts +1 -1
- package/dist/components/PluginWorkspaceView.vue.d.ts +310 -0
- package/dist/components/SettingsModal.vue.d.ts +1 -1
- package/dist/components/WellPlate.vue.d.ts +2 -2
- package/dist/components/index.d.ts +3 -12
- package/dist/components/index.js +3 -3
- package/dist/components/{AppPageSelector.vue.d.ts → internal/AppPageSelectorInternal.vue.d.ts} +1 -1
- package/dist/components/{AppPillNav.vue.d.ts → internal/AppPillNavInternal.vue.d.ts} +3 -1
- package/dist/components/{CalendarGridPanel.vue.d.ts → internal/CalendarGridPanelInternal.vue.d.ts} +1 -1
- package/dist/components/internal/FormSectionRenderer.vue.d.ts +4 -4
- package/dist/components/{WellEditPopup.vue.d.ts → internal/WellEditPopupInternal.vue.d.ts} +1 -1
- package/dist/{components-D_Sr0adg.js → components-BkGF4B4y.js} +4484 -3967
- package/dist/components-BkGF4B4y.js.map +1 -0
- package/dist/composables/experiment-utils.d.ts +8 -0
- package/dist/composables/index.d.ts +5 -7
- package/dist/composables/index.js +4 -4
- package/dist/composables/useAppExperiment.d.ts +31 -2
- package/dist/composables/useBioTemplateComponents.d.ts +5 -3
- package/dist/composables/useBioTemplatePackWorkspace.d.ts +3 -2
- package/dist/composables/useBioTemplatePresetWorkspace.d.ts +6 -5
- package/dist/composables/useBioTemplateWorkspace.d.ts +5 -4
- package/dist/composables/useControlSchema.d.ts +43 -21
- package/dist/composables/usePluginClient.d.ts +5 -2
- package/dist/{composables-C3dpXQN5.js → composables-CHsME9H1.js} +40 -28
- package/dist/composables-CHsME9H1.js.map +1 -0
- package/dist/index.d.ts +5 -12
- package/dist/index.js +5 -5
- package/dist/install.js +2 -2
- package/dist/styles.css +3625 -3651
- package/dist/templates/componentBindings.d.ts +13 -0
- package/dist/templates/index.d.ts +3 -3
- package/dist/templates/index.js +2 -2
- package/dist/{templates-50NPjaxL.js → templates-B5jmTWuk.js} +111 -56
- package/dist/templates-B5jmTWuk.js.map +1 -0
- package/dist/types/components.d.ts +6 -25
- package/dist/types/index.d.ts +1 -1
- package/dist/{useScheduleDrag-D4oWdh41.js → useScheduleDrag-BgzpQT53.js} +160 -117
- package/dist/useScheduleDrag-BgzpQT53.js.map +1 -0
- package/package.json +1 -1
- package/src/__tests__/components/ActionItem.test.ts +6 -6
- package/src/__tests__/components/AppLayout.test.ts +44 -0
- package/src/__tests__/components/AppPageSelector.test.ts +8 -8
- package/src/__tests__/components/AppPillNav.test.ts +53 -6
- package/src/__tests__/components/AppSidebar.test.ts +126 -0
- package/src/__tests__/components/AppToastContainer.test.ts +0 -11
- package/src/__tests__/components/AppTopBar.test.ts +182 -119
- package/src/__tests__/components/BioTemplateExperimentWorkspaceView.test.ts +7 -1
- package/src/__tests__/components/BioTemplatePackWorkspaceView.test.ts +15 -1
- package/src/__tests__/components/BioTemplatePresetWorkspaceView.test.ts +26 -1
- package/src/__tests__/components/CalendarGridPanel.test.ts +3 -3
- package/src/__tests__/components/ComponentBindingRenderer.test.ts +161 -0
- package/src/__tests__/components/ControlWorkspaceView.test.ts +134 -63
- package/src/__tests__/components/DateTimePicker.test.ts +2 -2
- package/src/__tests__/components/DoseDesignWorkspaceView.test.ts +185 -0
- package/src/__tests__/components/PluginWorkspaceView.test.ts +548 -0
- package/src/__tests__/composables/experiment-utils.test.ts +30 -0
- package/src/__tests__/composables/useApi.test.ts +30 -0
- package/src/__tests__/composables/useAppExperiment.test.ts +100 -1
- package/src/__tests__/composables/useBioTemplatePackWorkspace.test.ts +6 -3
- package/src/__tests__/composables/useBioTemplatePresetWorkspace.test.ts +6 -6
- package/src/__tests__/composables/useBioTemplateWorkspace.test.ts +6 -1
- package/src/__tests__/composables/useControlSchema.test.ts +150 -36
- package/src/__tests__/composables/usePluginClient.test.ts +99 -2
- package/src/__tests__/docs/frontendDocsCatalog.test.ts +120 -25
- package/src/__tests__/templates/templates.test.ts +12 -0
- package/src/components/AppAvatarMenu.vue +3 -3
- package/src/components/AppLayout.story.vue +39 -0
- package/src/components/AppLayout.vue +83 -2
- package/src/components/AppPluginSwitcher.vue +5 -5
- package/src/components/AppSidebar.story.vue +113 -5
- package/src/components/AppSidebar.vue +144 -24
- package/src/components/AppTopBar.story.vue +2 -5
- package/src/components/AppTopBar.vue +35 -425
- package/src/components/BioTemplateExperimentWorkspaceView.story.vue +2 -2
- package/src/components/BioTemplateExperimentWorkspaceView.vue +6 -0
- package/src/components/BioTemplatePackWorkspaceView.story.vue +4 -4
- package/src/components/BioTemplatePackWorkspaceView.vue +1 -0
- package/src/components/BioTemplatePresetWorkspaceView.story.vue +14 -2
- package/src/components/BioTemplatePresetWorkspaceView.vue +11 -2
- package/src/components/BioTemplateRenderer.vue +15 -227
- package/src/components/ComponentBindingRenderer.story.vue +57 -0
- package/src/components/ComponentBindingRenderer.vue +308 -0
- package/src/components/ControlWorkspaceView.story.vue +20 -9
- package/src/components/ControlWorkspaceView.vue +43 -12
- package/src/components/DatePicker.vue +2 -2
- package/src/components/DateTimePicker.vue +2 -2
- package/src/components/DoseDesignWorkspaceView.story.vue +77 -0
- package/src/components/DoseDesignWorkspaceView.vue +255 -0
- package/src/components/ExperimentPopover.vue +2 -6
- package/src/components/ExperimentSelectorModal.vue +6 -5
- package/src/components/FormBuilder.story.vue +190 -0
- package/src/components/PluginWorkspaceView.story.vue +334 -0
- package/src/components/PluginWorkspaceView.vue +708 -0
- package/src/components/SettingsModal.story.vue +87 -0
- package/src/components/WellPlate.vue +2 -2
- package/src/components/index.ts +3 -12
- package/src/components/{AppPageSelector.vue → internal/AppPageSelectorInternal.vue} +9 -9
- package/src/components/internal/AppPillNavInternal.vue +194 -0
- package/src/components/{CalendarGridPanel.vue → internal/CalendarGridPanelInternal.vue} +1 -1
- package/src/components/{WellEditPopup.vue → internal/WellEditPopupInternal.vue} +3 -3
- package/src/composables/experiment-utils.ts +26 -0
- package/src/composables/index.ts +21 -7
- package/src/composables/useApi.ts +9 -2
- package/src/composables/useAppExperiment.ts +85 -13
- package/src/composables/useBioTemplateComponents.ts +12 -0
- package/src/composables/useBioTemplatePackWorkspace.ts +6 -2
- package/src/composables/useBioTemplatePresetWorkspace.ts +10 -21
- package/src/composables/useBioTemplateWorkspace.ts +6 -4
- package/src/composables/useControlSchema.ts +157 -69
- package/src/composables/usePluginClient.ts +50 -9
- package/src/index.ts +6 -563
- package/src/styles/components/app-layout.css +82 -0
- package/src/styles/components/app-pill-nav.css +70 -0
- package/src/styles/components/app-sidebar.css +119 -0
- package/src/styles/components/app-top-bar.css +0 -235
- package/src/styles/index.css +0 -1
- package/src/templates/componentBindings.ts +38 -0
- package/src/templates/index.ts +4 -0
- package/src/types/components.ts +6 -31
- package/src/types/index.ts +2 -6
- package/dist/__tests__/composables/usePluginApi.test.d.ts +0 -13
- package/dist/components/FormFieldRenderer.vue.d.ts +0 -28
- package/dist/components/FormSection.vue.d.ts +0 -30
- package/dist/components/GroupingModal.vue.d.ts +0 -12
- package/dist/components/SettingsButton.vue.d.ts +0 -30
- package/dist/components/ToastNotification.vue.d.ts +0 -2
- package/dist/components-D_Sr0adg.js.map +0 -1
- package/dist/composables/usePluginApi.d.ts +0 -22
- package/dist/composables-C3dpXQN5.js.map +0 -1
- package/dist/templates-50NPjaxL.js.map +0 -1
- package/dist/useScheduleDrag-D4oWdh41.js.map +0 -1
- package/src/__tests__/components/FormCompatibility.test.ts +0 -94
- package/src/__tests__/components/GroupingModal.test.ts +0 -73
- package/src/__tests__/components/SettingsButton.test.ts +0 -44
- package/src/__tests__/composables/usePluginApi.test.ts +0 -81
- package/src/components/AppPillNav.vue +0 -71
- package/src/components/FormFieldRenderer.vue +0 -35
- package/src/components/FormSection.vue +0 -37
- package/src/components/GroupingModal.story.vue +0 -52
- package/src/components/GroupingModal.vue +0 -61
- package/src/components/SettingsButton.story.vue +0 -58
- package/src/components/SettingsButton.vue +0 -64
- package/src/components/ToastNotification.vue +0 -9
- package/src/composables/usePluginApi.ts +0 -32
- package/src/styles/components/settings-button.css +0 -31
- /package/dist/__tests__/components/{FormCompatibility.test.d.ts → ComponentBindingRenderer.test.d.ts} +0 -0
- /package/dist/__tests__/components/{GroupingModal.test.d.ts → DoseDesignWorkspaceView.test.d.ts} +0 -0
- /package/dist/__tests__/components/{SettingsButton.test.d.ts → PluginWorkspaceView.test.d.ts} +0 -0
- /package/dist/components/{ActionItem.vue.d.ts → internal/ActionItemInternal.vue.d.ts} +0 -0
- /package/src/components/{ActionItem.vue → internal/ActionItemInternal.vue} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
|
|
2
|
-
import { ref, computed } from 'vue'
|
|
2
|
+
import { ref, computed, nextTick } from 'vue'
|
|
3
3
|
|
|
4
4
|
// Capture side-effect callbacks so tests can invoke them directly
|
|
5
5
|
let capturedScopeDispose: (() => void) | null = null
|
|
@@ -83,6 +83,43 @@ describe('useAppExperiment', () => {
|
|
|
83
83
|
// -------------------------------------------------------------------------
|
|
84
84
|
|
|
85
85
|
describe('set', () => {
|
|
86
|
+
it('should initialize from a direct experiment option', () => {
|
|
87
|
+
const { experimentName, experimentCode, experimentId } = useAppExperiment({
|
|
88
|
+
experiment: makeExperiment({ id: 8, name: 'Initial run', experiment_code: 'EXP-008' }),
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
expect(experimentName.value).toBe('Initial run')
|
|
92
|
+
expect(experimentCode.value).toBe('EXP-008')
|
|
93
|
+
expect(experimentId.value).toBe(8)
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
it('should sync and clear a reactive experiment option', async () => {
|
|
97
|
+
const source = ref<ExperimentSummary | null>(
|
|
98
|
+
makeExperiment({ id: 8, name: 'Initial run', experiment_code: 'EXP-008' }),
|
|
99
|
+
)
|
|
100
|
+
const { experimentName, experimentCode, experimentId } = useAppExperiment({
|
|
101
|
+
experiment: source,
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
expect(experimentName.value).toBe('Initial run')
|
|
105
|
+
expect(experimentCode.value).toBe('EXP-008')
|
|
106
|
+
expect(experimentId.value).toBe(8)
|
|
107
|
+
|
|
108
|
+
source.value = makeExperiment({ id: 9, name: 'Updated run', experiment_code: 'EXP-009' })
|
|
109
|
+
await nextTick()
|
|
110
|
+
|
|
111
|
+
expect(experimentName.value).toBe('Updated run')
|
|
112
|
+
expect(experimentCode.value).toBe('EXP-009')
|
|
113
|
+
expect(experimentId.value).toBe(9)
|
|
114
|
+
|
|
115
|
+
source.value = null
|
|
116
|
+
await nextTick()
|
|
117
|
+
|
|
118
|
+
expect(experimentName.value).toBeUndefined()
|
|
119
|
+
expect(experimentCode.value).toBeUndefined()
|
|
120
|
+
expect(experimentId.value).toBeNull()
|
|
121
|
+
})
|
|
122
|
+
|
|
86
123
|
it('should update experimentName and experimentId on set', () => {
|
|
87
124
|
const { set, experimentName, experimentId } = useAppExperiment()
|
|
88
125
|
const experiment = makeExperiment({ id: 7, name: 'Alpha Run' })
|
|
@@ -511,6 +548,68 @@ describe('useAppExperiment', () => {
|
|
|
511
548
|
})
|
|
512
549
|
})
|
|
513
550
|
|
|
551
|
+
// -------------------------------------------------------------------------
|
|
552
|
+
// component bindings
|
|
553
|
+
// -------------------------------------------------------------------------
|
|
554
|
+
|
|
555
|
+
describe('component bindings', () => {
|
|
556
|
+
it('exposes live ExperimentPopover props from the provided state', async () => {
|
|
557
|
+
const saveDisabled = ref(false)
|
|
558
|
+
const saveDisabledMessage = ref<string | undefined>('Ready to save')
|
|
559
|
+
const onSave = vi.fn().mockResolvedValue('Saved')
|
|
560
|
+
const { set } = useAppExperiment({ onSave, saveDisabled, saveDisabledMessage })
|
|
561
|
+
const state = getState()
|
|
562
|
+
|
|
563
|
+
set(makeExperiment({
|
|
564
|
+
id: 12,
|
|
565
|
+
name: 'Dose response',
|
|
566
|
+
status: 'ongoing',
|
|
567
|
+
experiment_code: 'EXP-012',
|
|
568
|
+
}))
|
|
569
|
+
|
|
570
|
+
expect(state.popover.value).toMatchObject({
|
|
571
|
+
experimentName: 'Dose response',
|
|
572
|
+
experimentCode: 'EXP-012',
|
|
573
|
+
experimentStatus: 'ongoing',
|
|
574
|
+
showSave: true,
|
|
575
|
+
showDetach: true,
|
|
576
|
+
saveDisabled: false,
|
|
577
|
+
saveDisabledMessage: 'Ready to save',
|
|
578
|
+
saveLoading: false,
|
|
579
|
+
})
|
|
580
|
+
|
|
581
|
+
saveDisabled.value = true
|
|
582
|
+
saveDisabledMessage.value = 'Locked'
|
|
583
|
+
|
|
584
|
+
expect(state.popover.value.saveDisabled).toBe(true)
|
|
585
|
+
expect(state.popover.value.saveDisabledMessage).toBe('Locked')
|
|
586
|
+
|
|
587
|
+
await state.handleSave()
|
|
588
|
+
|
|
589
|
+
expect(state.popover.value.saveSuccessMessage).toBe('Saved')
|
|
590
|
+
})
|
|
591
|
+
|
|
592
|
+
it('exposes live ExperimentSelectorModal props from state and return value', () => {
|
|
593
|
+
const appExperiment = useAppExperiment()
|
|
594
|
+
const state = getState()
|
|
595
|
+
|
|
596
|
+
expect(state.selectorModal.value).toEqual({
|
|
597
|
+
modelValue: false,
|
|
598
|
+
currentExperimentId: null,
|
|
599
|
+
})
|
|
600
|
+
expect(appExperiment.selectorModal.value).toEqual(state.selectorModal.value)
|
|
601
|
+
|
|
602
|
+
appExperiment.set(makeExperiment({ id: 77 }))
|
|
603
|
+
state.openModal()
|
|
604
|
+
|
|
605
|
+
expect(state.selectorModal.value).toEqual({
|
|
606
|
+
modelValue: true,
|
|
607
|
+
currentExperimentId: 77,
|
|
608
|
+
})
|
|
609
|
+
expect(appExperiment.popover.value.experimentName).toBe('Test Experiment')
|
|
610
|
+
})
|
|
611
|
+
})
|
|
612
|
+
|
|
514
613
|
// -------------------------------------------------------------------------
|
|
515
614
|
// Timer cleanup via onScopeDispose
|
|
516
615
|
// -------------------------------------------------------------------------
|
|
@@ -46,7 +46,7 @@ describe('useBioTemplatePackWorkspace', () => {
|
|
|
46
46
|
expect(workspace.sidebar.value).toBe(workspace.workspace.value.sidebar)
|
|
47
47
|
expect(workspace.sidebar.value.values).toBe(workspace.workspace.value.values)
|
|
48
48
|
expect(workspace.sidebar.value.activeView).toBe('design')
|
|
49
|
-
expect(workspace.topBar.value).toBe(workspace.workspace.value.topBar)
|
|
49
|
+
expect(workspace.topBar.value).toBe(workspace.workspace.value.topBar.value)
|
|
50
50
|
expect(workspace.pillNav.value).toBe(workspace.workspace.value.pillNav)
|
|
51
51
|
expect(workspace.pillNav.value.items.map(item => item.id)).toContain('design')
|
|
52
52
|
expect(workspace.topBarSettings.value).toBe(workspace.workspace.value.topBarSettings)
|
|
@@ -56,9 +56,12 @@ describe('useBioTemplatePackWorkspace', () => {
|
|
|
56
56
|
expect(workspace.topBarSettings.value.settingsConfig.values).toBe(workspace.workspace.value.values)
|
|
57
57
|
expect(workspace.sidebar.value.panels.design.map(panel => panel.id)).toContain('dose')
|
|
58
58
|
expect(workspace.componentBindings.value.map(binding => binding.component)).toContain('DoseCalculator')
|
|
59
|
+
expect(workspace.componentBindingsById.value['dose-response:DoseCalculator'].component).toBe('DoseCalculator')
|
|
60
|
+
expect(workspace.componentBindingsById.value['dose-response:DoseCalculator'].props.mode).toBe('serial')
|
|
59
61
|
expect(workspace.componentProps.value.map(binding => binding.component)).toContain('PlateMapEditor')
|
|
60
62
|
expect(workspace.componentPropsById.value['plate-map:WellPlate'].wells).toBeDefined()
|
|
61
63
|
expect(workspace.bindings.value.componentPropsById['plate-map:WellPlate'].wells).toBeDefined()
|
|
64
|
+
expect(workspace.bindings.value.componentBindingsById['plate-map:WellPlate'].props.wells).toBeDefined()
|
|
62
65
|
expect(workspace.componentPropsByComponent.value.WellPlate.length).toBeGreaterThan(0)
|
|
63
66
|
expect(workspace.getComponentProps('WellPlate')?.wells).toBeDefined()
|
|
64
67
|
expect(workspace.bindings.value.getComponentProps('WellPlate')?.wells).toBeDefined()
|
|
@@ -79,10 +82,10 @@ describe('useBioTemplatePackWorkspace', () => {
|
|
|
79
82
|
workspace.pillNav.value.onSelect({ id: 'analysis', label: 'Analysis' })
|
|
80
83
|
expect(inner.activeView.value).toBe('analysis')
|
|
81
84
|
expect(workspace.sidebar.value.activeView).toBe('analysis')
|
|
82
|
-
expect(workspace.topBar.value.
|
|
85
|
+
expect(workspace.topBar.value.currentPillId).toBe('analysis')
|
|
83
86
|
expect(workspace.bindings.value.topBar.value.currentPillId).toBe('analysis')
|
|
84
87
|
|
|
85
|
-
workspace.topBar.value.
|
|
88
|
+
workspace.topBar.value.onPillSelect({ id: 'run', label: 'Run' })
|
|
86
89
|
expect(inner.activeView.value).toBe('run')
|
|
87
90
|
expect(workspace.sidebar.value.activeView).toBe('run')
|
|
88
91
|
expect(workspace.pillNav.value.currentItemId).toBe('run')
|
|
@@ -53,16 +53,18 @@ describe('useBioTemplatePresetWorkspace', () => {
|
|
|
53
53
|
expect(workspace.bindings.topBarSettings).toBe(workspace.topBarSettings)
|
|
54
54
|
expect(workspace.bindings.pillNav).toBe(workspace.pillNav)
|
|
55
55
|
expect(workspace.bindings.topBar.value.currentPillId).toBe('design')
|
|
56
|
-
expect(workspace.bindings.topBarTabs.value.currentTabId).toBe('design')
|
|
57
56
|
expect(workspace.controlViewIds.value).toEqual(['design'])
|
|
58
57
|
expect(workspace.controlViewItems.value).toEqual([{ id: 'design', label: 'Design' }])
|
|
59
58
|
expect(workspace.activeControlView.value).toBe('design')
|
|
60
59
|
expect(workspace.renderer.value.target).toBe(workspace.collection.value)
|
|
61
60
|
expect(workspace.bindings.renderer.value.target).toBe(workspace.collection.value)
|
|
62
61
|
expect(workspace.componentBindings.value.map(binding => binding.component)).toContain('DoseCalculator')
|
|
62
|
+
expect(workspace.componentBindingsById.value['dose-response:DoseCalculator'].component).toBe('DoseCalculator')
|
|
63
|
+
expect(workspace.componentBindingsById.value['dose-response:DoseCalculator'].props.mode).toBe('serial')
|
|
63
64
|
expect(workspace.componentProps.value.map(binding => binding.component)).toContain('WellPlate')
|
|
64
65
|
expect(workspace.componentPropsById.value['dose-response:DoseCalculator'].mode).toBe('serial')
|
|
65
66
|
expect(workspace.bindings.componentPropsById.value['dose-response:DoseCalculator'].mode).toBe('serial')
|
|
67
|
+
expect(workspace.bindings.componentBindingsById.value['dose-response:DoseCalculator'].props.mode).toBe('serial')
|
|
66
68
|
expect(workspace.componentPropsByComponent.value.WellPlate).toHaveLength(2)
|
|
67
69
|
expect(workspace.getComponentProps('DoseCalculator')?.mode).toBe('serial')
|
|
68
70
|
expect(workspace.bindings.getComponentProps('DoseCalculator')?.mode).toBe('serial')
|
|
@@ -82,7 +84,7 @@ describe('useBioTemplatePresetWorkspace', () => {
|
|
|
82
84
|
workspace.setActiveControlView('analysis')
|
|
83
85
|
expect(workspace.activeControlView.value).toBe('analysis')
|
|
84
86
|
expect(workspace.sidebar.activeView).toBe('analysis')
|
|
85
|
-
expect(workspace.topBar.
|
|
87
|
+
expect(workspace.topBar.value.currentPillId).toBe('analysis')
|
|
86
88
|
expect(workspace.pillNav.currentItemId).toBe('analysis')
|
|
87
89
|
|
|
88
90
|
workspace.setActiveControlView('missing')
|
|
@@ -104,15 +106,13 @@ describe('useBioTemplatePresetWorkspace', () => {
|
|
|
104
106
|
workspace.pillNav.onSelect({ id: 'analysis', label: 'Analysis' })
|
|
105
107
|
expect(workspace.activeControlView.value).toBe('analysis')
|
|
106
108
|
expect(workspace.sidebar.activeView).toBe('analysis')
|
|
107
|
-
expect(workspace.topBar.
|
|
109
|
+
expect(workspace.topBar.value.currentPillId).toBe('analysis')
|
|
108
110
|
expect(workspace.bindings.topBar.value.currentPillId).toBe('analysis')
|
|
109
|
-
expect(workspace.bindings.topBarTabs.value.currentTabId).toBe('analysis')
|
|
110
111
|
|
|
111
|
-
workspace.topBar.
|
|
112
|
+
workspace.topBar.value.onPillSelect({ id: 'run', label: 'Run' })
|
|
112
113
|
expect(workspace.activeControlView.value).toBe('run')
|
|
113
114
|
expect(workspace.pillNav.currentItemId).toBe('run')
|
|
114
115
|
expect(workspace.bindings.topBar.value.currentPillId).toBe('run')
|
|
115
|
-
expect(workspace.bindings.topBarTabs.value.currentTabId).toBe('run')
|
|
116
116
|
})
|
|
117
117
|
|
|
118
118
|
it('accepts direct initial values for generated preset controls and collection data', () => {
|
|
@@ -36,6 +36,9 @@ describe('useBioTemplateWorkspace', () => {
|
|
|
36
36
|
expect(workspace.sidebar.panels.design.map(panel => panel.id)).toContain('dose')
|
|
37
37
|
expect(workspace.componentProps.map(binding => binding.component)).toContain('DoseCalculator')
|
|
38
38
|
expect(workspace.componentProps.map(binding => binding.component)).toContain('WellPlate')
|
|
39
|
+
expect(workspace.componentBindingsById['plate-map:WellPlate'].component).toBe('WellPlate')
|
|
40
|
+
expect(workspace.componentBindingsById['plate-map:WellPlate'].props.wells).toBeDefined()
|
|
41
|
+
expect(workspace.bindings.componentBindingsById['dose-response:DoseCalculator'].props.mode).toBe('serial')
|
|
39
42
|
expect(workspace.componentPropsById['plate-map:WellPlate'].wells).toBeDefined()
|
|
40
43
|
expect(workspace.bindings.componentPropsById['plate-map:WellPlate'].wells).toBeDefined()
|
|
41
44
|
expect(workspace.componentPropsById['dose-response:DoseCalculator'].mode).toBe('serial')
|
|
@@ -56,14 +59,16 @@ describe('useBioTemplateWorkspace', () => {
|
|
|
56
59
|
expect(workspace.controlSchema.sampleNames).toBe(workspace.controls.controls.sampleNames)
|
|
57
60
|
expect(workspace.values.sampleNames).toEqual(['Control', 'Treatment'])
|
|
58
61
|
expect(workspace.activeView.value).toBe('design')
|
|
59
|
-
expect(workspace.topBar.
|
|
62
|
+
expect(workspace.topBar.value.pillNav.map(item => item.id)).toContain('design')
|
|
60
63
|
expect(workspace.pillNav.items.map(item => item.id)).toContain('design')
|
|
61
64
|
expect(workspace.controls.initialValues.sampleNames).toEqual(['Control', 'Treatment'])
|
|
62
65
|
expect(workspace.sidebar.panels.design.map(panel => panel.id)).toContain('layout')
|
|
63
66
|
expect(workspace.componentBindings.map(binding => binding.component)).toContain('PlateMapEditor')
|
|
64
67
|
expect(workspace.componentImports[0].statement).toContain('WellPlate')
|
|
65
68
|
expect(workspace.componentProps).toEqual([])
|
|
69
|
+
expect(workspace.componentBindingsById).toEqual({})
|
|
66
70
|
expect(workspace.componentPropsById).toEqual({})
|
|
71
|
+
expect(workspace.bindings.componentBindingsById).toEqual({})
|
|
67
72
|
expect(workspace.bindings.componentPropsById).toEqual({})
|
|
68
73
|
expect(workspace.componentPropsByComponent).toEqual({})
|
|
69
74
|
expect(workspace.getComponentProps('WellPlate')).toBeUndefined()
|
|
@@ -7,15 +7,18 @@ import {
|
|
|
7
7
|
controlsToSidebarPanels,
|
|
8
8
|
controlsToSettingsSchema,
|
|
9
9
|
controlsToTopBarSettingsConfig,
|
|
10
|
-
controlsToTopBarTabs,
|
|
11
10
|
controlsToViewIds,
|
|
12
11
|
controlsToViewItems,
|
|
12
|
+
controlValuesToComponentBindings,
|
|
13
|
+
controlValuesToComponentBindingsById,
|
|
13
14
|
controlValuesToComponentProps,
|
|
15
|
+
defineControlComponentBindings,
|
|
14
16
|
defineControlModel,
|
|
15
17
|
defineDoseDesignControlModel,
|
|
16
18
|
defineDoseCalculatorControlProps,
|
|
17
19
|
defineControls,
|
|
18
20
|
defineWellPlateControlProps,
|
|
21
|
+
defineWellPlateDoseComponentBindings,
|
|
19
22
|
defineWellPlateDoseControlProps,
|
|
20
23
|
getDefaultControlView,
|
|
21
24
|
getControlDefaults,
|
|
@@ -194,11 +197,10 @@ describe('useControlSchema', () => {
|
|
|
194
197
|
it('returns view helpers that can drive AppPillNav and AppSidebar together', () => {
|
|
195
198
|
expect(controlsToViewIds(controls)).toEqual(['analysis'])
|
|
196
199
|
expect(controlsToViewItems(controls)).toEqual([{ id: 'analysis', label: 'Analysis' }])
|
|
197
|
-
expect(controlsToTopBarTabs(controls)).toEqual([{ id: 'analysis', label: 'Analysis' }])
|
|
198
200
|
expect(getDefaultControlView(controls)).toBe('analysis')
|
|
199
201
|
})
|
|
200
202
|
|
|
201
|
-
it('uses shared view metadata for AppTopBar
|
|
203
|
+
it('uses shared view metadata for AppTopBar pill navigation', () => {
|
|
202
204
|
const runIcon = 'M8 5v14l11-7z'
|
|
203
205
|
const options = {
|
|
204
206
|
views: {
|
|
@@ -218,14 +220,6 @@ describe('useControlSchema', () => {
|
|
|
218
220
|
disabled: false,
|
|
219
221
|
},
|
|
220
222
|
])
|
|
221
|
-
expect(controlsToTopBarTabs(controls, options)).toEqual([
|
|
222
|
-
{
|
|
223
|
-
id: 'analysis',
|
|
224
|
-
label: 'Run',
|
|
225
|
-
icon: runIcon,
|
|
226
|
-
disabled: false,
|
|
227
|
-
},
|
|
228
|
-
])
|
|
229
223
|
})
|
|
230
224
|
|
|
231
225
|
it('flattens nested control models into workspace bindings', () => {
|
|
@@ -282,6 +276,23 @@ describe('useControlSchema', () => {
|
|
|
282
276
|
disabled: values => !values.showHeatmap,
|
|
283
277
|
},
|
|
284
278
|
},
|
|
279
|
+
components: defineControlComponentBindings({
|
|
280
|
+
dose: {
|
|
281
|
+
component: 'DoseCalculator',
|
|
282
|
+
props: {
|
|
283
|
+
mode: 'concentrationUnit',
|
|
284
|
+
targetWells: values => values.showHeatmap ? ['A1', 'A2'] : [],
|
|
285
|
+
disabled: values => !values.showHeatmap,
|
|
286
|
+
},
|
|
287
|
+
},
|
|
288
|
+
plate: {
|
|
289
|
+
component: 'WellPlate',
|
|
290
|
+
props: {
|
|
291
|
+
modelValue: values => values.showHeatmap ? ['A1', 'A2'] : [],
|
|
292
|
+
disabled: values => !values.showHeatmap,
|
|
293
|
+
},
|
|
294
|
+
},
|
|
295
|
+
}),
|
|
285
296
|
})
|
|
286
297
|
|
|
287
298
|
expect(model.controls.concentrationUnit).toMatchObject({
|
|
@@ -309,11 +320,12 @@ describe('useControlSchema', () => {
|
|
|
309
320
|
})
|
|
310
321
|
expect(model.componentProps).toBeDefined()
|
|
311
322
|
expect(model.componentPropsById).toBeDefined()
|
|
323
|
+
expect(model.componentBindings).toBeDefined()
|
|
312
324
|
|
|
313
325
|
const workspace = useControlWorkspace(model.controls, model.controlOptions)
|
|
314
326
|
|
|
315
327
|
expect(workspace.values.replicates).toBe(4)
|
|
316
|
-
expect(workspace.topBar.
|
|
328
|
+
expect(workspace.topBar.value.pillNav.map(item => [item.id, item.label])).toEqual([
|
|
317
329
|
['design', 'Design'],
|
|
318
330
|
['results', 'Results'],
|
|
319
331
|
])
|
|
@@ -342,6 +354,80 @@ describe('useControlSchema', () => {
|
|
|
342
354
|
disabled: false,
|
|
343
355
|
},
|
|
344
356
|
})
|
|
357
|
+
expect(workspace.getComponentBindings(model.componentBindings)).toEqual([
|
|
358
|
+
{
|
|
359
|
+
id: 'dose',
|
|
360
|
+
component: 'DoseCalculator',
|
|
361
|
+
props: {
|
|
362
|
+
mode: 'uM',
|
|
363
|
+
targetWells: ['A1', 'A2'],
|
|
364
|
+
disabled: false,
|
|
365
|
+
},
|
|
366
|
+
},
|
|
367
|
+
{
|
|
368
|
+
id: 'plate',
|
|
369
|
+
component: 'WellPlate',
|
|
370
|
+
props: {
|
|
371
|
+
modelValue: ['A1', 'A2'],
|
|
372
|
+
disabled: false,
|
|
373
|
+
},
|
|
374
|
+
},
|
|
375
|
+
])
|
|
376
|
+
expect(workspace.getComponentBindingsById(model.componentBindings).plate.props.modelValue).toEqual(['A1', 'A2'])
|
|
377
|
+
})
|
|
378
|
+
|
|
379
|
+
it('maps control values into named SDK component bindings', () => {
|
|
380
|
+
const values = {
|
|
381
|
+
threshold: 0.05,
|
|
382
|
+
selectedWells: ['A1'],
|
|
383
|
+
enabled: true,
|
|
384
|
+
}
|
|
385
|
+
const bindings = defineControlComponentBindings([
|
|
386
|
+
{
|
|
387
|
+
component: 'ResultChart',
|
|
388
|
+
props: {
|
|
389
|
+
score: 'threshold',
|
|
390
|
+
disabled: values => !values.enabled,
|
|
391
|
+
},
|
|
392
|
+
},
|
|
393
|
+
{
|
|
394
|
+
component: 'ResultChart',
|
|
395
|
+
props: ['selectedWells'],
|
|
396
|
+
},
|
|
397
|
+
{
|
|
398
|
+
id: 'plate',
|
|
399
|
+
component: 'WellPlate',
|
|
400
|
+
props: {
|
|
401
|
+
modelValue: 'selectedWells',
|
|
402
|
+
},
|
|
403
|
+
},
|
|
404
|
+
])
|
|
405
|
+
|
|
406
|
+
expect(controlValuesToComponentBindings(values, bindings)).toEqual([
|
|
407
|
+
{
|
|
408
|
+
id: 'ResultChart',
|
|
409
|
+
component: 'ResultChart',
|
|
410
|
+
props: {
|
|
411
|
+
score: 0.05,
|
|
412
|
+
disabled: false,
|
|
413
|
+
},
|
|
414
|
+
},
|
|
415
|
+
{
|
|
416
|
+
id: 'ResultChart-2',
|
|
417
|
+
component: 'ResultChart',
|
|
418
|
+
props: {
|
|
419
|
+
selectedWells: ['A1'],
|
|
420
|
+
},
|
|
421
|
+
},
|
|
422
|
+
{
|
|
423
|
+
id: 'plate',
|
|
424
|
+
component: 'WellPlate',
|
|
425
|
+
props: {
|
|
426
|
+
modelValue: ['A1'],
|
|
427
|
+
},
|
|
428
|
+
},
|
|
429
|
+
])
|
|
430
|
+
expect(controlValuesToComponentBindingsById(values, bindings).plate.component).toBe('WellPlate')
|
|
345
431
|
})
|
|
346
432
|
|
|
347
433
|
it('keeps direct view controls in separate generated sections', () => {
|
|
@@ -466,7 +552,6 @@ describe('useControlSchema', () => {
|
|
|
466
552
|
expect(toolkit.sidebarPanels.analysis).toHaveLength(2)
|
|
467
553
|
expect(toolkit.viewIds).toEqual(['analysis'])
|
|
468
554
|
expect(toolkit.viewItems).toEqual([{ id: 'analysis', label: 'Analysis' }])
|
|
469
|
-
expect(toolkit.topBarTabs).toEqual([{ id: 'analysis', label: 'Analysis' }])
|
|
470
555
|
expect(toolkit.defaultView).toBe('analysis')
|
|
471
556
|
expect(toolkit.sidebar.panels).toBe(toolkit.sidebarPanels)
|
|
472
557
|
expect(toolkit.sidebar.forms).toBe(toolkit.sectionSchemas)
|
|
@@ -502,8 +587,8 @@ describe('useControlSchema', () => {
|
|
|
502
587
|
expect(workspace.sidebar.modelValue).toBe(workspace.values)
|
|
503
588
|
expect(workspace.sidebar.values).toBe(workspace.values)
|
|
504
589
|
expect(workspace.sidebar.activeView).toBe('default')
|
|
505
|
-
expect(workspace.topBar.
|
|
506
|
-
expect(workspace.topBar.
|
|
590
|
+
expect(workspace.topBar.value.pillNav).toEqual([{ id: 'default', label: 'Default' }])
|
|
591
|
+
expect(workspace.topBar.value.currentPillId).toBe('default')
|
|
507
592
|
expect(workspace.pillNav.items).toEqual([{ id: 'default', label: 'Default' }])
|
|
508
593
|
expect(workspace.pillNav.currentItemId).toBe('default')
|
|
509
594
|
expect(workspace.topBarSettings.settingsConfig.values).toBe(workspace.values)
|
|
@@ -514,8 +599,11 @@ describe('useControlSchema', () => {
|
|
|
514
599
|
expect(workspace.topBarSettings.settingsConfig.schema).toBeUndefined()
|
|
515
600
|
expect(workspace.bindings.form).toBe(workspace.form)
|
|
516
601
|
expect(workspace.bindings.sidebar).toBe(workspace.sidebar)
|
|
602
|
+
expect(workspace.bindings.topBar).toBe(workspace.topBar)
|
|
517
603
|
expect(workspace.bindings.topBarSettings).toBe(workspace.topBarSettings)
|
|
518
604
|
expect(workspace.bindings.pillNav).toBe(workspace.pillNav)
|
|
605
|
+
expect(workspace.bindings.componentBindings).toBe(workspace.componentBindings)
|
|
606
|
+
expect(workspace.bindings.componentBindingsById).toBe(workspace.componentBindingsById)
|
|
519
607
|
expect(workspace.bindings.componentProps).toBe(workspace.componentProps)
|
|
520
608
|
expect(workspace.bindings.componentPropsById).toBe(workspace.componentPropsById)
|
|
521
609
|
expect(workspace.bindings.topBar.value).toMatchObject({
|
|
@@ -524,12 +612,6 @@ describe('useControlSchema', () => {
|
|
|
524
612
|
showSettings: true,
|
|
525
613
|
settingsConfig: workspace.topBarSettingsConfig,
|
|
526
614
|
})
|
|
527
|
-
expect(workspace.bindings.topBarTabs.value).toMatchObject({
|
|
528
|
-
tabs: workspace.topBar.tabs,
|
|
529
|
-
currentTabId: 'default',
|
|
530
|
-
showSettings: true,
|
|
531
|
-
settingsConfig: workspace.topBarSettingsConfig,
|
|
532
|
-
})
|
|
533
615
|
|
|
534
616
|
workspace.form['onUpdate:modelValue']({ threshold: 0.5, model: 'logistic' })
|
|
535
617
|
expect(workspace.values.threshold).toBe(0.5)
|
|
@@ -545,7 +627,7 @@ describe('useControlSchema', () => {
|
|
|
545
627
|
workspace.topBarSettings.onSettingsValuesChange({ mode: 'careful' })
|
|
546
628
|
expect(workspace.values.mode).toBe('careful')
|
|
547
629
|
|
|
548
|
-
workspace.topBar.
|
|
630
|
+
workspace.topBar.value.onPillSelect({ id: 'missing', label: 'Missing' })
|
|
549
631
|
expect(workspace.activeView.value).toBe('default')
|
|
550
632
|
|
|
551
633
|
workspace.resetValues()
|
|
@@ -702,6 +784,12 @@ describe('useControlSchema', () => {
|
|
|
702
784
|
expect(workspace.componentPropsById.value.dose.mode).toBe('serial')
|
|
703
785
|
expect(workspace.componentPropsById.value.dose.targetWells).toEqual(['E1'])
|
|
704
786
|
expect(workspace.componentPropsById.value.dose.disabled).toBe(true)
|
|
787
|
+
expect(workspace.componentBindings.value.map(binding => [binding.id, binding.component])).toEqual([
|
|
788
|
+
['plate', 'WellPlate'],
|
|
789
|
+
['dose', 'DoseCalculator'],
|
|
790
|
+
])
|
|
791
|
+
expect(workspace.componentBindingsById.value.plate.props.modelValue).toEqual(['E1'])
|
|
792
|
+
expect(workspace.componentBindingsById.value.dose.props.disabled).toBe(true)
|
|
705
793
|
|
|
706
794
|
const updatePlateSelection = workspace.componentPropsById.value.plate['onUpdate:modelValue']
|
|
707
795
|
expect(typeof updatePlateSelection).toBe('function')
|
|
@@ -753,6 +841,25 @@ describe('useControlSchema', () => {
|
|
|
753
841
|
expect(doseProps.onApplyToWells).toBeUndefined()
|
|
754
842
|
})
|
|
755
843
|
|
|
844
|
+
it('creates WellPlate and DoseCalculator component bindings for dose controls', () => {
|
|
845
|
+
const workspace = useControlWorkspace(defineControls({
|
|
846
|
+
selectedWells: { type: 'tags', default: ['B1'] },
|
|
847
|
+
plateFormat: 384,
|
|
848
|
+
doseMode: ['serial', 'dilution'],
|
|
849
|
+
disabled: false,
|
|
850
|
+
}))
|
|
851
|
+
const bindings = workspace.getComponentBindings(defineWellPlateDoseComponentBindings())
|
|
852
|
+
|
|
853
|
+
expect(bindings.map(binding => [binding.id, binding.component])).toEqual([
|
|
854
|
+
['plate', 'WellPlate'],
|
|
855
|
+
['dose', 'DoseCalculator'],
|
|
856
|
+
])
|
|
857
|
+
expect(bindings[0].props.modelValue).toEqual(['B1'])
|
|
858
|
+
expect(bindings[0].props.format).toBe(384)
|
|
859
|
+
expect(bindings[1].props.mode).toBe('serial')
|
|
860
|
+
expect(bindings[1].props.targetWells).toEqual(['B1'])
|
|
861
|
+
})
|
|
862
|
+
|
|
756
863
|
it('creates a complete dose design control model from one helper', () => {
|
|
757
864
|
const model = defineDoseDesignControlModel({
|
|
758
865
|
selectedWells: ['C1', 'C2'],
|
|
@@ -783,6 +890,10 @@ describe('useControlSchema', () => {
|
|
|
783
890
|
expect(componentPropsById.dose.targetWells).toEqual(['C1', 'C2'])
|
|
784
891
|
expect(componentPropsById.dose.disabled).toBe(false)
|
|
785
892
|
expect(componentPropsById.dose.molecularWeight).toBe(300.44)
|
|
893
|
+
expect(workspace.getComponentBindings(model.componentBindings).map(binding => [binding.id, binding.component])).toEqual([
|
|
894
|
+
['plate', 'WellPlate'],
|
|
895
|
+
['dose', 'DoseCalculator'],
|
|
896
|
+
])
|
|
786
897
|
|
|
787
898
|
const updatePlateSelection = componentPropsById.plate['onUpdate:modelValue']
|
|
788
899
|
expect(typeof updatePlateSelection).toBe('function')
|
|
@@ -814,9 +925,13 @@ describe('useControlSchema', () => {
|
|
|
814
925
|
expect(componentPropsById.wellPlate.showLegend).toBe(true)
|
|
815
926
|
expect(componentPropsById.doseCalculator.mode).toBe('serial')
|
|
816
927
|
expect(componentPropsById.doseCalculator.targetWells).toEqual(['A1', 'A2'])
|
|
928
|
+
expect(workspace.getComponentBindings(model.componentBindings).map(binding => [binding.id, binding.component])).toEqual([
|
|
929
|
+
['wellPlate', 'WellPlate'],
|
|
930
|
+
['doseCalculator', 'DoseCalculator'],
|
|
931
|
+
])
|
|
817
932
|
})
|
|
818
933
|
|
|
819
|
-
it('keeps AppTopBar
|
|
934
|
+
it('keeps AppTopBar pill navigation and AppSidebar active view on the same workspace state', async () => {
|
|
820
935
|
const workspace = useControlWorkspace({
|
|
821
936
|
threshold: {
|
|
822
937
|
default: 0.05,
|
|
@@ -837,47 +952,43 @@ describe('useControlSchema', () => {
|
|
|
837
952
|
|
|
838
953
|
expect(workspace.activeView.value).toBe('analysis')
|
|
839
954
|
expect(workspace.sidebar.activeView).toBe('analysis')
|
|
840
|
-
expect(workspace.topBar.
|
|
955
|
+
expect(workspace.topBar.value.currentPillId).toBe('analysis')
|
|
841
956
|
expect(workspace.pillNav.currentItemId).toBe('analysis')
|
|
842
957
|
expect(workspace.bindings.topBar.value.currentPillId).toBe('analysis')
|
|
843
|
-
expect(workspace.
|
|
844
|
-
expect(workspace.topBar.tabs.map(tab => tab.label)).toEqual(['Run', 'Results'])
|
|
958
|
+
expect(workspace.topBar.value.pillNav.map(item => item.label)).toEqual(['Run', 'Results'])
|
|
845
959
|
expect(workspace.pillNav.items.map(item => item.label)).toEqual(['Run', 'Results'])
|
|
846
960
|
|
|
847
|
-
workspace.topBar.
|
|
961
|
+
workspace.topBar.value.onPillSelect({ id: 'results', label: 'Results' })
|
|
848
962
|
expect(workspace.activeView.value).toBe('results')
|
|
849
963
|
expect(workspace.sidebar.activeView).toBe('results')
|
|
850
|
-
expect(workspace.topBar.
|
|
964
|
+
expect(workspace.topBar.value.currentPillId).toBe('results')
|
|
851
965
|
expect(workspace.pillNav.currentItemId).toBe('results')
|
|
852
966
|
expect(workspace.bindings.topBar.value.currentPillId).toBe('results')
|
|
853
|
-
expect(workspace.bindings.topBarTabs.value.currentTabId).toBe('results')
|
|
854
967
|
|
|
855
968
|
workspace.setActiveView('analysis')
|
|
856
969
|
expect(workspace.activeView.value).toBe('analysis')
|
|
857
970
|
expect(workspace.sidebar.activeView).toBe('analysis')
|
|
858
|
-
expect(workspace.topBar.
|
|
971
|
+
expect(workspace.topBar.value.currentPillId).toBe('analysis')
|
|
859
972
|
expect(workspace.pillNav.currentItemId).toBe('analysis')
|
|
860
973
|
workspace.bindings.topBar.value.onPillSelect({ id: 'results', label: 'Results' })
|
|
861
974
|
expect(workspace.activeView.value).toBe('results')
|
|
862
975
|
expect(workspace.bindings.topBar.value.currentPillId).toBe('results')
|
|
863
|
-
expect(workspace.bindings.topBarTabs.value.currentTabId).toBe('results')
|
|
864
976
|
|
|
865
|
-
workspace.
|
|
977
|
+
workspace.pillNav.onSelect({ id: 'analysis', label: 'Run' })
|
|
866
978
|
expect(workspace.activeView.value).toBe('analysis')
|
|
867
979
|
expect(workspace.bindings.topBar.value.currentPillId).toBe('analysis')
|
|
868
|
-
expect(workspace.bindings.topBarTabs.value.currentTabId).toBe('analysis')
|
|
869
980
|
|
|
870
981
|
workspace.pillNav.onSelect({ id: 'results', label: 'Results' })
|
|
871
982
|
expect(workspace.activeView.value).toBe('results')
|
|
872
983
|
expect(workspace.sidebar.activeView).toBe('results')
|
|
873
|
-
expect(workspace.topBar.
|
|
984
|
+
expect(workspace.topBar.value.currentPillId).toBe('results')
|
|
874
985
|
expect(workspace.pillNav.currentItemId).toBe('results')
|
|
875
986
|
|
|
876
987
|
workspace.activeView.value = 'analysis'
|
|
877
988
|
await nextTick()
|
|
878
989
|
|
|
879
990
|
expect(workspace.sidebar.activeView).toBe('analysis')
|
|
880
|
-
expect(workspace.topBar.
|
|
991
|
+
expect(workspace.topBar.value.currentPillId).toBe('analysis')
|
|
881
992
|
expect(workspace.pillNav.currentItemId).toBe('analysis')
|
|
882
993
|
|
|
883
994
|
workspace.pillNav.currentItemId = 'results'
|
|
@@ -885,7 +996,7 @@ describe('useControlSchema', () => {
|
|
|
885
996
|
|
|
886
997
|
expect(workspace.activeView.value).toBe('results')
|
|
887
998
|
expect(workspace.sidebar.activeView).toBe('results')
|
|
888
|
-
expect(workspace.topBar.
|
|
999
|
+
expect(workspace.topBar.value.currentPillId).toBe('results')
|
|
889
1000
|
})
|
|
890
1001
|
|
|
891
1002
|
it('builds controls and component bindings for biology templates', () => {
|
|
@@ -900,6 +1011,8 @@ describe('useControlSchema', () => {
|
|
|
900
1011
|
expect(controlsToolkit.sidebarPanels.design.map(panel => panel.id)).toContain('dose')
|
|
901
1012
|
expect(componentsToolkit.bindings.map(binding => binding.component)).toContain('WellPlate')
|
|
902
1013
|
expect(componentsToolkit.imports[0].statement).toContain('DoseCalculator')
|
|
1014
|
+
expect(componentsToolkit.componentBindingsById['dose-response:DoseCalculator'].component).toBe('DoseCalculator')
|
|
1015
|
+
expect(componentsToolkit.componentBindingsById['dose-response:DoseCalculator'].props.mode).toBe('serial')
|
|
903
1016
|
expect(componentsToolkit.componentProps.map(binding => binding.component)).toContain('DoseCalculator')
|
|
904
1017
|
expect(componentsToolkit.componentPropsById['dose-response:DoseCalculator'].mode).toBe('serial')
|
|
905
1018
|
expect(componentsToolkit.componentPropsByComponent.WellPlate).toHaveLength(2)
|
|
@@ -910,6 +1023,7 @@ describe('useControlSchema', () => {
|
|
|
910
1023
|
const presetOnlyToolkit = useBioTemplateComponents('wellplate-screen')
|
|
911
1024
|
expect(presetOnlyToolkit.imports[0].statement).toContain('PlateMapEditor')
|
|
912
1025
|
expect(presetOnlyToolkit.componentProps).toEqual([])
|
|
1026
|
+
expect(presetOnlyToolkit.componentBindingsById).toEqual({})
|
|
913
1027
|
expect(presetOnlyToolkit.componentPropsById).toEqual({})
|
|
914
1028
|
expect(presetOnlyToolkit.componentPropsByComponent).toEqual({})
|
|
915
1029
|
expect(presetOnlyToolkit.getComponentProps('WellPlate')).toBeUndefined()
|