@morscherlab/mint-sdk 1.0.0-beta.1 → 1.0.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +218 -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/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/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/FormCompatibility.test.d.ts +1 -0
- package/dist/__tests__/components/GroupAssigner.test.d.ts +1 -0
- package/dist/__tests__/components/GroupingModal.test.d.ts +1 -0
- package/dist/__tests__/components/MultiSelect.test.d.ts +1 -0
- package/dist/__tests__/components/PluginIcon.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/SettingsButton.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/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/ActionItem.vue.d.ts +32 -0
- package/dist/components/AppAvatarMenu.vue.d.ts +2 -7
- package/dist/components/AppPageSelector.vue.d.ts +3 -6
- package/dist/components/AppPillNav.vue.d.ts +2 -2
- package/dist/components/AppSidebar.vue.d.ts +56 -3
- package/dist/components/AppToastContainer.vue.d.ts +2 -0
- package/dist/components/AppTopBar.vue.d.ts +43 -10
- package/dist/components/BaseButton.vue.d.ts +2 -2
- 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 +3 -3
- package/dist/components/BaseRadioGroup.vue.d.ts +4 -4
- package/dist/components/BaseSelect.vue.d.ts +4 -4
- package/dist/components/BaseSlider.vue.d.ts +1 -1
- package/dist/components/BaseTabs.vue.d.ts +2 -2
- package/dist/components/BaseTextarea.vue.d.ts +2 -2
- package/dist/components/BaseToggle.vue.d.ts +1 -1
- package/dist/components/BioTemplateExperimentWorkspaceView.vue.d.ts +117 -0
- package/dist/components/BioTemplatePackWorkspaceView.vue.d.ts +92 -0
- package/dist/components/BioTemplatePresetWorkspaceView.vue.d.ts +82 -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/CalendarGridPanel.vue.d.ts +25 -0
- package/dist/components/CollapsibleCard.vue.d.ts +1 -1
- package/dist/components/ColorSlider.vue.d.ts +1 -1
- 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 +130 -0
- package/dist/components/DatePicker.vue.d.ts +2 -2
- package/dist/components/DateTimePicker.vue.d.ts +3 -3
- package/dist/components/DropdownButton.vue.d.ts +4 -4
- 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 +2 -2
- 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 +22 -8
- package/dist/components/FormFieldRenderer.vue.d.ts +7 -10
- package/dist/components/FormSection.vue.d.ts +11 -24
- package/dist/components/FormulaInput.vue.d.ts +2 -2
- package/dist/components/IconButton.vue.d.ts +1 -1
- package/dist/components/LoadingSpinner.vue.d.ts +1 -1
- 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 +2 -2
- package/dist/components/PluginIcon.vue.d.ts +11 -0
- package/dist/components/ProgressBar.vue.d.ts +2 -2
- package/dist/components/ProtocolStepEditor.vue.d.ts +3 -1
- package/dist/components/RackEditor.vue.d.ts +2 -2
- package/dist/components/ReagentEditor.vue.d.ts +1 -1
- package/dist/components/ResourceCard.vue.d.ts +1 -1
- package/dist/components/SampleLegend.vue.d.ts +2 -2
- package/dist/components/SampleSelector.vue.d.ts +1 -1
- package/dist/components/ScheduleCalendar.vue.d.ts +2 -2
- package/dist/components/ScientificNumber.vue.d.ts +1 -1
- package/dist/components/SegmentedControl.vue.d.ts +3 -3
- package/dist/components/SequenceInput.vue.d.ts +3 -3
- package/dist/components/SettingsButton.vue.d.ts +2 -2
- package/dist/components/SettingsModal.vue.d.ts +32 -4
- 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 +2 -2
- package/dist/components/UnitInput.vue.d.ts +2 -2
- package/dist/components/WellPlate.vue.d.ts +8 -8
- package/dist/components/index.d.ts +12 -1
- package/dist/components/index.js +3 -3
- package/dist/components/internal/FormFieldRendererInternal.vue.d.ts +31 -0
- package/dist/components/internal/FormSectionRenderer.vue.d.ts +43 -0
- package/dist/{components-CzbQQPCb.js → components-D_Sr0adg.js} +9629 -8647
- package/dist/components-D_Sr0adg.js.map +1 -0
- package/dist/composables/index.d.ts +21 -2
- package/dist/composables/index.js +4 -3
- package/dist/composables/platformContextHelpers.d.ts +14 -0
- package/dist/composables/useBioTemplateComponents.d.ts +20 -0
- package/dist/composables/useBioTemplateControls.d.ts +6 -0
- package/dist/composables/useBioTemplatePackWorkspace.d.ts +45 -0
- package/dist/composables/useBioTemplatePresetWorkspace.d.ts +74 -0
- package/dist/composables/useBioTemplateWorkspace.d.ts +50 -0
- package/dist/composables/useCalendarGrid.d.ts +26 -0
- package/dist/composables/useControlSchema.d.ts +321 -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 +24 -3
- package/dist/composables/usePluginApi.d.ts +7 -14
- package/dist/composables/usePluginClient.d.ts +109 -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-BXklV5ii.js → composables-C3dpXQN5.js} +228 -146
- package/dist/composables-C3dpXQN5.js.map +1 -0
- package/dist/index.d.ts +12 -3
- 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/auth.d.ts +1 -1
- package/dist/stores/index.js +1 -1
- package/dist/stores/settings.d.ts +4 -1
- package/dist/styles.css +5255 -5654
- 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 +58 -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-50NPjaxL.js +9333 -0
- package/dist/templates-50NPjaxL.js.map +1 -0
- package/dist/types/components.d.ts +62 -1
- package/dist/types/form-builder.d.ts +6 -8
- package/dist/types/index.d.ts +2 -2
- package/dist/types/platform.d.ts +8 -1
- package/dist/useScheduleDrag-D4oWdh41.js +4371 -0
- package/dist/useScheduleDrag-D4oWdh41.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/AppPageSelector.test.ts +134 -0
- package/src/__tests__/components/AppPillNav.test.ts +78 -0
- package/src/__tests__/components/AppPluginSwitcher.test.ts +44 -0
- package/src/__tests__/components/AppSidebar.test.ts +370 -0
- package/src/__tests__/components/AppToastContainer.test.ts +48 -0
- package/src/__tests__/components/AppTopBar.test.ts +414 -13
- 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 +153 -0
- package/src/__tests__/components/BioTemplatePackWorkspaceView.test.ts +161 -0
- package/src/__tests__/components/BioTemplatePresetWorkspaceView.test.ts +281 -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/ConcentrationInput.test.ts +45 -0
- package/src/__tests__/components/ControlWorkspaceView.test.ts +1031 -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/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/FormCompatibility.test.ts +94 -0
- package/src/__tests__/components/GroupAssigner.test.ts +30 -0
- package/src/__tests__/components/GroupingModal.test.ts +73 -0
- package/src/__tests__/components/MultiSelect.test.ts +48 -0
- package/src/__tests__/components/PluginIcon.test.ts +119 -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/SettingsButton.test.ts +44 -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/useBioTemplatePackWorkspace.test.ts +122 -0
- package/src/__tests__/composables/useBioTemplatePresetWorkspace.test.ts +199 -0
- package/src/__tests__/composables/useBioTemplateWorkspace.test.ts +99 -0
- package/src/__tests__/composables/useCalendarGrid.test.ts +38 -0
- package/src/__tests__/composables/useControlSchema.test.ts +919 -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 +444 -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 +229 -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 +1043 -0
- package/src/components/ActionItem.vue +82 -0
- package/src/components/AppAvatarMenu.vue +15 -69
- package/src/components/AppLayout.story.vue +25 -25
- package/src/components/AppPageSelector.vue +63 -94
- package/src/components/AppPillNav.vue +44 -39
- package/src/components/AppPluginSwitcher.vue +41 -145
- package/src/components/AppSidebar.story.vue +94 -0
- package/src/components/AppSidebar.vue +187 -12
- package/src/components/{ToastNotification.story.vue → AppToastContainer.story.vue} +6 -6
- package/src/components/AppToastContainer.vue +62 -0
- package/src/components/AppTopBar.story.vue +7 -30
- package/src/components/AppTopBar.vue +283 -84
- 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 +337 -0
- package/src/components/BioTemplatePackWorkspaceView.story.vue +107 -0
- package/src/components/BioTemplatePackWorkspaceView.vue +176 -0
- package/src/components/BioTemplatePresetWorkspaceView.story.vue +151 -0
- package/src/components/BioTemplatePresetWorkspaceView.vue +392 -0
- package/src/components/BioTemplateRenderer.story.vue +57 -0
- package/src/components/BioTemplateRenderer.vue +269 -0
- package/src/components/Breadcrumb.vue +14 -8
- package/src/components/CalendarGridPanel.vue +120 -0
- package/src/components/ConcentrationInput.vue +27 -64
- package/src/components/ControlWorkspaceView.story.vue +336 -0
- package/src/components/ControlWorkspaceView.vue +347 -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/DropdownButton.vue +14 -32
- package/src/components/EmptyState.vue +4 -2
- package/src/components/ExperimentPopover.vue +5 -22
- package/src/components/FormBuilder.vue +124 -27
- package/src/components/FormFieldRenderer.vue +15 -38
- package/src/components/FormSection.vue +20 -73
- package/src/components/GroupAssigner.vue +24 -56
- package/src/components/GroupingModal.story.vue +3 -3
- package/src/components/GroupingModal.vue +30 -391
- package/src/components/MultiSelect.vue +17 -12
- package/src/components/PlateMapEditor.vue +3 -8
- package/src/components/PluginIcon.story.vue +71 -0
- package/src/components/PluginIcon.vue +68 -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/SettingsButton.story.vue +1 -1
- package/src/components/SettingsButton.vue +15 -27
- package/src/components/SettingsModal.story.vue +337 -45
- package/src/components/SettingsModal.vue +344 -66
- package/src/components/TagsInput.vue +29 -14
- package/src/components/ThemeToggle.vue +9 -7
- package/src/components/TimePicker.vue +19 -41
- package/src/components/ToastNotification.vue +4 -57
- package/src/components/Tooltip.vue +7 -12
- package/src/components/WellEditPopup.vue +3 -8
- package/src/components/WellPlate.vue +4 -10
- package/src/components/index.ts +12 -1
- package/src/components/internal/FormFieldRendererInternal.vue +50 -0
- package/src/components/internal/FormSectionRenderer.vue +78 -0
- package/src/composables/index.ts +212 -0
- package/src/composables/platformContextHelpers.ts +74 -0
- package/src/composables/useBioTemplateComponents.ts +93 -0
- package/src/composables/useBioTemplateControls.ts +41 -0
- package/src/composables/useBioTemplatePackWorkspace.ts +181 -0
- package/src/composables/useBioTemplatePresetWorkspace.ts +337 -0
- package/src/composables/useBioTemplateWorkspace.ts +139 -0
- package/src/composables/useCalendarGrid.ts +140 -0
- package/src/composables/useControlSchema.ts +1274 -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/usePluginApi.ts +7 -14
- package/src/composables/usePluginClient.ts +425 -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 +228 -4
- package/src/install.ts +11 -4
- package/src/stores/settings.ts +13 -9
- package/src/styles/components/app-page-selector.css +23 -0
- package/src/styles/components/app-pill-nav.css +8 -2
- package/src/styles/components/app-top-bar.css +35 -2
- package/src/styles/components/button.css +3 -7
- package/src/styles/components/concentration-input.css +3 -142
- package/src/styles/components/dropdown-button.css +4 -4
- package/src/styles/components/empty-state.css +0 -16
- package/src/styles/components/input.css +4 -5
- package/src/styles/components/number-input.css +3 -3
- package/src/styles/components/plugin-icon.css +38 -0
- package/src/styles/components/segmented-control.css +4 -7
- package/src/styles/components/settings-button.css +3 -66
- package/src/styles/components/settings-modal.css +184 -0
- package/src/styles/components/tabs.css +1 -2
- package/src/styles/components/textarea.css +4 -5
- package/src/styles/components/theme-toggle.css +3 -66
- package/src/styles/components/unit-input.css +3 -3
- package/src/styles/index.css +0 -1
- 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 +615 -0
- package/src/templates/controlSchemas.ts +718 -0
- package/src/templates/index.ts +314 -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 +80 -1
- package/src/types/form-builder.ts +7 -2
- package/src/types/index.ts +17 -0
- package/src/types/platform.ts +8 -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/auth-DsI0rQ7_.js.map +0 -1
- package/dist/components-CzbQQPCb.js.map +0 -1
- package/dist/composables-BXklV5ii.js.map +0 -1
- package/dist/useScheduleDrag-CxBeqYcu.js +0 -7181
- package/dist/useScheduleDrag-CxBeqYcu.js.map +0 -1
- package/src/styles/components/grouping-modal.css +0 -323
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import {
|
|
2
|
+
onScopeDispose,
|
|
3
|
+
ref,
|
|
4
|
+
watch,
|
|
5
|
+
type Ref,
|
|
6
|
+
type WatchOptions,
|
|
7
|
+
type WatchSource,
|
|
8
|
+
type WatchStopHandle,
|
|
9
|
+
} from 'vue'
|
|
10
|
+
|
|
11
|
+
export type DebouncedWatchCleanup = () => void
|
|
12
|
+
export type DebouncedWatchSource<T> = WatchSource<T> | WatchSource<unknown>[] | (() => T)
|
|
13
|
+
export type DebouncedWatchCallback<T> = (
|
|
14
|
+
value: T,
|
|
15
|
+
oldValue: T | undefined,
|
|
16
|
+
onCleanup: (cleanup: DebouncedWatchCleanup) => void,
|
|
17
|
+
) => void | Promise<void>
|
|
18
|
+
|
|
19
|
+
export interface UseDebouncedWatchOptions extends WatchOptions {
|
|
20
|
+
/** Debounce interval in milliseconds. */
|
|
21
|
+
delay?: number
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface UseDebouncedWatchReturn {
|
|
25
|
+
/** Whether a callback is currently scheduled. */
|
|
26
|
+
isPending: Ref<boolean>
|
|
27
|
+
/** Cancel the pending callback without stopping the watcher. */
|
|
28
|
+
cancel: () => void
|
|
29
|
+
/** Run the pending callback immediately, if one is scheduled. */
|
|
30
|
+
flush: () => void
|
|
31
|
+
/** Stop the watcher and clear pending callbacks. */
|
|
32
|
+
stop: WatchStopHandle
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Watch a Vue source with debounced callback execution and explicit cancel/flush controls. */
|
|
36
|
+
export function useDebouncedWatch<T>(
|
|
37
|
+
source: DebouncedWatchSource<T>,
|
|
38
|
+
callback: DebouncedWatchCallback<T>,
|
|
39
|
+
options: UseDebouncedWatchOptions = {},
|
|
40
|
+
): UseDebouncedWatchReturn {
|
|
41
|
+
const { delay = 300, ...watchOptions } = options
|
|
42
|
+
const isPending = ref(false)
|
|
43
|
+
|
|
44
|
+
let timer: ReturnType<typeof setTimeout> | null = null
|
|
45
|
+
let hasLatestValue = false
|
|
46
|
+
let latestValue: T
|
|
47
|
+
let latestOldValue: T | undefined
|
|
48
|
+
let callbackCleanup: DebouncedWatchCleanup | null = null
|
|
49
|
+
let stopped = false
|
|
50
|
+
|
|
51
|
+
function clearTimer(): void {
|
|
52
|
+
if (timer) {
|
|
53
|
+
clearTimeout(timer)
|
|
54
|
+
timer = null
|
|
55
|
+
}
|
|
56
|
+
isPending.value = false
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function runCallbackCleanup(): void {
|
|
60
|
+
if (!callbackCleanup) return
|
|
61
|
+
callbackCleanup()
|
|
62
|
+
callbackCleanup = null
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function cancel(): void {
|
|
66
|
+
clearTimer()
|
|
67
|
+
hasLatestValue = false
|
|
68
|
+
latestOldValue = undefined
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function flush(): void {
|
|
72
|
+
if (!hasLatestValue) return
|
|
73
|
+
const value = latestValue
|
|
74
|
+
const oldValue = latestOldValue
|
|
75
|
+
cancel()
|
|
76
|
+
runCallbackCleanup()
|
|
77
|
+
void callback(value, oldValue, (cleanup) => {
|
|
78
|
+
callbackCleanup = cleanup
|
|
79
|
+
})
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function schedule(value: T, oldValue: T | undefined): void {
|
|
83
|
+
cancel()
|
|
84
|
+
hasLatestValue = true
|
|
85
|
+
latestValue = value
|
|
86
|
+
latestOldValue = oldValue
|
|
87
|
+
isPending.value = true
|
|
88
|
+
timer = setTimeout(flush, delay)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const stopWatch = watch(
|
|
92
|
+
source as WatchSource<unknown> | WatchSource<unknown>[],
|
|
93
|
+
(value, oldValue, onCleanup) => {
|
|
94
|
+
schedule(value as T, oldValue as T | undefined)
|
|
95
|
+
onCleanup(() => {
|
|
96
|
+
cancel()
|
|
97
|
+
runCallbackCleanup()
|
|
98
|
+
})
|
|
99
|
+
},
|
|
100
|
+
watchOptions,
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
function stop(): void {
|
|
104
|
+
if (stopped) return
|
|
105
|
+
stopped = true
|
|
106
|
+
stopWatch()
|
|
107
|
+
cancel()
|
|
108
|
+
runCallbackCleanup()
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
onScopeDispose(stop)
|
|
112
|
+
|
|
113
|
+
return {
|
|
114
|
+
isPending,
|
|
115
|
+
cancel,
|
|
116
|
+
flush,
|
|
117
|
+
stop,
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { ref, type Ref } from 'vue'
|
|
2
|
+
import { useEventListener } from './useEventListener'
|
|
3
|
+
|
|
4
|
+
export interface UseDropdownStateOptions {
|
|
5
|
+
closeOnOutsideClick?: boolean
|
|
6
|
+
closeOnEscape?: boolean
|
|
7
|
+
insideRefs?: Array<Ref<HTMLElement | null>>
|
|
8
|
+
onOpen?: () => void
|
|
9
|
+
onClose?: () => void
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface UseDropdownStateReturn {
|
|
13
|
+
isOpen: Ref<boolean>
|
|
14
|
+
rootRef: Ref<HTMLElement | null>
|
|
15
|
+
open: () => void
|
|
16
|
+
close: () => void
|
|
17
|
+
toggle: () => void
|
|
18
|
+
handleClickOutside: (event: MouseEvent) => void
|
|
19
|
+
handleKeydown: (event: KeyboardEvent) => void
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** Shared disclosure state for dropdown-style SDK components. */
|
|
23
|
+
export function useDropdownState(options: UseDropdownStateOptions = {}): UseDropdownStateReturn {
|
|
24
|
+
const isOpen = ref(false)
|
|
25
|
+
const rootRef = ref<HTMLElement | null>(null)
|
|
26
|
+
const closeOnOutsideClick = options.closeOnOutsideClick ?? true
|
|
27
|
+
const closeOnEscape = options.closeOnEscape ?? true
|
|
28
|
+
|
|
29
|
+
function open(): void {
|
|
30
|
+
if (isOpen.value) return
|
|
31
|
+
isOpen.value = true
|
|
32
|
+
options.onOpen?.()
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function close(): void {
|
|
36
|
+
if (!isOpen.value) return
|
|
37
|
+
isOpen.value = false
|
|
38
|
+
options.onClose?.()
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function toggle(): void {
|
|
42
|
+
if (isOpen.value) {
|
|
43
|
+
close()
|
|
44
|
+
} else {
|
|
45
|
+
open()
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function handleClickOutside(event: MouseEvent): void {
|
|
50
|
+
if (!closeOnOutsideClick || !isOpen.value || !rootRef.value) return
|
|
51
|
+
const target = event.target
|
|
52
|
+
if (
|
|
53
|
+
target instanceof Node &&
|
|
54
|
+
!rootRef.value.contains(target) &&
|
|
55
|
+
!options.insideRefs?.some(ref => ref.value?.contains(target))
|
|
56
|
+
) {
|
|
57
|
+
close()
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function handleKeydown(event: KeyboardEvent): void {
|
|
62
|
+
if (closeOnEscape && event.key === 'Escape') {
|
|
63
|
+
close()
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (closeOnOutsideClick) {
|
|
68
|
+
useEventListener(() => document, 'click', handleClickOutside)
|
|
69
|
+
}
|
|
70
|
+
if (closeOnEscape) {
|
|
71
|
+
useEventListener(() => document, 'keydown', handleKeydown)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return {
|
|
75
|
+
isOpen,
|
|
76
|
+
rootRef,
|
|
77
|
+
open,
|
|
78
|
+
close,
|
|
79
|
+
toggle,
|
|
80
|
+
handleClickOutside,
|
|
81
|
+
handleKeydown,
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { isRef, onMounted, onUnmounted, watch, type Ref } from 'vue'
|
|
2
|
+
|
|
3
|
+
export type EventTargetGetter<TTarget extends EventTarget = EventTarget> =
|
|
4
|
+
() => TTarget | null | undefined
|
|
5
|
+
|
|
6
|
+
export type EventTargetLike<TTarget extends EventTarget = EventTarget> =
|
|
7
|
+
| TTarget
|
|
8
|
+
| Ref<TTarget | null | undefined>
|
|
9
|
+
| EventTargetGetter<TTarget>
|
|
10
|
+
| null
|
|
11
|
+
| undefined
|
|
12
|
+
|
|
13
|
+
export type EventListenerEnabled = boolean | Ref<boolean>
|
|
14
|
+
|
|
15
|
+
export interface UseEventListenerObjectOptions extends AddEventListenerOptions {
|
|
16
|
+
enabled?: EventListenerEnabled
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export type UseEventListenerOptions = boolean | UseEventListenerObjectOptions
|
|
20
|
+
export type EventListenerStop = () => void
|
|
21
|
+
|
|
22
|
+
export type EventMapFor<TTarget extends EventTarget> =
|
|
23
|
+
TTarget extends Window
|
|
24
|
+
? WindowEventMap
|
|
25
|
+
: TTarget extends Document
|
|
26
|
+
? DocumentEventMap
|
|
27
|
+
: TTarget extends HTMLElement
|
|
28
|
+
? HTMLElementEventMap
|
|
29
|
+
: Record<string, Event>
|
|
30
|
+
|
|
31
|
+
export type EventFor<
|
|
32
|
+
TTarget extends EventTarget,
|
|
33
|
+
TType extends string,
|
|
34
|
+
> = TType extends keyof EventMapFor<TTarget>
|
|
35
|
+
? EventMapFor<TTarget>[TType]
|
|
36
|
+
: Event
|
|
37
|
+
|
|
38
|
+
/** Bind a DOM event listener on mount, remove it on unmount, and rebind when a ref target changes. */
|
|
39
|
+
export function useEventListener<
|
|
40
|
+
TTarget extends EventTarget = EventTarget,
|
|
41
|
+
TType extends string = string,
|
|
42
|
+
>(
|
|
43
|
+
target: EventTargetLike<TTarget>,
|
|
44
|
+
type: TType,
|
|
45
|
+
listener: (event: EventFor<TTarget, TType>) => void,
|
|
46
|
+
options?: UseEventListenerOptions,
|
|
47
|
+
): EventListenerStop {
|
|
48
|
+
let stopCurrent: EventListenerStop | undefined
|
|
49
|
+
let mounted = false
|
|
50
|
+
|
|
51
|
+
function stop(): void {
|
|
52
|
+
stopCurrent?.()
|
|
53
|
+
stopCurrent = undefined
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function start(): void {
|
|
57
|
+
stop()
|
|
58
|
+
if (!mounted || !isEnabled(options)) return
|
|
59
|
+
const resolvedTarget = resolveEventTarget(target)
|
|
60
|
+
if (!resolvedTarget) return
|
|
61
|
+
|
|
62
|
+
const eventListener = listener as EventListener
|
|
63
|
+
const eventOptions = getEventOptions(options)
|
|
64
|
+
resolvedTarget.addEventListener(type, eventListener, eventOptions)
|
|
65
|
+
stopCurrent = () => {
|
|
66
|
+
resolvedTarget.removeEventListener(type, eventListener, eventOptions)
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
onMounted(() => {
|
|
71
|
+
mounted = true
|
|
72
|
+
start()
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
if (isRef(target)) {
|
|
76
|
+
watch(target, start, { flush: 'post' })
|
|
77
|
+
}
|
|
78
|
+
const enabled = getEnabledOption(options)
|
|
79
|
+
if (isRef(enabled)) {
|
|
80
|
+
watch(enabled, start, { flush: 'post' })
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
onUnmounted(() => {
|
|
84
|
+
mounted = false
|
|
85
|
+
stop()
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
return stop
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function resolveEventTarget(target: EventTargetLike): EventTarget | null | undefined {
|
|
92
|
+
if (isRef(target)) return target.value
|
|
93
|
+
if (typeof target === 'function') return target()
|
|
94
|
+
return target
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function getEnabledOption(options: UseEventListenerOptions | undefined): EventListenerEnabled | undefined {
|
|
98
|
+
return typeof options === 'object' ? options.enabled : undefined
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function isEnabled(options: UseEventListenerOptions | undefined): boolean {
|
|
102
|
+
const enabled = getEnabledOption(options)
|
|
103
|
+
if (isRef(enabled)) return enabled.value
|
|
104
|
+
return enabled ?? true
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function getEventOptions(options: UseEventListenerOptions | undefined): boolean | AddEventListenerOptions | undefined {
|
|
108
|
+
if (typeof options !== 'object') return options
|
|
109
|
+
const { enabled: _enabled, ...eventOptions } = options
|
|
110
|
+
return eventOptions
|
|
111
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { computed, ref, toValue, watch, type ComputedRef, type Ref } from 'vue'
|
|
2
|
+
|
|
3
|
+
export type ExpansionSetSource<T> =
|
|
4
|
+
| T
|
|
5
|
+
| Ref<T>
|
|
6
|
+
| ComputedRef<T>
|
|
7
|
+
| (() => T)
|
|
8
|
+
|
|
9
|
+
export interface UseExpansionSetOptions {
|
|
10
|
+
defaultIds?: ExpansionSetSource<readonly string[] | null | undefined>
|
|
11
|
+
allIds?: ExpansionSetSource<readonly string[] | null | undefined>
|
|
12
|
+
expandAll?: ExpansionSetSource<boolean | null | undefined>
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface UseExpansionSetReturn {
|
|
16
|
+
expandedIds: Ref<Set<string>>
|
|
17
|
+
expandedList: ComputedRef<string[]>
|
|
18
|
+
isExpanded: (id: string) => boolean
|
|
19
|
+
expand: (id: string) => void
|
|
20
|
+
collapse: (id: string) => void
|
|
21
|
+
toggle: (id: string) => boolean
|
|
22
|
+
expandMany: (ids: readonly string[]) => void
|
|
23
|
+
setExpanded: (ids: readonly string[]) => void
|
|
24
|
+
collapseAll: () => void
|
|
25
|
+
reset: () => void
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** Shared expansion state for trees, grouped selectors, and disclosure lists. */
|
|
29
|
+
export function useExpansionSet(options: UseExpansionSetOptions = {}): UseExpansionSetReturn {
|
|
30
|
+
const expandedIds = ref(new Set(normalizeIds(toValue(options.defaultIds))))
|
|
31
|
+
const expandedList = computed(() => [...expandedIds.value])
|
|
32
|
+
|
|
33
|
+
if (options.expandAll !== undefined) {
|
|
34
|
+
watch(
|
|
35
|
+
() => toValue(options.expandAll),
|
|
36
|
+
(shouldExpandAll) => {
|
|
37
|
+
if (shouldExpandAll === undefined || shouldExpandAll === null) return
|
|
38
|
+
if (shouldExpandAll) {
|
|
39
|
+
setExpanded(normalizeIds(toValue(options.allIds)))
|
|
40
|
+
} else {
|
|
41
|
+
reset()
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
{ immediate: true },
|
|
45
|
+
)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (options.allIds !== undefined) {
|
|
49
|
+
watch(
|
|
50
|
+
() => normalizeIds(toValue(options.allIds)),
|
|
51
|
+
(ids) => {
|
|
52
|
+
if (toValue(options.expandAll)) {
|
|
53
|
+
setExpanded(ids)
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function isExpanded(id: string): boolean {
|
|
60
|
+
return expandedIds.value.has(id)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function expand(id: string) {
|
|
64
|
+
if (expandedIds.value.has(id)) return
|
|
65
|
+
expandedIds.value = new Set([...expandedIds.value, id])
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function collapse(id: string) {
|
|
69
|
+
if (!expandedIds.value.has(id)) return
|
|
70
|
+
const next = new Set(expandedIds.value)
|
|
71
|
+
next.delete(id)
|
|
72
|
+
expandedIds.value = next
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function toggle(id: string): boolean {
|
|
76
|
+
if (expandedIds.value.has(id)) {
|
|
77
|
+
collapse(id)
|
|
78
|
+
return false
|
|
79
|
+
}
|
|
80
|
+
expand(id)
|
|
81
|
+
return true
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function expandMany(ids: readonly string[]) {
|
|
85
|
+
expandedIds.value = new Set([...expandedIds.value, ...normalizeIds(ids)])
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function setExpanded(ids: readonly string[]) {
|
|
89
|
+
expandedIds.value = new Set(normalizeIds(ids))
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function collapseAll() {
|
|
93
|
+
expandedIds.value = new Set()
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function reset() {
|
|
97
|
+
setExpanded(normalizeIds(toValue(options.defaultIds)))
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return {
|
|
101
|
+
expandedIds,
|
|
102
|
+
expandedList,
|
|
103
|
+
isExpanded,
|
|
104
|
+
expand,
|
|
105
|
+
collapse,
|
|
106
|
+
toggle,
|
|
107
|
+
expandMany,
|
|
108
|
+
setExpanded,
|
|
109
|
+
collapseAll,
|
|
110
|
+
reset,
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function normalizeIds(ids: readonly string[] | null | undefined): string[] {
|
|
115
|
+
if (!ids) return []
|
|
116
|
+
return [...new Set(ids.filter(Boolean))]
|
|
117
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ref, computed, type Ref, type ComputedRef } from 'vue'
|
|
2
2
|
import { useApi } from './useApi'
|
|
3
|
+
import { useRequestSyncState } from './useRequestSyncState'
|
|
3
4
|
import type { TreeNode, SummaryData } from '../types'
|
|
4
5
|
|
|
5
6
|
export interface UseExperimentDataOptions {
|
|
@@ -8,13 +9,23 @@ export interface UseExperimentDataOptions {
|
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
export interface UseExperimentDataReturn {
|
|
12
|
+
/** Raw experiment data payload from `/experiments/{id}/data`, or null. */
|
|
11
13
|
data: Ref<Record<string, unknown> | null>
|
|
14
|
+
/** Hierarchy tree rows normalised from `tree_data` or `treeData`. */
|
|
12
15
|
treeData: ComputedRef<TreeNode[]>
|
|
16
|
+
/** Table rows normalised from `table_data` or `tableData`. */
|
|
13
17
|
tableData: ComputedRef<Record<string, unknown>[]>
|
|
18
|
+
/** Summary payload normalised from `summary_data` or `summaryData`, or null. */
|
|
14
19
|
summaryData: ComputedRef<SummaryData | null>
|
|
20
|
+
/** Whether experiment data is currently loading. */
|
|
15
21
|
isLoading: Ref<boolean>
|
|
22
|
+
/** Error message from the last failed fetch, or null. */
|
|
16
23
|
error: Ref<string | null>
|
|
24
|
+
/** Timestamp of the last successful experiment data fetch, or null. */
|
|
25
|
+
lastLoadedAt: Ref<Date | null>
|
|
26
|
+
/** Fetch experiment data for an experiment id. */
|
|
17
27
|
fetch: (experimentId: number) => Promise<void>
|
|
28
|
+
/** Refetch the most recently fetched experiment id. */
|
|
18
29
|
refresh: () => Promise<void>
|
|
19
30
|
}
|
|
20
31
|
|
|
@@ -25,8 +36,10 @@ export function useExperimentData(
|
|
|
25
36
|
const api = useApi({ baseUrl: options.apiBaseUrl })
|
|
26
37
|
|
|
27
38
|
const data = ref<Record<string, unknown> | null>(null)
|
|
28
|
-
const
|
|
29
|
-
const
|
|
39
|
+
const request = useRequestSyncState('Failed to fetch experiment data')
|
|
40
|
+
const isLoading = request.loading
|
|
41
|
+
const error = request.error
|
|
42
|
+
const lastLoadedAt = request.lastLoadedAt
|
|
30
43
|
let lastExperimentId: number | null = null
|
|
31
44
|
|
|
32
45
|
const treeData = computed<TreeNode[]>(() => {
|
|
@@ -52,18 +65,13 @@ export function useExperimentData(
|
|
|
52
65
|
|
|
53
66
|
async function fetchData(experimentId: number): Promise<void> {
|
|
54
67
|
lastExperimentId = experimentId
|
|
55
|
-
isLoading.value = true
|
|
56
|
-
error.value = null
|
|
57
68
|
try {
|
|
58
|
-
|
|
59
|
-
`/experiments/${experimentId}/data
|
|
69
|
+
data.value = await request.run(
|
|
70
|
+
() => api.get<Record<string, unknown>>(`/experiments/${experimentId}/data`),
|
|
71
|
+
{ success: 'load', errorMessage: 'Failed to fetch experiment data' },
|
|
60
72
|
)
|
|
61
|
-
|
|
62
|
-
} catch (e) {
|
|
63
|
-
error.value = e instanceof Error ? e.message : 'Failed to fetch experiment data'
|
|
73
|
+
} catch {
|
|
64
74
|
data.value = null
|
|
65
|
-
} finally {
|
|
66
|
-
isLoading.value = false
|
|
67
75
|
}
|
|
68
76
|
}
|
|
69
77
|
|
|
@@ -80,6 +88,7 @@ export function useExperimentData(
|
|
|
80
88
|
summaryData,
|
|
81
89
|
isLoading,
|
|
82
90
|
error,
|
|
91
|
+
lastLoadedAt,
|
|
83
92
|
fetch: fetchData,
|
|
84
93
|
refresh,
|
|
85
94
|
}
|