@morscherlab/mint-sdk 1.0.0-beta.2 → 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/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 +41 -10
- 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 +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/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 +1 -1
- package/dist/components/DateTimePicker.vue.d.ts +3 -3
- package/dist/components/Divider.vue.d.ts +1 -1
- 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 +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/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/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/SettingsButton.vue.d.ts +2 -2
- package/dist/components/SettingsModal.vue.d.ts +13 -5
- 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 +8 -8
- package/dist/components/index.d.ts +11 -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-_XqPEhP9.js → components-D_Sr0adg.js} +7290 -6518
- 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 +21 -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-tiZqLu1M.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/index.js +1 -1
- package/dist/stores/settings.d.ts +4 -1
- package/dist/styles.css +5235 -5977
- 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 +26 -4
- 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-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 +383 -0
- 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/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 +251 -57
- 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.vue +2 -22
- 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 +1 -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/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 +11 -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 +224 -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 +7 -0
- package/src/styles/components/app-top-bar.css +34 -0
- package/src/styles/components/concentration-input.css +3 -142
- package/src/styles/components/empty-state.css +0 -16
- package/src/styles/components/settings-button.css +3 -66
- package/src/styles/components/theme-toggle.css +3 -66
- 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 +41 -4
- package/src/types/form-builder.ts +7 -2
- package/src/types/index.ts +14 -0
- 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/auth-DsI0rQ7_.js.map +0 -1
- package/dist/components-_XqPEhP9.js.map +0 -1
- 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/styles/components/grouping-modal.css +0 -323
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
/** Dropdown menu for switching between installed plugins with color swatches, version badges, and an install link. */
|
|
3
|
-
import {
|
|
3
|
+
import { useDropdownState } from '../composables/useDropdownState'
|
|
4
4
|
import type { PluginSwitcherPlugin } from '../types/components'
|
|
5
|
+
import ActionItem from './ActionItem.vue'
|
|
5
6
|
|
|
6
7
|
interface Props {
|
|
7
8
|
current: PluginSwitcherPlugin
|
|
@@ -21,55 +22,26 @@ const emit = defineEmits<{
|
|
|
21
22
|
'install-click': []
|
|
22
23
|
}>()
|
|
23
24
|
|
|
24
|
-
const isOpen =
|
|
25
|
-
const rootRef = ref<HTMLElement | null>(null)
|
|
25
|
+
const { isOpen, rootRef, close, toggle } = useDropdownState()
|
|
26
26
|
|
|
27
27
|
function initialsOf(plugin: PluginSwitcherPlugin) {
|
|
28
28
|
const label = plugin.label || plugin.id
|
|
29
29
|
return label.slice(0, 2).toUpperCase()
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
function toggle() {
|
|
33
|
-
isOpen.value = !isOpen.value
|
|
34
|
-
}
|
|
35
|
-
|
|
36
32
|
function handleSelect(plugin: PluginSwitcherPlugin) {
|
|
37
33
|
if (plugin.id === props.current.id) {
|
|
38
|
-
|
|
34
|
+
close()
|
|
39
35
|
return
|
|
40
36
|
}
|
|
41
37
|
emit('select', plugin)
|
|
42
|
-
|
|
38
|
+
close()
|
|
43
39
|
}
|
|
44
40
|
|
|
45
41
|
function handleInstall() {
|
|
46
42
|
emit('install-click')
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function handleClickOutside(event: MouseEvent) {
|
|
51
|
-
if (!isOpen.value) return
|
|
52
|
-
const target = event.target as Node
|
|
53
|
-
if (rootRef.value && !rootRef.value.contains(target)) {
|
|
54
|
-
isOpen.value = false
|
|
55
|
-
}
|
|
43
|
+
close()
|
|
56
44
|
}
|
|
57
|
-
|
|
58
|
-
function handleKeydown(event: KeyboardEvent) {
|
|
59
|
-
if (event.key === 'Escape' && isOpen.value) {
|
|
60
|
-
isOpen.value = false
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
onMounted(() => {
|
|
65
|
-
document.addEventListener('click', handleClickOutside)
|
|
66
|
-
document.addEventListener('keydown', handleKeydown)
|
|
67
|
-
})
|
|
68
|
-
|
|
69
|
-
onUnmounted(() => {
|
|
70
|
-
document.removeEventListener('click', handleClickOutside)
|
|
71
|
-
document.removeEventListener('keydown', handleKeydown)
|
|
72
|
-
})
|
|
73
45
|
</script>
|
|
74
46
|
|
|
75
47
|
<template>
|
|
@@ -102,124 +74,48 @@ onUnmounted(() => {
|
|
|
102
74
|
|
|
103
75
|
<div v-if="isOpen" class="mint-plugin-switcher__menu" role="menu">
|
|
104
76
|
<div class="mint-plugin-switcher__menu-title">Switch plugin</div>
|
|
105
|
-
<
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
77
|
+
<ActionItem
|
|
78
|
+
v-for="plugin in plugins"
|
|
79
|
+
:key="plugin.id"
|
|
80
|
+
:href="plugin.href"
|
|
81
|
+
:to="plugin.to"
|
|
82
|
+
:class="[
|
|
83
|
+
'mint-plugin-switcher__item',
|
|
84
|
+
{ 'mint-plugin-switcher__item--active': plugin.id === current.id },
|
|
85
|
+
]"
|
|
86
|
+
role="menuitem"
|
|
87
|
+
@click="handleSelect(plugin)"
|
|
88
|
+
>
|
|
89
|
+
<span
|
|
90
|
+
class="mint-plugin-switcher__item-swatch"
|
|
91
|
+
:style="{ background: plugin.color ?? 'var(--color-primary)' }"
|
|
115
92
|
>
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
stroke-width="2.5"
|
|
131
|
-
stroke-linecap="round"
|
|
132
|
-
stroke-linejoin="round"
|
|
133
|
-
aria-hidden="true"
|
|
134
|
-
>
|
|
135
|
-
<path d="M5 13l4 4L19 7" />
|
|
136
|
-
</svg>
|
|
137
|
-
</a>
|
|
138
|
-
<router-link
|
|
139
|
-
v-else-if="plugin.to"
|
|
140
|
-
:to="plugin.to"
|
|
141
|
-
:class="[
|
|
142
|
-
'mint-plugin-switcher__item',
|
|
143
|
-
{ 'mint-plugin-switcher__item--active': plugin.id === current.id },
|
|
144
|
-
]"
|
|
145
|
-
role="menuitem"
|
|
146
|
-
@click="handleSelect(plugin)"
|
|
147
|
-
>
|
|
148
|
-
<span
|
|
149
|
-
class="mint-plugin-switcher__item-swatch"
|
|
150
|
-
:style="{ background: plugin.color ?? 'var(--color-primary)' }"
|
|
151
|
-
>
|
|
152
|
-
{{ initialsOf(plugin) }}
|
|
153
|
-
</span>
|
|
154
|
-
<span class="mint-plugin-switcher__item-label">{{ plugin.label }}</span>
|
|
155
|
-
<span v-if="plugin.version" class="mint-plugin-switcher__item-version">v{{ plugin.version }}</span>
|
|
156
|
-
<svg
|
|
157
|
-
v-if="plugin.id === current.id"
|
|
158
|
-
class="mint-plugin-switcher__item-check"
|
|
159
|
-
viewBox="0 0 24 24"
|
|
160
|
-
fill="none"
|
|
161
|
-
stroke="currentColor"
|
|
162
|
-
stroke-width="2.5"
|
|
163
|
-
stroke-linecap="round"
|
|
164
|
-
stroke-linejoin="round"
|
|
165
|
-
aria-hidden="true"
|
|
166
|
-
>
|
|
167
|
-
<path d="M5 13l4 4L19 7" />
|
|
168
|
-
</svg>
|
|
169
|
-
</router-link>
|
|
170
|
-
<button
|
|
171
|
-
v-else
|
|
172
|
-
type="button"
|
|
173
|
-
:class="[
|
|
174
|
-
'mint-plugin-switcher__item',
|
|
175
|
-
{ 'mint-plugin-switcher__item--active': plugin.id === current.id },
|
|
176
|
-
]"
|
|
177
|
-
role="menuitem"
|
|
178
|
-
@click="handleSelect(plugin)"
|
|
93
|
+
{{ initialsOf(plugin) }}
|
|
94
|
+
</span>
|
|
95
|
+
<span class="mint-plugin-switcher__item-label">{{ plugin.label }}</span>
|
|
96
|
+
<span v-if="plugin.version" class="mint-plugin-switcher__item-version">v{{ plugin.version }}</span>
|
|
97
|
+
<svg
|
|
98
|
+
v-if="plugin.id === current.id"
|
|
99
|
+
class="mint-plugin-switcher__item-check"
|
|
100
|
+
viewBox="0 0 24 24"
|
|
101
|
+
fill="none"
|
|
102
|
+
stroke="currentColor"
|
|
103
|
+
stroke-width="2.5"
|
|
104
|
+
stroke-linecap="round"
|
|
105
|
+
stroke-linejoin="round"
|
|
106
|
+
aria-hidden="true"
|
|
179
107
|
>
|
|
180
|
-
<
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
>
|
|
184
|
-
{{ initialsOf(plugin) }}
|
|
185
|
-
</span>
|
|
186
|
-
<span class="mint-plugin-switcher__item-label">{{ plugin.label }}</span>
|
|
187
|
-
<span v-if="plugin.version" class="mint-plugin-switcher__item-version">v{{ plugin.version }}</span>
|
|
188
|
-
<svg
|
|
189
|
-
v-if="plugin.id === current.id"
|
|
190
|
-
class="mint-plugin-switcher__item-check"
|
|
191
|
-
viewBox="0 0 24 24"
|
|
192
|
-
fill="none"
|
|
193
|
-
stroke="currentColor"
|
|
194
|
-
stroke-width="2.5"
|
|
195
|
-
stroke-linecap="round"
|
|
196
|
-
stroke-linejoin="round"
|
|
197
|
-
aria-hidden="true"
|
|
198
|
-
>
|
|
199
|
-
<path d="M5 13l4 4L19 7" />
|
|
200
|
-
</svg>
|
|
201
|
-
</button>
|
|
202
|
-
</template>
|
|
108
|
+
<path d="M5 13l4 4L19 7" />
|
|
109
|
+
</svg>
|
|
110
|
+
</ActionItem>
|
|
203
111
|
|
|
204
112
|
<template v-if="plugins.length && (installHref || installTo || $slots.install)">
|
|
205
113
|
<div class="mint-plugin-switcher__divider" role="separator" />
|
|
206
114
|
</template>
|
|
207
115
|
<slot name="install">
|
|
208
|
-
<
|
|
209
|
-
v-if="installHref"
|
|
116
|
+
<ActionItem
|
|
117
|
+
v-if="installHref || installTo"
|
|
210
118
|
:href="installHref"
|
|
211
|
-
class="mint-plugin-switcher__install"
|
|
212
|
-
role="menuitem"
|
|
213
|
-
@click="handleInstall"
|
|
214
|
-
>
|
|
215
|
-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
216
|
-
<line x1="12" y1="5" x2="12" y2="19" />
|
|
217
|
-
<line x1="5" y1="12" x2="19" y2="12" />
|
|
218
|
-
</svg>
|
|
219
|
-
<span>{{ installLabel }}</span>
|
|
220
|
-
</a>
|
|
221
|
-
<router-link
|
|
222
|
-
v-else-if="installTo"
|
|
223
119
|
:to="installTo"
|
|
224
120
|
class="mint-plugin-switcher__install"
|
|
225
121
|
role="menuitem"
|
|
@@ -230,7 +126,7 @@ onUnmounted(() => {
|
|
|
230
126
|
<line x1="5" y1="12" x2="19" y2="12" />
|
|
231
127
|
</svg>
|
|
232
128
|
<span>{{ installLabel }}</span>
|
|
233
|
-
</
|
|
129
|
+
</ActionItem>
|
|
234
130
|
</slot>
|
|
235
131
|
</div>
|
|
236
132
|
</div>
|
|
@@ -9,6 +9,10 @@ import BaseInput from './BaseInput.vue'
|
|
|
9
9
|
import NumberInput from './NumberInput.vue'
|
|
10
10
|
import FileUploader from './FileUploader.vue'
|
|
11
11
|
import FormField from './FormField.vue'
|
|
12
|
+
import WellPlate from './WellPlate.vue'
|
|
13
|
+
import { defineControls, getControlDefaults } from '../composables/useControlSchema'
|
|
14
|
+
import { useBioTemplateWorkspace } from '../composables/useBioTemplateWorkspace'
|
|
15
|
+
import { createWellPlateScreenCollection } from '../templates'
|
|
12
16
|
import type { SidebarToolSection } from '../types'
|
|
13
17
|
|
|
14
18
|
/* --- Icon paths (Lucide-style) --- */
|
|
@@ -127,6 +131,57 @@ const container = ref('vial')
|
|
|
127
131
|
const expNumber = ref(1)
|
|
128
132
|
const initials = ref('XP')
|
|
129
133
|
const toggleState = reactive<Record<string, boolean>>({ naming: true, randomize: false })
|
|
134
|
+
const schemaControls = defineControls({
|
|
135
|
+
threshold: {
|
|
136
|
+
type: 'slider',
|
|
137
|
+
label: 'Threshold',
|
|
138
|
+
default: 0.05,
|
|
139
|
+
min: 0,
|
|
140
|
+
max: 1,
|
|
141
|
+
props: { step: 0.01 },
|
|
142
|
+
section: 'parameters',
|
|
143
|
+
sectionLabel: 'Parameters',
|
|
144
|
+
sectionSubtitle: 'Analysis controls',
|
|
145
|
+
view: 'analysis',
|
|
146
|
+
sidebar: {
|
|
147
|
+
icon: icons.settings,
|
|
148
|
+
iconColor: '#6366f1',
|
|
149
|
+
iconBg: '#e0e7ff',
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
method: {
|
|
153
|
+
label: 'Model',
|
|
154
|
+
default: 'linear',
|
|
155
|
+
options: ['linear', 'logistic', 'quadratic'],
|
|
156
|
+
required: true,
|
|
157
|
+
section: 'parameters',
|
|
158
|
+
view: 'analysis',
|
|
159
|
+
},
|
|
160
|
+
showOutliers: {
|
|
161
|
+
label: 'Show outliers',
|
|
162
|
+
default: true,
|
|
163
|
+
section: 'display',
|
|
164
|
+
sectionLabel: 'Display',
|
|
165
|
+
sectionSubtitle: 'Result filters',
|
|
166
|
+
view: 'analysis',
|
|
167
|
+
sidebar: {
|
|
168
|
+
icon: icons.zap,
|
|
169
|
+
iconColor: '#0ea5e9',
|
|
170
|
+
iconBg: '#e0f2fe',
|
|
171
|
+
defaultOpen: false,
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
})
|
|
175
|
+
const controlValues = reactive<Record<string, unknown>>({ ...getControlDefaults(schemaControls) })
|
|
176
|
+
const templateCollection = createWellPlateScreenCollection({
|
|
177
|
+
samples: ['Control', 'Treatment'],
|
|
178
|
+
compounds: { 'Drug A': [10, 1, 0.1] },
|
|
179
|
+
})
|
|
180
|
+
const templateWorkspace = useBioTemplateWorkspace(templateCollection)
|
|
181
|
+
const templateValues = reactive<Record<string, unknown>>({ ...templateWorkspace.controls.initialValues })
|
|
182
|
+
const templateWellPlateProps = templateWorkspace.componentProps
|
|
183
|
+
.find(binding => binding.component === 'WellPlate')
|
|
184
|
+
?.propsObject ?? {}
|
|
130
185
|
|
|
131
186
|
function handleToggle(id: string, value: boolean) {
|
|
132
187
|
toggleState[id] = value
|
|
@@ -218,6 +273,45 @@ function initSimpleToolkit() {
|
|
|
218
273
|
</div>
|
|
219
274
|
</Variant>
|
|
220
275
|
|
|
276
|
+
<Variant title="Schema Driven Controls">
|
|
277
|
+
<div style="padding: 2rem; height: 520px; position: relative; background: var(--bg-primary, #f1f5f9);">
|
|
278
|
+
<AppSidebar
|
|
279
|
+
:controls="schemaControls"
|
|
280
|
+
active-view="analysis"
|
|
281
|
+
v-model="controlValues"
|
|
282
|
+
width="300px"
|
|
283
|
+
/>
|
|
284
|
+
</div>
|
|
285
|
+
</Variant>
|
|
286
|
+
|
|
287
|
+
<Variant title="Template Driven Controls">
|
|
288
|
+
<div style="padding: 2rem; min-height: 560px; display: flex; gap: 1rem; background: var(--bg-primary, #f1f5f9);">
|
|
289
|
+
<AppSidebar
|
|
290
|
+
v-bind="templateWorkspace.sidebar"
|
|
291
|
+
active-view="design"
|
|
292
|
+
v-model="templateValues"
|
|
293
|
+
width="300px"
|
|
294
|
+
/>
|
|
295
|
+
|
|
296
|
+
<div style="flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0.75rem;">
|
|
297
|
+
<div style="display: flex; gap: 0.5rem; flex-wrap: wrap;">
|
|
298
|
+
<span
|
|
299
|
+
v-for="binding in templateWorkspace.componentBindings"
|
|
300
|
+
:key="binding.id"
|
|
301
|
+
style="font-size: 0.75rem; padding: 0.25rem 0.5rem; border: 1px solid var(--border-color, #e5e7eb); border-radius: 0.375rem; background: var(--bg-card, #fff); color: var(--text-secondary, #4b5563);"
|
|
302
|
+
>
|
|
303
|
+
{{ binding.component }}
|
|
304
|
+
</span>
|
|
305
|
+
</div>
|
|
306
|
+
<WellPlate
|
|
307
|
+
v-bind="templateWellPlateProps"
|
|
308
|
+
size="fill"
|
|
309
|
+
readonly
|
|
310
|
+
/>
|
|
311
|
+
</div>
|
|
312
|
+
</div>
|
|
313
|
+
</Variant>
|
|
314
|
+
|
|
221
315
|
<Variant title="Simple Toolkit" :init-state="initSimpleToolkit">
|
|
222
316
|
<template #default="{ state }">
|
|
223
317
|
<div style="padding: 2rem; height: 500px; position: relative; background: var(--bg-primary, #f1f5f9);">
|
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* AppSidebar - Context-sensitive toolkit panel
|
|
4
4
|
*
|
|
5
|
-
* Shows tool sections relevant to the active view. Sections are defined
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* `#section-{sectionId}`.
|
|
5
|
+
* Shows tool sections relevant to the active view. Sections are defined via
|
|
6
|
+
* the `panels` config and rendered as CollapsibleCards. Controls can be
|
|
7
|
+
* provided through named slots or auto-rendered from FormBuilder schemas.
|
|
9
8
|
*
|
|
10
9
|
* When the active view has no matching panels, the sidebar hides entirely.
|
|
11
10
|
*
|
|
@@ -20,11 +19,27 @@
|
|
|
20
19
|
* </template>
|
|
21
20
|
* <template #header>Plugin Tools</template>
|
|
22
21
|
* </AppSidebar>
|
|
22
|
+
*
|
|
23
|
+
* <!-- Direct schema-driven controls -->
|
|
24
|
+
* <AppSidebar :controls="controls" :active-view="activeTab" v-model="values" />
|
|
23
25
|
* ```
|
|
24
26
|
*/
|
|
25
27
|
import { computed } from 'vue'
|
|
26
|
-
import type { SidebarToolSection } from '../types'
|
|
28
|
+
import type { PillNavItem, SidebarToolSection } from '../types'
|
|
29
|
+
import type { FormEnhancements, FormSchema } from '../types/form-builder'
|
|
30
|
+
import {
|
|
31
|
+
controlsToSectionFormSchemas,
|
|
32
|
+
controlsToSidebarPanels,
|
|
33
|
+
defineControlModel,
|
|
34
|
+
getControlDefaults,
|
|
35
|
+
mergeControlWorkspaceOptions,
|
|
36
|
+
type ControlModel,
|
|
37
|
+
type ControlModelBinding,
|
|
38
|
+
type ControlSchema,
|
|
39
|
+
type ControlWorkspaceOptions,
|
|
40
|
+
} from '../composables/useControlSchema'
|
|
27
41
|
import CollapsibleCard from './CollapsibleCard.vue'
|
|
42
|
+
import FormBuilder from './FormBuilder.vue'
|
|
28
43
|
|
|
29
44
|
interface Props {
|
|
30
45
|
/** Map of view IDs to their tool sections */
|
|
@@ -41,6 +56,36 @@ interface Props {
|
|
|
41
56
|
side?: 'left' | 'right'
|
|
42
57
|
/** Toggle state map: sectionId → boolean */
|
|
43
58
|
toggleState?: Record<string, boolean>
|
|
59
|
+
/** Optional FormBuilder schemas keyed by section ID. Used when no section slot is provided. */
|
|
60
|
+
forms?: Record<string, FormSchema>
|
|
61
|
+
/** Generated view IDs from useControlSchema(). Consumed for clean v-bind ergonomics. */
|
|
62
|
+
viewIds?: string[]
|
|
63
|
+
/** Generated AppPillNav-compatible view items from useControlSchema(). Consumed for clean v-bind ergonomics. */
|
|
64
|
+
viewItems?: PillNavItem[]
|
|
65
|
+
/** Default view ID used when activeView is omitted. */
|
|
66
|
+
defaultView?: string
|
|
67
|
+
/** Model returned by defineControlModel(), or a raw nested ControlModel for one-step sidebar/form generation. */
|
|
68
|
+
model?: ControlModel | ControlModelBinding
|
|
69
|
+
/** Compact control schema. When provided, AppSidebar generates panels, section forms, and default values. */
|
|
70
|
+
controls?: ControlSchema
|
|
71
|
+
/** Options passed to compact control schema generation, including shared initialValues. */
|
|
72
|
+
controlOptions?: ControlWorkspaceOptions
|
|
73
|
+
/** Shared values for auto-rendered section forms. Supports default v-model. */
|
|
74
|
+
modelValue?: Record<string, unknown>
|
|
75
|
+
/** Shared values for auto-rendered section forms */
|
|
76
|
+
values?: Record<string, unknown>
|
|
77
|
+
/** Runtime FormBuilder enhancements for auto-rendered section forms */
|
|
78
|
+
formEnhancements?: FormEnhancements<Record<string, unknown>>
|
|
79
|
+
/** Show submit/cancel actions inside auto-rendered section forms */
|
|
80
|
+
showFormActions?: boolean
|
|
81
|
+
/** Loading/saving state for auto-rendered section forms */
|
|
82
|
+
formLoading?: boolean
|
|
83
|
+
/** Disabled state for auto-rendered section forms */
|
|
84
|
+
formDisabled?: boolean
|
|
85
|
+
/** Readonly state for auto-rendered section forms */
|
|
86
|
+
formReadonly?: boolean
|
|
87
|
+
/** Size passed to auto-rendered section forms */
|
|
88
|
+
formSize?: 'sm' | 'md' | 'lg'
|
|
44
89
|
}
|
|
45
90
|
|
|
46
91
|
const props = withDefaults(defineProps<Props>(), {
|
|
@@ -51,15 +96,76 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
51
96
|
width: '280px',
|
|
52
97
|
side: 'left',
|
|
53
98
|
toggleState: () => ({}),
|
|
99
|
+
forms: () => ({}),
|
|
100
|
+
viewIds: () => [],
|
|
101
|
+
viewItems: () => [],
|
|
102
|
+
defaultView: '',
|
|
103
|
+
model: undefined,
|
|
104
|
+
controlOptions: () => ({}),
|
|
105
|
+
modelValue: undefined,
|
|
106
|
+
values: () => ({}),
|
|
107
|
+
showFormActions: false,
|
|
108
|
+
formLoading: false,
|
|
109
|
+
formDisabled: false,
|
|
110
|
+
formReadonly: false,
|
|
111
|
+
formSize: 'sm',
|
|
54
112
|
})
|
|
55
113
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
114
|
+
const resolvedModel = computed<ControlModelBinding | undefined>(() => {
|
|
115
|
+
if (props.model === undefined) return undefined
|
|
116
|
+
return isControlModelBinding(props.model) ? props.model : defineControlModel(props.model)
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
const resolvedControls = computed<ControlSchema | undefined>(() =>
|
|
120
|
+
props.controls ?? resolvedModel.value?.controls,
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
const resolvedControlOptions = computed<ControlWorkspaceOptions>(() =>
|
|
124
|
+
mergeControlWorkspaceOptions(resolvedModel.value?.controlOptions ?? {}, props.controlOptions)
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
const generatedPanels = computed<Record<string, SidebarToolSection[]>>(() => {
|
|
128
|
+
if (!resolvedControls.value) return {}
|
|
129
|
+
return controlsToSidebarPanels(resolvedControls.value, resolvedControlOptions.value)
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
const generatedForms = computed<Record<string, FormSchema>>(() => {
|
|
133
|
+
if (!resolvedControls.value) return {}
|
|
134
|
+
return controlsToSectionFormSchemas(resolvedControls.value, resolvedControlOptions.value)
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
const generatedDefaults = computed<Record<string, unknown>>(() => {
|
|
138
|
+
if (!resolvedControls.value) return {}
|
|
139
|
+
return {
|
|
140
|
+
...getControlDefaults(resolvedControls.value),
|
|
141
|
+
...(resolvedControlOptions.value.initialValues ?? {}),
|
|
142
|
+
}
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
const resolvedPanels = computed<Record<string, SidebarToolSection[]>>(() =>
|
|
146
|
+
mergeSidebarPanels(generatedPanels.value, props.panels),
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
const resolvedForms = computed<Record<string, FormSchema>>(() => ({
|
|
150
|
+
...generatedForms.value,
|
|
151
|
+
...props.forms,
|
|
152
|
+
}))
|
|
153
|
+
|
|
154
|
+
const resolvedValues = computed<Record<string, unknown>>(() => ({
|
|
155
|
+
...generatedDefaults.value,
|
|
156
|
+
...(props.modelValue ?? props.values),
|
|
157
|
+
}))
|
|
158
|
+
|
|
159
|
+
const resolvedActiveView = computed(() => {
|
|
160
|
+
if (props.activeView) return props.activeView
|
|
161
|
+
if (props.defaultView) return props.defaultView
|
|
162
|
+
if (!resolvedControls.value) return ''
|
|
163
|
+
return firstVisibleViewId(resolvedPanels.value)
|
|
164
|
+
})
|
|
59
165
|
|
|
60
166
|
const activeSections = computed<SidebarToolSection[]>(() => {
|
|
61
|
-
if (!
|
|
62
|
-
return
|
|
167
|
+
if (!resolvedActiveView.value || !resolvedPanels.value[resolvedActiveView.value]) return []
|
|
168
|
+
return resolvedPanels.value[resolvedActiveView.value]
|
|
63
169
|
})
|
|
64
170
|
|
|
65
171
|
const isVisible = computed(() => activeSections.value.length > 0)
|
|
@@ -75,6 +181,60 @@ const sidebarClasses = computed(() => [
|
|
|
75
181
|
const sidebarStyle = computed(() => ({
|
|
76
182
|
width: props.width,
|
|
77
183
|
}))
|
|
184
|
+
|
|
185
|
+
const emit = defineEmits<{
|
|
186
|
+
'update:toggle': [sectionId: string, value: boolean]
|
|
187
|
+
'update:modelValue': [values: Record<string, unknown>]
|
|
188
|
+
'update:values': [values: Record<string, unknown>]
|
|
189
|
+
'form-submit': [sectionId: string, values: Record<string, unknown>]
|
|
190
|
+
'form-cancel': [sectionId: string]
|
|
191
|
+
}>()
|
|
192
|
+
|
|
193
|
+
function handleFormUpdate(values: Record<string, unknown>) {
|
|
194
|
+
const nextValues = { ...resolvedValues.value, ...values }
|
|
195
|
+
emit('update:modelValue', nextValues)
|
|
196
|
+
emit('update:values', nextValues)
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function handleFormSubmit(sectionId: string, values: Record<string, unknown>) {
|
|
200
|
+
emit('form-submit', sectionId, values)
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function handleFormCancel(sectionId: string) {
|
|
204
|
+
emit('form-cancel', sectionId)
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function mergeSidebarPanels(
|
|
208
|
+
generated: Record<string, SidebarToolSection[]>,
|
|
209
|
+
explicit: Record<string, SidebarToolSection[]>,
|
|
210
|
+
): Record<string, SidebarToolSection[]> {
|
|
211
|
+
const merged: Record<string, SidebarToolSection[]> = {}
|
|
212
|
+
const viewIds = new Set([...Object.keys(generated), ...Object.keys(explicit)])
|
|
213
|
+
|
|
214
|
+
for (const viewId of viewIds) {
|
|
215
|
+
const sectionsById = new Map<string, SidebarToolSection>()
|
|
216
|
+
for (const section of generated[viewId] ?? []) {
|
|
217
|
+
sectionsById.set(section.id, section)
|
|
218
|
+
}
|
|
219
|
+
for (const section of explicit[viewId] ?? []) {
|
|
220
|
+
sectionsById.set(section.id, section)
|
|
221
|
+
}
|
|
222
|
+
merged[viewId] = [...sectionsById.values()]
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return merged
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function firstVisibleViewId(panels: Record<string, SidebarToolSection[]>): string {
|
|
229
|
+
for (const [viewId, sections] of Object.entries(panels)) {
|
|
230
|
+
if (sections.length > 0) return viewId
|
|
231
|
+
}
|
|
232
|
+
return ''
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
function isControlModelBinding(model: ControlModel | ControlModelBinding): model is ControlModelBinding {
|
|
236
|
+
return 'controls' in model && 'controlOptions' in model
|
|
237
|
+
}
|
|
78
238
|
</script>
|
|
79
239
|
|
|
80
240
|
<template>
|
|
@@ -101,9 +261,24 @@ const sidebarStyle = computed(() => ({
|
|
|
101
261
|
:default-open="section.defaultOpen !== false"
|
|
102
262
|
:show-toggle="section.showToggle"
|
|
103
263
|
:toggle-value="toggleState[section.id] ?? false"
|
|
104
|
-
@update:toggle-value="
|
|
264
|
+
@update:toggle-value="emit('update:toggle', section.id, $event)"
|
|
105
265
|
>
|
|
106
|
-
<slot :name="`section-${section.id}`"
|
|
266
|
+
<slot :name="`section-${section.id}`">
|
|
267
|
+
<FormBuilder
|
|
268
|
+
v-if="resolvedForms[section.id]"
|
|
269
|
+
:model-value="resolvedValues"
|
|
270
|
+
:schema="resolvedForms[section.id]"
|
|
271
|
+
:enhancements="formEnhancements"
|
|
272
|
+
:loading="formLoading"
|
|
273
|
+
:disabled="formDisabled"
|
|
274
|
+
:readonly="formReadonly"
|
|
275
|
+
:size="formSize"
|
|
276
|
+
:show-actions="showFormActions"
|
|
277
|
+
@update:model-value="handleFormUpdate"
|
|
278
|
+
@submit="handleFormSubmit(section.id, $event)"
|
|
279
|
+
@cancel="handleFormCancel(section.id)"
|
|
280
|
+
/>
|
|
281
|
+
</slot>
|
|
107
282
|
</CollapsibleCard>
|
|
108
283
|
</div>
|
|
109
284
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import
|
|
2
|
+
import AppToastContainer from './AppToastContainer.vue'
|
|
3
3
|
import { useToast } from '../composables/useToast'
|
|
4
4
|
|
|
5
5
|
const toast = useToast()
|
|
@@ -34,7 +34,7 @@ function triggerLongToast(type: 'success' | 'error') {
|
|
|
34
34
|
</script>
|
|
35
35
|
|
|
36
36
|
<template>
|
|
37
|
-
<Story title="Feedback/
|
|
37
|
+
<Story title="Feedback/AppToastContainer">
|
|
38
38
|
<Variant title="Playground">
|
|
39
39
|
<template #default="{ state }">
|
|
40
40
|
<div style="padding: 2rem; display: flex; flex-direction: column; align-items: center; gap: 1rem;">
|
|
@@ -71,7 +71,7 @@ function triggerLongToast(type: 'success' | 'error') {
|
|
|
71
71
|
Info
|
|
72
72
|
</button>
|
|
73
73
|
</div>
|
|
74
|
-
<
|
|
74
|
+
<AppToastContainer />
|
|
75
75
|
</div>
|
|
76
76
|
</template>
|
|
77
77
|
|
|
@@ -112,7 +112,7 @@ function triggerLongToast(type: 'success' | 'error') {
|
|
|
112
112
|
Info Toast
|
|
113
113
|
</button>
|
|
114
114
|
</div>
|
|
115
|
-
<
|
|
115
|
+
<AppToastContainer />
|
|
116
116
|
</div>
|
|
117
117
|
</Variant>
|
|
118
118
|
|
|
@@ -128,7 +128,7 @@ function triggerLongToast(type: 'success' | 'error') {
|
|
|
128
128
|
<p style="margin: 0; color: var(--text-muted, #94a3b8); font-size: 0.75rem;">
|
|
129
129
|
Click to see multiple toasts stacked. Click any toast to dismiss it.
|
|
130
130
|
</p>
|
|
131
|
-
<
|
|
131
|
+
<AppToastContainer />
|
|
132
132
|
</div>
|
|
133
133
|
</Variant>
|
|
134
134
|
<Variant title="Progress bar — 4s / 6s TTL">
|
|
@@ -150,7 +150,7 @@ function triggerLongToast(type: 'success' | 'error') {
|
|
|
150
150
|
<p style="margin: 0; font-size: 0.8125rem; color: var(--text-muted);">
|
|
151
151
|
Watch the bottom progress bar shrink over the toast's TTL.
|
|
152
152
|
</p>
|
|
153
|
-
<
|
|
153
|
+
<AppToastContainer />
|
|
154
154
|
</div>
|
|
155
155
|
</Variant>
|
|
156
156
|
</Story>
|