@morscherlab/mint-sdk 1.0.0-beta.2 → 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 +225 -6
- package/dist/__tests__/components/ActionItem.test.d.ts +1 -0
- package/dist/__tests__/components/AppAvatarMenu.test.d.ts +1 -0
- package/dist/__tests__/components/AppPageSelector.test.d.ts +1 -0
- package/dist/__tests__/components/AppPillNav.test.d.ts +1 -0
- package/dist/__tests__/components/AppPluginSwitcher.test.d.ts +1 -0
- package/dist/__tests__/components/AppToastContainer.test.d.ts +1 -0
- package/dist/__tests__/components/BaseRadioGroup.test.d.ts +1 -0
- package/dist/__tests__/components/BaseSelect.test.d.ts +1 -0
- package/dist/__tests__/components/BaseTabs.test.d.ts +1 -0
- package/dist/__tests__/components/BatchProgressList.test.d.ts +1 -0
- package/dist/__tests__/components/BioTemplateExperimentWorkspaceView.test.d.ts +1 -0
- package/dist/__tests__/components/BioTemplatePackWorkspaceView.test.d.ts +1 -0
- package/dist/__tests__/components/BioTemplatePresetWorkspaceView.test.d.ts +1 -0
- package/dist/__tests__/components/BioTemplateRenderer.test.d.ts +1 -0
- package/dist/__tests__/components/Breadcrumb.test.d.ts +1 -0
- package/dist/__tests__/components/CalendarGridPanel.test.d.ts +1 -0
- package/dist/__tests__/components/ComponentBindingRenderer.test.d.ts +1 -0
- package/dist/__tests__/components/ConcentrationInput.test.d.ts +1 -0
- package/dist/__tests__/components/ControlWorkspaceView.test.d.ts +1 -0
- package/dist/__tests__/components/DatePicker.test.d.ts +1 -0
- package/dist/__tests__/components/DateTimePicker.test.d.ts +1 -0
- package/dist/__tests__/components/DoseDesignWorkspaceView.test.d.ts +1 -0
- package/dist/__tests__/components/EmptyState.test.d.ts +1 -0
- package/dist/__tests__/components/ExperimentPopover.test.d.ts +1 -0
- package/dist/__tests__/components/FormBuilder.test.d.ts +1 -0
- package/dist/__tests__/components/GroupAssigner.test.d.ts +1 -0
- package/dist/__tests__/components/MultiSelect.test.d.ts +1 -0
- package/dist/__tests__/components/PluginWorkspaceView.test.d.ts +1 -0
- package/dist/__tests__/components/ProtocolStepEditor.test.d.ts +1 -0
- package/dist/__tests__/components/ReagentList.test.d.ts +1 -0
- package/dist/__tests__/components/SampleHierarchyTree.test.d.ts +1 -0
- package/dist/__tests__/components/SampleSelector.test.d.ts +1 -0
- package/dist/__tests__/components/SegmentedControl.test.d.ts +1 -0
- package/dist/__tests__/components/SettingsModal.test.d.ts +1 -0
- package/dist/__tests__/components/TagsInput.test.d.ts +1 -0
- package/dist/__tests__/components/ThemeToggle.test.d.ts +1 -0
- package/dist/__tests__/components/TimePicker.test.d.ts +1 -0
- package/dist/__tests__/composables/experiment-utils.test.d.ts +1 -0
- package/dist/__tests__/composables/useApi.test.d.ts +1 -0
- package/dist/__tests__/composables/useBioTemplatePackWorkspace.test.d.ts +1 -0
- package/dist/__tests__/composables/useBioTemplatePresetWorkspace.test.d.ts +1 -0
- package/dist/__tests__/composables/useBioTemplateWorkspace.test.d.ts +1 -0
- package/dist/__tests__/composables/useCalendarGrid.test.d.ts +1 -0
- package/dist/__tests__/composables/useControlSchema.test.d.ts +1 -0
- package/dist/__tests__/composables/useDebouncedWatch.test.d.ts +1 -0
- package/dist/__tests__/composables/useDropdownState.test.d.ts +1 -0
- package/dist/__tests__/composables/useEventListener.test.d.ts +1 -0
- package/dist/__tests__/composables/useExpansionSet.test.d.ts +1 -0
- package/dist/__tests__/composables/useExperimentData.test.d.ts +1 -0
- package/dist/__tests__/composables/useExperimentSelector.test.d.ts +1 -0
- package/dist/__tests__/composables/useGroupAssignment.test.d.ts +1 -0
- package/dist/__tests__/composables/useListSelection.test.d.ts +1 -0
- package/dist/__tests__/composables/usePluginClient.test.d.ts +1 -0
- package/dist/__tests__/composables/usePluginConfig.test.d.ts +1 -0
- package/dist/__tests__/composables/useRequestSyncState.test.d.ts +1 -0
- package/dist/__tests__/composables/useSampleGroups.test.d.ts +1 -0
- package/dist/__tests__/composables/useSelectionLimit.test.d.ts +1 -0
- package/dist/__tests__/composables/useSortedItems.test.d.ts +1 -0
- package/dist/__tests__/composables/useTemplateCollection.test.d.ts +1 -0
- package/dist/__tests__/composables/useTextSearch.test.d.ts +1 -0
- package/dist/__tests__/composables/useTheme.test.d.ts +1 -0
- package/dist/__tests__/composables/useTimeUtils.test.d.ts +1 -0
- package/dist/__tests__/docs/frontendDocsCatalog.test.d.ts +1 -0
- package/dist/__tests__/templates/templates.test.d.ts +1 -0
- package/dist/{auth-DsI0rQ7_.js → auth-QQj2kkze.js} +12 -5
- package/dist/auth-QQj2kkze.js.map +1 -0
- package/dist/components/AppAvatarMenu.vue.d.ts +2 -7
- 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 +111 -6
- package/dist/components/AppTopBar.vue.d.ts +35 -22
- package/dist/components/BaseButton.vue.d.ts +1 -1
- package/dist/components/BaseCheckbox.vue.d.ts +1 -1
- package/dist/components/BaseInput.vue.d.ts +2 -2
- package/dist/components/BasePill.vue.d.ts +2 -2
- package/dist/components/BaseRadioGroup.vue.d.ts +3 -3
- package/dist/components/BaseSelect.vue.d.ts +3 -3
- package/dist/components/BaseTabs.vue.d.ts +2 -2
- package/dist/components/BaseTextarea.vue.d.ts +1 -1
- package/dist/components/BaseToggle.vue.d.ts +1 -1
- package/dist/components/BioTemplateExperimentWorkspaceView.vue.d.ts +119 -0
- package/dist/components/BioTemplatePackWorkspaceView.vue.d.ts +93 -0
- package/dist/components/BioTemplatePresetWorkspaceView.vue.d.ts +87 -0
- package/dist/components/BioTemplateRenderer.vue.d.ts +29 -0
- package/dist/components/Breadcrumb.vue.d.ts +2 -2
- package/dist/components/Calendar.vue.d.ts +1 -1
- package/dist/components/CollapsibleCard.vue.d.ts +1 -1
- package/dist/components/ComponentBindingRenderer.vue.d.ts +44 -0
- package/dist/components/ConcentrationInput.vue.d.ts +2 -2
- package/dist/components/ConfirmDialog.vue.d.ts +2 -2
- package/dist/components/ControlWorkspaceView.vue.d.ts +147 -0
- package/dist/components/DatePicker.vue.d.ts +1 -1
- package/dist/components/DateTimePicker.vue.d.ts +3 -3
- package/dist/components/Divider.vue.d.ts +1 -1
- package/dist/components/DoseDesignWorkspaceView.vue.d.ts +149 -0
- package/dist/components/DropdownButton.vue.d.ts +3 -3
- package/dist/components/EmptyState.vue.d.ts +1 -2
- package/dist/components/ExperimentDataViewer.vue.d.ts +1 -1
- package/dist/components/ExperimentTimeline.vue.d.ts +2 -2
- package/dist/components/FileUploader.vue.d.ts +1 -1
- package/dist/components/FitPanel.vue.d.ts +1 -1
- package/dist/components/FormActions.vue.d.ts +4 -4
- package/dist/components/FormBuilder.vue.d.ts +31 -17
- package/dist/components/FormulaInput.vue.d.ts +2 -2
- package/dist/components/MoleculeInput.vue.d.ts +2 -2
- package/dist/components/MultiSelect.vue.d.ts +3 -3
- package/dist/components/NumberInput.vue.d.ts +1 -1
- package/dist/components/PlateMapEditor.vue.d.ts +1 -1
- package/dist/components/PluginWorkspaceView.vue.d.ts +310 -0
- package/dist/components/ProgressBar.vue.d.ts +1 -1
- package/dist/components/ProtocolStepEditor.vue.d.ts +3 -1
- package/dist/components/RackEditor.vue.d.ts +2 -2
- package/dist/components/SampleLegend.vue.d.ts +2 -2
- package/dist/components/ScheduleCalendar.vue.d.ts +2 -2
- package/dist/components/SegmentedControl.vue.d.ts +2 -2
- package/dist/components/SequenceInput.vue.d.ts +3 -3
- package/dist/components/SettingsModal.vue.d.ts +14 -6
- package/dist/components/StatusIndicator.vue.d.ts +1 -1
- package/dist/components/TagsInput.vue.d.ts +3 -2
- package/dist/components/TimePicker.vue.d.ts +3 -3
- package/dist/components/TimeRangeInput.vue.d.ts +1 -1
- package/dist/components/UnitInput.vue.d.ts +2 -2
- package/dist/components/WellPlate.vue.d.ts +6 -6
- package/dist/components/index.d.ts +9 -8
- package/dist/components/index.js +3 -3
- package/dist/components/{SettingsButton.vue.d.ts → internal/ActionItemInternal.vue.d.ts} +11 -9
- package/dist/components/{AppPageSelector.vue.d.ts → internal/AppPageSelectorInternal.vue.d.ts} +3 -6
- package/dist/components/{AppPillNav.vue.d.ts → internal/AppPillNavInternal.vue.d.ts} +4 -2
- package/dist/components/internal/CalendarGridPanelInternal.vue.d.ts +25 -0
- package/dist/components/{FormFieldRenderer.vue.d.ts → internal/FormFieldRendererInternal.vue.d.ts} +2 -2
- package/dist/components/{FormSection.vue.d.ts → internal/FormSectionRenderer.vue.d.ts} +7 -7
- package/dist/components/{WellEditPopup.vue.d.ts → internal/WellEditPopupInternal.vue.d.ts} +1 -1
- package/dist/{components-_XqPEhP9.js → components-BkGF4B4y.js} +9760 -8471
- package/dist/components-BkGF4B4y.js.map +1 -0
- package/dist/composables/experiment-utils.d.ts +8 -0
- package/dist/composables/index.d.ts +22 -5
- package/dist/composables/index.js +4 -3
- package/dist/composables/platformContextHelpers.d.ts +14 -0
- package/dist/composables/useAppExperiment.d.ts +31 -2
- package/dist/composables/useBioTemplateComponents.d.ts +22 -0
- package/dist/composables/useBioTemplateControls.d.ts +6 -0
- package/dist/composables/useBioTemplatePackWorkspace.d.ts +46 -0
- package/dist/composables/useBioTemplatePresetWorkspace.d.ts +75 -0
- package/dist/composables/useBioTemplateWorkspace.d.ts +51 -0
- package/dist/composables/useCalendarGrid.d.ts +26 -0
- package/dist/composables/useControlSchema.d.ts +343 -0
- package/dist/composables/useDebouncedWatch.d.ts +20 -0
- package/dist/composables/useDropdownState.d.ts +19 -0
- package/dist/composables/useEventListener.d.ts +13 -0
- package/dist/composables/useExpansionSet.d.ts +21 -0
- package/dist/composables/useExperimentData.d.ts +10 -0
- package/dist/composables/useExperimentSave.d.ts +31 -2
- package/dist/composables/useExperimentSelector.d.ts +20 -0
- package/dist/composables/useForm.d.ts +2 -0
- package/dist/composables/useGroupAssignment.d.ts +31 -0
- package/dist/composables/useListSelection.d.ts +35 -0
- package/dist/composables/usePlatformContext.d.ts +21 -3
- package/dist/composables/usePluginClient.d.ts +112 -0
- package/dist/composables/usePluginConfig.d.ts +12 -0
- package/dist/composables/useRequestSyncState.d.ts +34 -0
- package/dist/composables/useSampleGroups.d.ts +32 -0
- package/dist/composables/useSelectionLimit.d.ts +17 -0
- package/dist/composables/useSortedItems.d.ts +32 -0
- package/dist/composables/useTemplateCollection.d.ts +58 -0
- package/dist/composables/useTextSearch.d.ts +18 -0
- package/dist/composables/useTimeUtils.d.ts +8 -0
- package/dist/{composables-tiZqLu1M.js → composables-CHsME9H1.js} +240 -146
- package/dist/composables-CHsME9H1.js.map +1 -0
- package/dist/index.d.ts +6 -4
- package/dist/index.js +6 -5
- package/dist/install.d.ts +7 -2
- package/dist/install.js +2 -2
- package/dist/install.js.map +1 -1
- package/dist/stores/index.js +1 -1
- package/dist/stores/settings.d.ts +4 -1
- package/dist/styles.css +4746 -5514
- package/dist/templates/adapters.d.ts +43 -0
- package/dist/templates/builders.d.ts +63 -0
- package/dist/templates/catalog.d.ts +188 -0
- package/dist/templates/componentBindings.d.ts +71 -0
- package/dist/templates/controlSchemas.d.ts +25 -0
- package/dist/templates/index.d.ts +15 -0
- package/dist/templates/index.js +2 -0
- package/dist/templates/lookup.d.ts +4 -0
- package/dist/templates/packs.d.ts +18 -0
- package/dist/templates/presets.d.ts +90 -0
- package/dist/templates/types.d.ts +531 -0
- package/dist/templates-B5jmTWuk.js +9388 -0
- package/dist/templates-B5jmTWuk.js.map +1 -0
- package/dist/types/components.d.ts +26 -23
- package/dist/types/form-builder.d.ts +6 -8
- package/dist/types/index.d.ts +2 -2
- package/dist/types/platform.d.ts +7 -1
- package/dist/useScheduleDrag-BgzpQT53.js +4414 -0
- package/dist/useScheduleDrag-BgzpQT53.js.map +1 -0
- package/dist/utils/formModelSync.d.ts +5 -0
- package/dist/utils/items.d.ts +8 -0
- package/dist/utils/options.d.ts +6 -0
- package/dist/utils/pluginIcon.d.ts +9 -0
- package/package.json +7 -2
- package/src/__tests__/components/ActionItem.test.ts +99 -0
- package/src/__tests__/components/AppAvatarMenu.test.ts +27 -0
- package/src/__tests__/components/AppLayout.test.ts +44 -0
- package/src/__tests__/components/AppPageSelector.test.ts +134 -0
- package/src/__tests__/components/AppPillNav.test.ts +125 -0
- package/src/__tests__/components/AppPluginSwitcher.test.ts +44 -0
- package/src/__tests__/components/AppSidebar.test.ts +496 -0
- package/src/__tests__/components/AppToastContainer.test.ts +37 -0
- package/src/__tests__/components/AppTopBar.test.ts +455 -9
- package/src/__tests__/components/BaseRadioGroup.test.ts +25 -0
- package/src/__tests__/components/BaseSelect.test.ts +21 -0
- package/src/__tests__/components/BaseTabs.test.ts +25 -0
- package/src/__tests__/components/BatchProgressList.test.ts +52 -0
- package/src/__tests__/components/BioTemplateExperimentWorkspaceView.test.ts +159 -0
- package/src/__tests__/components/BioTemplatePackWorkspaceView.test.ts +175 -0
- package/src/__tests__/components/BioTemplatePresetWorkspaceView.test.ts +306 -0
- package/src/__tests__/components/BioTemplateRenderer.test.ts +71 -0
- package/src/__tests__/components/Breadcrumb.test.ts +23 -0
- package/src/__tests__/components/CalendarGridPanel.test.ts +36 -0
- package/src/__tests__/components/ComponentBindingRenderer.test.ts +161 -0
- package/src/__tests__/components/ConcentrationInput.test.ts +45 -0
- package/src/__tests__/components/ControlWorkspaceView.test.ts +1102 -0
- package/src/__tests__/components/DataFrame.test.ts +11 -0
- package/src/__tests__/components/DatePicker.test.ts +45 -0
- package/src/__tests__/components/DateTimePicker.test.ts +48 -0
- package/src/__tests__/components/DoseDesignWorkspaceView.test.ts +185 -0
- package/src/__tests__/components/DropdownButton.test.ts +23 -0
- package/src/__tests__/components/EmptyState.test.ts +23 -0
- package/src/__tests__/components/ExperimentPopover.test.ts +56 -0
- package/src/__tests__/components/FormBuilder.test.ts +296 -0
- package/src/__tests__/components/GroupAssigner.test.ts +30 -0
- package/src/__tests__/components/MultiSelect.test.ts +48 -0
- package/src/__tests__/components/PluginWorkspaceView.test.ts +548 -0
- package/src/__tests__/components/ProtocolStepEditor.test.ts +33 -0
- package/src/__tests__/components/ReagentList.test.ts +82 -0
- package/src/__tests__/components/SampleHierarchyTree.test.ts +53 -0
- package/src/__tests__/components/SampleSelector.test.ts +60 -0
- package/src/__tests__/components/SegmentedControl.test.ts +24 -0
- package/src/__tests__/components/SettingsModal.test.ts +296 -0
- package/src/__tests__/components/TagsInput.test.ts +75 -0
- package/src/__tests__/components/ThemeToggle.test.ts +47 -0
- package/src/__tests__/components/TimePicker.test.ts +38 -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 +125 -0
- package/src/__tests__/composables/useBioTemplatePresetWorkspace.test.ts +199 -0
- package/src/__tests__/composables/useBioTemplateWorkspace.test.ts +104 -0
- package/src/__tests__/composables/useCalendarGrid.test.ts +38 -0
- package/src/__tests__/composables/useControlSchema.test.ts +1033 -0
- package/src/__tests__/composables/useDebouncedWatch.test.ts +93 -0
- package/src/__tests__/composables/useDropdownState.test.ts +95 -0
- package/src/__tests__/composables/useEventListener.test.ts +116 -0
- package/src/__tests__/composables/useExpansionSet.test.ts +62 -0
- package/src/__tests__/composables/useExperimentData.test.ts +4 -0
- package/src/__tests__/composables/useExperimentSave.test.ts +203 -8
- package/src/__tests__/composables/useExperimentSelector.test.ts +164 -0
- package/src/__tests__/composables/useForm.test.ts +58 -0
- package/src/__tests__/composables/useFormBuilder.test.ts +77 -0
- package/src/__tests__/composables/useGroupAssignment.test.ts +73 -0
- package/src/__tests__/composables/useListSelection.test.ts +66 -0
- package/src/__tests__/composables/usePluginClient.test.ts +541 -0
- package/src/__tests__/composables/usePluginConfig.test.ts +5 -0
- package/src/__tests__/composables/useRequestSyncState.test.ts +92 -0
- package/src/__tests__/composables/useSampleGroups.test.ts +66 -0
- package/src/__tests__/composables/useSelectionLimit.test.ts +41 -0
- package/src/__tests__/composables/useSortedItems.test.ts +87 -0
- package/src/__tests__/composables/useTemplateCollection.test.ts +147 -0
- package/src/__tests__/composables/useTextSearch.test.ts +55 -0
- package/src/__tests__/composables/useTheme.test.ts +91 -0
- package/src/__tests__/composables/useTimeUtils.test.ts +35 -0
- package/src/__tests__/docs/frontendDocsCatalog.test.ts +324 -0
- package/src/__tests__/fixtures/templates/dose-response.json +81 -0
- package/src/__tests__/fixtures/templates/plate-map.json +54 -0
- package/src/__tests__/fixtures/templates/qpcr-plate.json +96 -0
- package/src/__tests__/fixtures/templates/sample-sheet.json +71 -0
- package/src/__tests__/templates/templates.test.ts +1055 -0
- package/src/components/AppAvatarMenu.vue +15 -69
- package/src/components/AppLayout.story.vue +64 -25
- package/src/components/AppLayout.vue +83 -2
- package/src/components/AppPluginSwitcher.vue +41 -145
- package/src/components/AppSidebar.story.vue +203 -1
- package/src/components/AppSidebar.vue +320 -25
- package/src/components/{ToastNotification.story.vue → AppToastContainer.story.vue} +6 -6
- package/src/components/{ToastNotification.vue → AppToastContainer.vue} +1 -1
- package/src/components/AppTopBar.story.vue +7 -33
- package/src/components/AppTopBar.vue +104 -300
- package/src/components/BaseModal.vue +3 -5
- package/src/components/BaseRadioGroup.vue +7 -3
- package/src/components/BaseSelect.vue +11 -7
- package/src/components/BaseTabs.vue +6 -4
- package/src/components/BatchProgressList.vue +5 -8
- package/src/components/BioTemplateExperimentWorkspaceView.story.vue +123 -0
- package/src/components/BioTemplateExperimentWorkspaceView.vue +343 -0
- package/src/components/BioTemplatePackWorkspaceView.story.vue +107 -0
- package/src/components/BioTemplatePackWorkspaceView.vue +177 -0
- package/src/components/BioTemplatePresetWorkspaceView.story.vue +163 -0
- package/src/components/BioTemplatePresetWorkspaceView.vue +401 -0
- package/src/components/BioTemplateRenderer.story.vue +57 -0
- package/src/components/BioTemplateRenderer.vue +57 -0
- package/src/components/Breadcrumb.vue +14 -8
- package/src/components/ComponentBindingRenderer.story.vue +57 -0
- package/src/components/ComponentBindingRenderer.vue +308 -0
- package/src/components/ConcentrationInput.vue +27 -64
- package/src/components/ControlWorkspaceView.story.vue +347 -0
- package/src/components/ControlWorkspaceView.vue +378 -0
- package/src/components/DataFrame.vue +34 -50
- package/src/components/DatePicker.vue +59 -192
- package/src/components/DateTimePicker.vue +50 -171
- package/src/components/DoseDesignWorkspaceView.story.vue +77 -0
- package/src/components/DoseDesignWorkspaceView.vue +255 -0
- package/src/components/DropdownButton.vue +14 -32
- package/src/components/EmptyState.vue +4 -2
- package/src/components/ExperimentPopover.vue +7 -28
- package/src/components/ExperimentSelectorModal.vue +6 -5
- package/src/components/FormBuilder.story.vue +190 -0
- package/src/components/FormBuilder.vue +124 -27
- package/src/components/GroupAssigner.vue +24 -56
- package/src/components/MultiSelect.vue +17 -12
- package/src/components/PlateMapEditor.vue +3 -8
- package/src/components/PluginIcon.vue +2 -22
- package/src/components/PluginWorkspaceView.story.vue +334 -0
- package/src/components/PluginWorkspaceView.vue +708 -0
- package/src/components/ProtocolStepEditor.vue +13 -22
- package/src/components/ReagentList.vue +25 -33
- package/src/components/SampleHierarchyTree.vue +12 -23
- package/src/components/SampleSelector.vue +42 -122
- package/src/components/SegmentedControl.vue +7 -3
- package/src/components/SettingsModal.story.vue +88 -1
- package/src/components/SettingsModal.vue +120 -29
- package/src/components/TagsInput.vue +29 -14
- package/src/components/ThemeToggle.vue +9 -7
- package/src/components/TimePicker.vue +19 -41
- package/src/components/Tooltip.vue +7 -12
- package/src/components/WellPlate.vue +6 -12
- package/src/components/index.ts +9 -8
- package/src/components/internal/ActionItemInternal.vue +82 -0
- package/src/components/internal/AppPageSelectorInternal.vue +128 -0
- package/src/components/internal/AppPillNavInternal.vue +194 -0
- package/src/components/internal/CalendarGridPanelInternal.vue +120 -0
- package/src/components/{FormFieldRenderer.vue → internal/FormFieldRendererInternal.vue} +4 -12
- package/src/components/{FormSection.vue → internal/FormSectionRenderer.vue} +6 -18
- package/src/components/{WellEditPopup.vue → internal/WellEditPopupInternal.vue} +5 -10
- package/src/composables/experiment-utils.ts +26 -0
- package/src/composables/index.ts +229 -3
- package/src/composables/platformContextHelpers.ts +74 -0
- package/src/composables/useApi.ts +9 -2
- package/src/composables/useAppExperiment.ts +85 -13
- package/src/composables/useBioTemplateComponents.ts +105 -0
- package/src/composables/useBioTemplateControls.ts +41 -0
- package/src/composables/useBioTemplatePackWorkspace.ts +185 -0
- package/src/composables/useBioTemplatePresetWorkspace.ts +326 -0
- package/src/composables/useBioTemplateWorkspace.ts +141 -0
- package/src/composables/useCalendarGrid.ts +140 -0
- package/src/composables/useControlSchema.ts +1362 -0
- package/src/composables/useDebouncedWatch.ts +119 -0
- package/src/composables/useDropdownState.ts +83 -0
- package/src/composables/useEventListener.ts +111 -0
- package/src/composables/useExpansionSet.ts +117 -0
- package/src/composables/useExperimentData.ts +20 -11
- package/src/composables/useExperimentSave.ts +202 -50
- package/src/composables/useExperimentSelector.ts +86 -72
- package/src/composables/useForm.ts +49 -4
- package/src/composables/useFormBuilder.ts +93 -42
- package/src/composables/useGroupAssignment.ts +148 -0
- package/src/composables/useListSelection.ts +158 -0
- package/src/composables/usePluginClient.ts +466 -0
- package/src/composables/usePluginConfig.ts +34 -13
- package/src/composables/useRequestSyncState.ts +126 -0
- package/src/composables/useSampleGroups.ts +126 -0
- package/src/composables/useSelectionLimit.ts +57 -0
- package/src/composables/useSortedItems.ts +118 -0
- package/src/composables/useTemplateCollection.ts +229 -0
- package/src/composables/useTextSearch.ts +60 -0
- package/src/composables/useTheme.ts +2 -28
- package/src/composables/useTimeUtils.ts +26 -2
- package/src/composables/useWellPlateEditor.ts +13 -9
- package/src/index.ts +11 -348
- package/src/install.ts +11 -4
- package/src/stores/settings.ts +13 -9
- package/src/styles/components/app-layout.css +82 -0
- package/src/styles/components/app-page-selector.css +23 -0
- package/src/styles/components/app-pill-nav.css +77 -0
- package/src/styles/components/app-sidebar.css +119 -0
- package/src/styles/components/app-top-bar.css +0 -201
- package/src/styles/components/concentration-input.css +3 -142
- package/src/styles/components/empty-state.css +0 -16
- package/src/styles/components/theme-toggle.css +3 -66
- package/src/styles/index.css +0 -2
- package/src/templates/adapters.ts +785 -0
- package/src/templates/builders.ts +2149 -0
- package/src/templates/catalog.ts +245 -0
- package/src/templates/componentBindings.ts +653 -0
- package/src/templates/controlSchemas.ts +718 -0
- package/src/templates/index.ts +318 -0
- package/src/templates/lookup.ts +18 -0
- package/src/templates/packs.ts +156 -0
- package/src/templates/presets.ts +146 -0
- package/src/templates/types.ts +668 -0
- package/src/types/components.ts +39 -27
- package/src/types/form-builder.ts +7 -2
- package/src/types/index.ts +13 -3
- package/src/types/platform.ts +7 -1
- package/src/utils/formModelSync.ts +52 -0
- package/src/utils/items.ts +28 -0
- package/src/utils/options.ts +23 -0
- package/src/utils/pluginIcon.ts +30 -0
- package/dist/__tests__/composables/usePluginApi.test.d.ts +0 -13
- package/dist/auth-DsI0rQ7_.js.map +0 -1
- package/dist/components/GroupingModal.vue.d.ts +0 -12
- package/dist/components-_XqPEhP9.js.map +0 -1
- package/dist/composables/usePluginApi.d.ts +0 -29
- package/dist/composables-tiZqLu1M.js.map +0 -1
- package/dist/useScheduleDrag-CA9sGNJG.js +0 -7181
- package/dist/useScheduleDrag-CA9sGNJG.js.map +0 -1
- package/src/__tests__/composables/usePluginApi.test.ts +0 -81
- package/src/components/AppPageSelector.vue +0 -159
- package/src/components/AppPillNav.vue +0 -66
- package/src/components/GroupingModal.story.vue +0 -52
- package/src/components/GroupingModal.vue +0 -422
- package/src/components/SettingsButton.story.vue +0 -58
- package/src/components/SettingsButton.vue +0 -76
- package/src/composables/usePluginApi.ts +0 -39
- package/src/styles/components/grouping-modal.css +0 -323
- package/src/styles/components/settings-button.css +0 -94
- /package/dist/components/{ToastNotification.vue.d.ts → AppToastContainer.vue.d.ts} +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { ref, watch, computed
|
|
3
|
-
import type { Well, WellEditData, WellEditField } from '
|
|
2
|
+
import { ref, watch, computed } from 'vue'
|
|
3
|
+
import type { Well, WellEditData, WellEditField } from '../../types'
|
|
4
|
+
import { useEventListener } from '../../composables/useEventListener'
|
|
4
5
|
|
|
5
6
|
interface Props {
|
|
6
7
|
wellId: string
|
|
@@ -83,13 +84,7 @@ function handleKeydown(e: KeyboardEvent) {
|
|
|
83
84
|
if (e.key === 'Escape') close()
|
|
84
85
|
}
|
|
85
86
|
|
|
86
|
-
|
|
87
|
-
document.addEventListener('keydown', handleKeydown)
|
|
88
|
-
})
|
|
89
|
-
|
|
90
|
-
onUnmounted(() => {
|
|
91
|
-
document.removeEventListener('keydown', handleKeydown)
|
|
92
|
-
})
|
|
87
|
+
useEventListener(() => document, 'keydown', handleKeydown)
|
|
93
88
|
|
|
94
89
|
const sampleTypeButtons = [
|
|
95
90
|
{ type: 'sample', label: 'S', tooltip: 'Sample' },
|
|
@@ -230,5 +225,5 @@ const sampleTypeButtons = [
|
|
|
230
225
|
</template>
|
|
231
226
|
|
|
232
227
|
<style>
|
|
233
|
-
@import '
|
|
228
|
+
@import '../../styles/components/well-edit-popup.css';
|
|
234
229
|
</style>
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import type { DatePreset, ExperimentStatus, SelectOption, PillVariant } from '../types'
|
|
2
2
|
|
|
3
|
+
interface ExperimentCodeSource {
|
|
4
|
+
id?: number | null
|
|
5
|
+
experiment_code?: string | null
|
|
6
|
+
}
|
|
7
|
+
|
|
3
8
|
export function formatExperimentDate(dateStr: string): string {
|
|
4
9
|
try {
|
|
5
10
|
return new Date(dateStr).toLocaleDateString(undefined, {
|
|
@@ -41,6 +46,27 @@ export const EXPERIMENT_STATUS_LABELS: Record<ExperimentStatus, string> = {
|
|
|
41
46
|
cancelled: 'Cancelled',
|
|
42
47
|
}
|
|
43
48
|
|
|
49
|
+
export function formatExperimentStatus(status?: ExperimentStatus | string | null): string {
|
|
50
|
+
if (!status) return ''
|
|
51
|
+
if (status in EXPERIMENT_STATUS_LABELS) {
|
|
52
|
+
return EXPERIMENT_STATUS_LABELS[status as ExperimentStatus]
|
|
53
|
+
}
|
|
54
|
+
const label = String(status).replace(/[-_]+/g, ' ').trim()
|
|
55
|
+
return label ? label.replace(/^\w/, c => c.toUpperCase()) : ''
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function getExperimentStatusVariant(status?: ExperimentStatus | string | null): PillVariant {
|
|
59
|
+
if (status && status in EXPERIMENT_STATUS_VARIANT_MAP) {
|
|
60
|
+
return EXPERIMENT_STATUS_VARIANT_MAP[status as ExperimentStatus]
|
|
61
|
+
}
|
|
62
|
+
return 'default'
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function resolveExperimentCode(experiment: ExperimentCodeSource): string | undefined {
|
|
66
|
+
if (experiment.experiment_code) return experiment.experiment_code
|
|
67
|
+
return experiment.id != null ? `EXP-${experiment.id}` : undefined
|
|
68
|
+
}
|
|
69
|
+
|
|
44
70
|
export const DATE_PRESET_OPTIONS: SelectOption<string>[] = [
|
|
45
71
|
{ value: '', label: 'Any time' },
|
|
46
72
|
{ value: 'last_7_days', label: 'Last 7 days' },
|
package/src/composables/index.ts
CHANGED
|
@@ -43,6 +43,7 @@ export {
|
|
|
43
43
|
type SerialDilutionParams,
|
|
44
44
|
type SerialDilutionStep,
|
|
45
45
|
type SerialDilutionResult,
|
|
46
|
+
type ConversionResult,
|
|
46
47
|
type WellConcentration,
|
|
47
48
|
type UseDoseCalculatorReturn,
|
|
48
49
|
} from './useDoseCalculator'
|
|
@@ -75,6 +76,7 @@ export {
|
|
|
75
76
|
useTimeUtils,
|
|
76
77
|
parseTime,
|
|
77
78
|
formatTime,
|
|
79
|
+
formatTimeSlot,
|
|
78
80
|
generateTimeSlots,
|
|
79
81
|
rangesOverlap,
|
|
80
82
|
durationMinutes,
|
|
@@ -84,8 +86,30 @@ export {
|
|
|
84
86
|
snapToSlot,
|
|
85
87
|
addMinutes,
|
|
86
88
|
compareTime,
|
|
89
|
+
findNearestTimeSlotIndex,
|
|
90
|
+
toMinutes,
|
|
91
|
+
fromMinutes,
|
|
87
92
|
} from './useTimeUtils'
|
|
88
93
|
export { useScheduleDrag } from './useScheduleDrag'
|
|
94
|
+
export {
|
|
95
|
+
useEventListener,
|
|
96
|
+
type EventListenerEnabled,
|
|
97
|
+
type EventFor,
|
|
98
|
+
type EventListenerStop,
|
|
99
|
+
type EventMapFor,
|
|
100
|
+
type EventTargetGetter,
|
|
101
|
+
type EventTargetLike,
|
|
102
|
+
type UseEventListenerObjectOptions,
|
|
103
|
+
type UseEventListenerOptions,
|
|
104
|
+
} from './useEventListener'
|
|
105
|
+
export {
|
|
106
|
+
useDebouncedWatch,
|
|
107
|
+
type DebouncedWatchCallback,
|
|
108
|
+
type DebouncedWatchCleanup,
|
|
109
|
+
type DebouncedWatchSource,
|
|
110
|
+
type UseDebouncedWatchOptions,
|
|
111
|
+
type UseDebouncedWatchReturn,
|
|
112
|
+
} from './useDebouncedWatch'
|
|
89
113
|
export { useFormBuilder, evaluateCondition } from './useFormBuilder'
|
|
90
114
|
export { useAutoGroup, DEFAULT_COLORS, extractSamplesFromDesignData } from './useAutoGroup'
|
|
91
115
|
export {
|
|
@@ -105,6 +129,9 @@ export {
|
|
|
105
129
|
} from './useExperimentSelector'
|
|
106
130
|
export {
|
|
107
131
|
formatExperimentDate,
|
|
132
|
+
formatExperimentStatus,
|
|
133
|
+
getExperimentStatusVariant,
|
|
134
|
+
resolveExperimentCode,
|
|
108
135
|
datePresetToISO,
|
|
109
136
|
EXPERIMENT_STATUS_OPTIONS,
|
|
110
137
|
EXPERIMENT_STATUS_VARIANT_MAP,
|
|
@@ -125,9 +152,13 @@ export {
|
|
|
125
152
|
export {
|
|
126
153
|
useAppExperiment,
|
|
127
154
|
APP_EXPERIMENT_KEY,
|
|
155
|
+
type AppExperimentRecord,
|
|
156
|
+
type AppExperimentSource,
|
|
128
157
|
type UseAppExperimentOptions,
|
|
129
158
|
type UseAppExperimentReturn,
|
|
130
159
|
type AppExperimentState,
|
|
160
|
+
type AppExperimentPopoverBinding,
|
|
161
|
+
type AppExperimentSelectorModalBinding,
|
|
131
162
|
} from './useAppExperiment'
|
|
132
163
|
export {
|
|
133
164
|
useExperimentSave,
|
|
@@ -135,6 +166,201 @@ export {
|
|
|
135
166
|
type UseExperimentSaveReturn,
|
|
136
167
|
} from './useExperimentSave'
|
|
137
168
|
export {
|
|
138
|
-
|
|
139
|
-
type
|
|
140
|
-
|
|
169
|
+
useTemplateCollection,
|
|
170
|
+
type TemplateCollectionInput,
|
|
171
|
+
type UseTemplateCollectionOptions,
|
|
172
|
+
type UseTemplateCollectionReturn,
|
|
173
|
+
} from './useTemplateCollection'
|
|
174
|
+
export {
|
|
175
|
+
useRequestSyncState,
|
|
176
|
+
type RequestSyncRunOptions,
|
|
177
|
+
type RequestSyncSuccessKind,
|
|
178
|
+
type UseRequestSyncStateReturn,
|
|
179
|
+
} from './useRequestSyncState'
|
|
180
|
+
export {
|
|
181
|
+
useSelectionLimit,
|
|
182
|
+
type SelectionLimitSource,
|
|
183
|
+
type UseSelectionLimitOptions,
|
|
184
|
+
type UseSelectionLimitReturn,
|
|
185
|
+
} from './useSelectionLimit'
|
|
186
|
+
export {
|
|
187
|
+
useListSelection,
|
|
188
|
+
type ListSelectionSource,
|
|
189
|
+
type ListSelectionValue,
|
|
190
|
+
type UseListSelectionOptions,
|
|
191
|
+
type UseListSelectionReturn,
|
|
192
|
+
type WidenListSelectionValue,
|
|
193
|
+
} from './useListSelection'
|
|
194
|
+
export {
|
|
195
|
+
useGroupAssignment,
|
|
196
|
+
type GroupAssignmentSource,
|
|
197
|
+
type GroupAssignmentState,
|
|
198
|
+
type GroupAssignmentZone,
|
|
199
|
+
type UseGroupAssignmentOptions,
|
|
200
|
+
type UseGroupAssignmentReturn,
|
|
201
|
+
} from './useGroupAssignment'
|
|
202
|
+
export {
|
|
203
|
+
useSampleGroups,
|
|
204
|
+
type DisplaySampleSubGroup,
|
|
205
|
+
type SampleGroupSource,
|
|
206
|
+
type SampleMajorGroup,
|
|
207
|
+
type UseSampleGroupsOptions,
|
|
208
|
+
type UseSampleGroupsReturn,
|
|
209
|
+
} from './useSampleGroups'
|
|
210
|
+
export {
|
|
211
|
+
useExpansionSet,
|
|
212
|
+
type ExpansionSetSource,
|
|
213
|
+
type UseExpansionSetOptions,
|
|
214
|
+
type UseExpansionSetReturn,
|
|
215
|
+
} from './useExpansionSet'
|
|
216
|
+
export {
|
|
217
|
+
compareSortValues,
|
|
218
|
+
useSortedItems,
|
|
219
|
+
type CompareSortValuesOptions,
|
|
220
|
+
type SortComparator,
|
|
221
|
+
type SortComparatorContext,
|
|
222
|
+
type SortDescriptor,
|
|
223
|
+
type SortedItemsSource,
|
|
224
|
+
type SortOrder,
|
|
225
|
+
type UseSortedItemsOptions,
|
|
226
|
+
type UseSortedItemsReturn,
|
|
227
|
+
} from './useSortedItems'
|
|
228
|
+
export {
|
|
229
|
+
candidateMatchesSearch,
|
|
230
|
+
normalizeSearchQuery,
|
|
231
|
+
useTextSearch,
|
|
232
|
+
type TextSearchCandidate,
|
|
233
|
+
type TextSearchSource,
|
|
234
|
+
type UseTextSearchOptions,
|
|
235
|
+
type UseTextSearchReturn,
|
|
236
|
+
} from './useTextSearch'
|
|
237
|
+
export {
|
|
238
|
+
controlsToFormSchema,
|
|
239
|
+
controlsToSectionFormSchema,
|
|
240
|
+
controlsToSectionFormSchemas,
|
|
241
|
+
controlsToSidebarPanels,
|
|
242
|
+
controlsToSettingsSchema,
|
|
243
|
+
controlsToTopBarSettingsConfig,
|
|
244
|
+
controlsToViewIds,
|
|
245
|
+
controlsToViewItems,
|
|
246
|
+
controlValuesToComponentBindings,
|
|
247
|
+
controlValuesToComponentBindingsById,
|
|
248
|
+
controlValuesToComponentProps,
|
|
249
|
+
defineControlComponentBindings,
|
|
250
|
+
defineControlModel,
|
|
251
|
+
defineDoseDesignControlModel,
|
|
252
|
+
defineDoseCalculatorControlProps,
|
|
253
|
+
defineControls,
|
|
254
|
+
defineWellPlateControlProps,
|
|
255
|
+
defineWellPlateDoseComponentBindings,
|
|
256
|
+
defineWellPlateDoseControlProps,
|
|
257
|
+
getDefaultControlView,
|
|
258
|
+
getControlDefaults,
|
|
259
|
+
useControlSchema,
|
|
260
|
+
useControlWorkspace,
|
|
261
|
+
type ControlDefinition,
|
|
262
|
+
type ControlComponentBinding,
|
|
263
|
+
type ControlComponentBindingConfig,
|
|
264
|
+
type ControlComponentBindingRecordConfig,
|
|
265
|
+
type ControlComponentBindingsById,
|
|
266
|
+
type ControlComponentBindingsConfig,
|
|
267
|
+
type ControlComponentPropSource,
|
|
268
|
+
type ControlComponentPropsByIdMap,
|
|
269
|
+
type ControlComponentPropsMap,
|
|
270
|
+
type DoseDesignControlModelOptions,
|
|
271
|
+
type DoseCalculatorControlPropsOptions,
|
|
272
|
+
type ControlFormSchema,
|
|
273
|
+
type ControlInput,
|
|
274
|
+
type ControlModel,
|
|
275
|
+
type ControlModelBinding,
|
|
276
|
+
type ControlModelSectionConfig,
|
|
277
|
+
type ControlModelViewConfig,
|
|
278
|
+
type ControlOption,
|
|
279
|
+
type ControlOptionValue,
|
|
280
|
+
type ControlPrimitive,
|
|
281
|
+
type ControlSchema,
|
|
282
|
+
type ControlSchemaOptions,
|
|
283
|
+
type ControlShorthand,
|
|
284
|
+
type ControlWorkspaceOptions,
|
|
285
|
+
type ControlFormBinding,
|
|
286
|
+
type ControlSettingsBinding,
|
|
287
|
+
type ControlSidebarBinding,
|
|
288
|
+
type ControlSectionConfig,
|
|
289
|
+
type ControlSidebarConfig,
|
|
290
|
+
type ControlTopBarSettingsBinding,
|
|
291
|
+
type ControlViewConfig,
|
|
292
|
+
type ControlValues,
|
|
293
|
+
type UseControlSchemaReturn,
|
|
294
|
+
type ControlWorkspaceAppTopBarPillBinding,
|
|
295
|
+
type ControlWorkspaceComponentBindings,
|
|
296
|
+
type ControlWorkspaceFormBinding,
|
|
297
|
+
type ControlWorkspacePillNavBinding,
|
|
298
|
+
type ControlWorkspaceSidebarBinding,
|
|
299
|
+
type ControlWorkspaceTopBarBinding,
|
|
300
|
+
type ControlWorkspaceTopBarSettingsBinding,
|
|
301
|
+
type UseControlWorkspaceReturn,
|
|
302
|
+
type WellPlateControlPropsOptions,
|
|
303
|
+
type WellPlateDoseControlPropsOptions,
|
|
304
|
+
} from './useControlSchema'
|
|
305
|
+
export {
|
|
306
|
+
getBioTemplateControlSchema,
|
|
307
|
+
requireBioTemplateControlSchema,
|
|
308
|
+
useBioTemplateControls,
|
|
309
|
+
type BioTemplateControlSchema,
|
|
310
|
+
type BioTemplateControlTarget,
|
|
311
|
+
} from './useBioTemplateControls'
|
|
312
|
+
export {
|
|
313
|
+
getBioTemplateComponentProps,
|
|
314
|
+
getBioTemplateComponentBindings,
|
|
315
|
+
toBioTemplateComponentBindings,
|
|
316
|
+
toBioTemplateComponentBindingsById,
|
|
317
|
+
toBioTemplateComponentProps,
|
|
318
|
+
toBioTemplateComponentPropsByComponent,
|
|
319
|
+
toBioTemplateComponentPropsById,
|
|
320
|
+
useBioTemplateComponents,
|
|
321
|
+
type BioTemplateComponentBinding,
|
|
322
|
+
type BioTemplateComponentBindingsById,
|
|
323
|
+
type BioTemplateComponentPropsByComponent,
|
|
324
|
+
type BioTemplateComponentPropsBinding,
|
|
325
|
+
type BioTemplateComponentPropsById,
|
|
326
|
+
type BioTemplateComponentPropsLookupOptions,
|
|
327
|
+
type BioTemplateResolvedComponentBinding,
|
|
328
|
+
type BioTemplateComponentTarget,
|
|
329
|
+
type UseBioTemplateComponentsReturn,
|
|
330
|
+
} from './useBioTemplateComponents'
|
|
331
|
+
export {
|
|
332
|
+
useBioTemplateWorkspace,
|
|
333
|
+
type BioTemplateRendererBinding,
|
|
334
|
+
type BioTemplateWorkspaceBindings,
|
|
335
|
+
type BioTemplateWorkspaceTarget,
|
|
336
|
+
type UseBioTemplateWorkspaceReturn,
|
|
337
|
+
} from './useBioTemplateWorkspace'
|
|
338
|
+
export {
|
|
339
|
+
useBioTemplatePresetWorkspace,
|
|
340
|
+
type BioTemplatePresetWorkspaceBindings,
|
|
341
|
+
type UseBioTemplatePresetWorkspaceOptions,
|
|
342
|
+
type UseBioTemplatePresetWorkspaceReturn,
|
|
343
|
+
} from './useBioTemplatePresetWorkspace'
|
|
344
|
+
export {
|
|
345
|
+
useBioTemplatePackWorkspace,
|
|
346
|
+
type UseBioTemplatePackWorkspaceOptions,
|
|
347
|
+
type UseBioTemplatePackWorkspaceReturn,
|
|
348
|
+
} from './useBioTemplatePackWorkspace'
|
|
349
|
+
export {
|
|
350
|
+
buildPluginEndpointUrl,
|
|
351
|
+
createPluginClient,
|
|
352
|
+
getPluginPageSelectorItems,
|
|
353
|
+
resolvePluginBaseUrl,
|
|
354
|
+
usePluginClient,
|
|
355
|
+
usePluginSettings,
|
|
356
|
+
useCurrentExperiment,
|
|
357
|
+
type BuildPluginEndpointUrlOptions,
|
|
358
|
+
type PluginContract,
|
|
359
|
+
type PluginEndpointContract,
|
|
360
|
+
type PluginEndpointDefinition,
|
|
361
|
+
type PluginHttpMethod,
|
|
362
|
+
type PluginNavItemContract,
|
|
363
|
+
type CreatePluginClientOptions,
|
|
364
|
+
type UseCurrentExperimentOptions,
|
|
365
|
+
type UseCurrentExperimentReturn,
|
|
366
|
+
} from './usePluginClient'
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { PlatformContext } from '../types'
|
|
2
|
+
|
|
3
|
+
export type ExperimentAwarePlatformContext = PlatformContext & {
|
|
4
|
+
currentExperiment?: unknown
|
|
5
|
+
currentExperimentId?: unknown
|
|
6
|
+
experiment?: unknown
|
|
7
|
+
experimentId?: unknown
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function getInjectedPlatformContext(): PlatformContext | undefined {
|
|
11
|
+
if (typeof window === 'undefined') return undefined
|
|
12
|
+
return (window as unknown as { __MINT_PLATFORM__?: PlatformContext }).__MINT_PLATFORM__
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function getInjectedExperimentContext(): ExperimentAwarePlatformContext | undefined {
|
|
16
|
+
return getInjectedPlatformContext() as ExperimentAwarePlatformContext | undefined
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function currentExperimentFromContext<TExperiment>(
|
|
20
|
+
context: ExperimentAwarePlatformContext | undefined = getInjectedExperimentContext(),
|
|
21
|
+
): TExperiment | undefined {
|
|
22
|
+
const candidate = context?.currentExperiment ?? context?.experiment
|
|
23
|
+
return candidate && typeof candidate === 'object'
|
|
24
|
+
? candidate as TExperiment
|
|
25
|
+
: undefined
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function currentExperimentIdFromContext(
|
|
29
|
+
context: ExperimentAwarePlatformContext | undefined = getInjectedExperimentContext(),
|
|
30
|
+
): number | undefined {
|
|
31
|
+
return parseExperimentId(
|
|
32
|
+
context?.currentExperimentId ??
|
|
33
|
+
context?.experimentId ??
|
|
34
|
+
context?.currentExperiment ??
|
|
35
|
+
context?.experiment,
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function currentExperimentIdFromUrl(): number | undefined {
|
|
40
|
+
if (typeof window === 'undefined') return undefined
|
|
41
|
+
const params = new URLSearchParams(window.location.search)
|
|
42
|
+
return parseExperimentId(params.get('experimentId') ?? params.get('experiment_id'))
|
|
43
|
+
?? experimentIdFromPath(window.location.pathname)
|
|
44
|
+
?? experimentIdFromPath(window.location.hash.replace(/^#\/?/, '/'))
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function resolveCurrentExperimentId(
|
|
48
|
+
context: ExperimentAwarePlatformContext | undefined = getInjectedExperimentContext(),
|
|
49
|
+
): number | undefined {
|
|
50
|
+
return currentExperimentIdFromContext(context) ?? currentExperimentIdFromUrl()
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function parseExperimentId(value: unknown): number | undefined {
|
|
54
|
+
if (typeof value === 'number' && Number.isFinite(value)) return value
|
|
55
|
+
if (typeof value === 'string' && value.trim()) {
|
|
56
|
+
const parsed = Number(value)
|
|
57
|
+
return Number.isFinite(parsed) ? parsed : undefined
|
|
58
|
+
}
|
|
59
|
+
if (value && typeof value === 'object' && 'id' in value) {
|
|
60
|
+
return parseExperimentId((value as { id?: unknown }).id)
|
|
61
|
+
}
|
|
62
|
+
return undefined
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function experimentIdFromPath(path: string): number | undefined {
|
|
66
|
+
const segments = path.split('/').filter(Boolean)
|
|
67
|
+
for (let index = 0; index < segments.length - 1; index += 1) {
|
|
68
|
+
const segment = segments[index]?.toLowerCase()
|
|
69
|
+
if (segment === 'experiment' || segment === 'experiments') {
|
|
70
|
+
return parseExperimentId(decodeURIComponent(segments[index + 1] ?? ''))
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return undefined
|
|
74
|
+
}
|
|
@@ -5,6 +5,13 @@ import { useAuthStore } from '../stores/auth'
|
|
|
5
5
|
let apiClientInstance: AxiosInstance | null = null
|
|
6
6
|
let interceptorAttached = false
|
|
7
7
|
|
|
8
|
+
function joinUrlPath(baseUrl: string, path: string): string {
|
|
9
|
+
if (!path) return baseUrl
|
|
10
|
+
const normalizedBase = baseUrl.replace(/\/+$/, '')
|
|
11
|
+
const normalizedPath = path.replace(/^\/+/, '/')
|
|
12
|
+
return `${normalizedBase}${normalizedPath.startsWith('/') ? normalizedPath : `/${normalizedPath}`}`
|
|
13
|
+
}
|
|
14
|
+
|
|
8
15
|
function getApiClient(): AxiosInstance {
|
|
9
16
|
if (!apiClientInstance) {
|
|
10
17
|
apiClientInstance = axios.create({
|
|
@@ -144,12 +151,12 @@ export function useApi(options: ApiClientOptions = {}): UseApiReturn {
|
|
|
144
151
|
// Build full URL for external use (e.g., <a href="...">)
|
|
145
152
|
function buildUrl(path: string): string {
|
|
146
153
|
const baseUrl = options.baseUrl ?? settingsStore.getApiBaseUrl()
|
|
147
|
-
return
|
|
154
|
+
return joinUrlPath(baseUrl, path)
|
|
148
155
|
}
|
|
149
156
|
|
|
150
157
|
// WebSocket URL builder
|
|
151
158
|
function buildWsUrl(path: string): string {
|
|
152
|
-
return
|
|
159
|
+
return joinUrlPath(settingsStore.getWsBaseUrl(), path)
|
|
153
160
|
}
|
|
154
161
|
|
|
155
162
|
return {
|
|
@@ -4,14 +4,28 @@ import {
|
|
|
4
4
|
readonly,
|
|
5
5
|
provide,
|
|
6
6
|
toValue,
|
|
7
|
+
watch,
|
|
7
8
|
onScopeDispose,
|
|
8
9
|
type Ref,
|
|
9
10
|
type ComputedRef,
|
|
10
11
|
type InjectionKey,
|
|
11
12
|
} from 'vue'
|
|
12
13
|
import type { ExperimentSummary, ExperimentStatus } from '../types'
|
|
14
|
+
import { resolveExperimentCode } from './experiment-utils'
|
|
15
|
+
|
|
16
|
+
export type AppExperimentRecord = Pick<ExperimentSummary, 'id' | 'name' | 'status' | 'experiment_code'>
|
|
17
|
+
|
|
18
|
+
export type AppExperimentSource =
|
|
19
|
+
| AppExperimentRecord
|
|
20
|
+
| null
|
|
21
|
+
| undefined
|
|
22
|
+
| Ref<AppExperimentRecord | null | undefined>
|
|
23
|
+
| ComputedRef<AppExperimentRecord | null | undefined>
|
|
24
|
+
| (() => AppExperimentRecord | null | undefined)
|
|
13
25
|
|
|
14
26
|
export interface UseAppExperimentOptions {
|
|
27
|
+
/** Current experiment source to mirror into the app shell. Accepts a value, ref, computed, or getter. */
|
|
28
|
+
experiment?: AppExperimentSource
|
|
15
29
|
onSelect?: (experiment: ExperimentSummary) => void | Promise<void>
|
|
16
30
|
onSave?: () => string | null | Promise<string | null>
|
|
17
31
|
onDetach?: () => void
|
|
@@ -19,12 +33,37 @@ export interface UseAppExperimentOptions {
|
|
|
19
33
|
saveDisabledMessage?: string | Ref<string | undefined> | ComputedRef<string | undefined>
|
|
20
34
|
}
|
|
21
35
|
|
|
36
|
+
export interface AppExperimentPopoverBinding {
|
|
37
|
+
experimentName?: string
|
|
38
|
+
experimentCode?: string
|
|
39
|
+
experimentStatus?: ExperimentStatus
|
|
40
|
+
showSave: boolean
|
|
41
|
+
showDetach: boolean
|
|
42
|
+
saveDisabled: boolean
|
|
43
|
+
saveDisabledMessage?: string
|
|
44
|
+
saveLoading: boolean
|
|
45
|
+
saveSuccessMessage?: string
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface AppExperimentSelectorModalBinding {
|
|
49
|
+
modelValue: boolean
|
|
50
|
+
currentExperimentId: number | null
|
|
51
|
+
}
|
|
52
|
+
|
|
22
53
|
export interface UseAppExperimentReturn {
|
|
23
|
-
set: (experiment:
|
|
54
|
+
set: (experiment: AppExperimentRecord) => void
|
|
24
55
|
clear: () => void
|
|
25
56
|
experimentName: Readonly<Ref<string | undefined>>
|
|
26
57
|
experimentCode: Readonly<Ref<string | undefined>>
|
|
58
|
+
experimentStatus: Readonly<Ref<ExperimentStatus | undefined>>
|
|
27
59
|
experimentId: Readonly<Ref<number | null>>
|
|
60
|
+
popover: ComputedRef<AppExperimentPopoverBinding>
|
|
61
|
+
selectorModal: ComputedRef<AppExperimentSelectorModalBinding>
|
|
62
|
+
openModal: () => void
|
|
63
|
+
closeModal: () => void
|
|
64
|
+
handleSelect: (experiment: ExperimentSummary) => void
|
|
65
|
+
handleSave: () => Promise<void>
|
|
66
|
+
handleDetach: () => void
|
|
28
67
|
}
|
|
29
68
|
|
|
30
69
|
export interface AppExperimentState {
|
|
@@ -40,6 +79,8 @@ export interface AppExperimentState {
|
|
|
40
79
|
closeModal: () => void
|
|
41
80
|
saveDisabled: ComputedRef<boolean>
|
|
42
81
|
saveDisabledMessage: ComputedRef<string | undefined>
|
|
82
|
+
popover: ComputedRef<AppExperimentPopoverBinding>
|
|
83
|
+
selectorModal: ComputedRef<AppExperimentSelectorModalBinding>
|
|
43
84
|
openModal: () => void
|
|
44
85
|
handleSelect: (experiment: ExperimentSummary) => void
|
|
45
86
|
handleSave: () => Promise<void>
|
|
@@ -48,7 +89,7 @@ export interface AppExperimentState {
|
|
|
48
89
|
|
|
49
90
|
export const APP_EXPERIMENT_KEY: InjectionKey<AppExperimentState> = Symbol('app-experiment')
|
|
50
91
|
|
|
51
|
-
/** Manages the
|
|
92
|
+
/** Manages the current experiment selection, save flow, and detach action for a plugin's AppTopBar app shell. */
|
|
52
93
|
export function useAppExperiment(options: UseAppExperimentOptions = {}): UseAppExperimentReturn {
|
|
53
94
|
const experimentName = ref<string | undefined>()
|
|
54
95
|
const experimentCode = ref<string | undefined>()
|
|
@@ -64,19 +105,26 @@ export function useAppExperiment(options: UseAppExperimentOptions = {}): UseAppE
|
|
|
64
105
|
const showDetach = computed(() => experimentId.value !== null)
|
|
65
106
|
const saveDisabled = computed(() => toValue(options.saveDisabled) ?? false)
|
|
66
107
|
const saveDisabledMessage = computed(() => toValue(options.saveDisabledMessage))
|
|
67
|
-
|
|
68
|
-
|
|
108
|
+
const popover = computed<AppExperimentPopoverBinding>(() => ({
|
|
109
|
+
experimentName: experimentName.value,
|
|
110
|
+
experimentCode: experimentCode.value,
|
|
111
|
+
experimentStatus: experimentStatus.value,
|
|
112
|
+
showSave: showSave.value,
|
|
113
|
+
showDetach: showDetach.value,
|
|
114
|
+
saveDisabled: saveDisabled.value,
|
|
115
|
+
saveDisabledMessage: saveDisabledMessage.value,
|
|
116
|
+
saveLoading: saveLoading.value,
|
|
117
|
+
saveSuccessMessage: saveSuccessMessage.value,
|
|
118
|
+
}))
|
|
119
|
+
const selectorModal = computed<AppExperimentSelectorModalBinding>(() => ({
|
|
120
|
+
modelValue: showModal.value,
|
|
121
|
+
currentExperimentId: experimentId.value,
|
|
122
|
+
}))
|
|
123
|
+
|
|
124
|
+
function set(experiment: AppExperimentRecord) {
|
|
69
125
|
experimentId.value = experiment.id
|
|
70
126
|
experimentName.value = experiment.name
|
|
71
|
-
|
|
72
|
-
// topbar always has a compact identifier to show instead of the long
|
|
73
|
-
// name. Matches the `EXP-${id}` format used elsewhere (e.g., queue
|
|
74
|
-
// cards in mint-ms-planner). Callers with the real code should pass it
|
|
75
|
-
// via `experiment_code` to keep the topbar chip in sync with the
|
|
76
|
-
// formal code shown in the popover panel.
|
|
77
|
-
experimentCode.value = experiment.experiment_code ?? (
|
|
78
|
-
experiment.id != null ? `EXP-${experiment.id}` : undefined
|
|
79
|
-
)
|
|
127
|
+
experimentCode.value = resolveExperimentCode(experiment)
|
|
80
128
|
experimentStatus.value = experiment.status
|
|
81
129
|
}
|
|
82
130
|
|
|
@@ -87,6 +135,20 @@ export function useAppExperiment(options: UseAppExperimentOptions = {}): UseAppE
|
|
|
87
135
|
experimentStatus.value = undefined
|
|
88
136
|
}
|
|
89
137
|
|
|
138
|
+
if (options.experiment !== undefined) {
|
|
139
|
+
watch(
|
|
140
|
+
() => toValue(options.experiment),
|
|
141
|
+
(experiment) => {
|
|
142
|
+
if (experiment) {
|
|
143
|
+
set(experiment)
|
|
144
|
+
} else {
|
|
145
|
+
clear()
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
{ immediate: true },
|
|
149
|
+
)
|
|
150
|
+
}
|
|
151
|
+
|
|
90
152
|
function openModal() {
|
|
91
153
|
showModal.value = true
|
|
92
154
|
}
|
|
@@ -140,6 +202,8 @@ export function useAppExperiment(options: UseAppExperimentOptions = {}): UseAppE
|
|
|
140
202
|
showDetach,
|
|
141
203
|
saveDisabled,
|
|
142
204
|
saveDisabledMessage,
|
|
205
|
+
popover,
|
|
206
|
+
selectorModal,
|
|
143
207
|
openModal,
|
|
144
208
|
closeModal,
|
|
145
209
|
handleSelect,
|
|
@@ -154,6 +218,14 @@ export function useAppExperiment(options: UseAppExperimentOptions = {}): UseAppE
|
|
|
154
218
|
clear,
|
|
155
219
|
experimentName: readonly(experimentName),
|
|
156
220
|
experimentCode: readonly(experimentCode),
|
|
221
|
+
experimentStatus: readonly(experimentStatus),
|
|
157
222
|
experimentId: readonly(experimentId),
|
|
223
|
+
popover,
|
|
224
|
+
selectorModal,
|
|
225
|
+
openModal,
|
|
226
|
+
closeModal,
|
|
227
|
+
handleSelect,
|
|
228
|
+
handleSave,
|
|
229
|
+
handleDetach,
|
|
158
230
|
}
|
|
159
231
|
}
|