@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
package/src/types/components.ts
CHANGED
|
@@ -34,7 +34,11 @@ export interface TabItem {
|
|
|
34
34
|
badge?: string | number
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
export type TabItemInput = TabItem | string
|
|
38
|
+
|
|
37
39
|
// Select types
|
|
40
|
+
export type OptionPrimitive = string | number
|
|
41
|
+
|
|
38
42
|
export interface SelectOption<T = string> {
|
|
39
43
|
value: T
|
|
40
44
|
label: string
|
|
@@ -42,6 +46,8 @@ export interface SelectOption<T = string> {
|
|
|
42
46
|
description?: string
|
|
43
47
|
}
|
|
44
48
|
|
|
49
|
+
export type SelectOptionInput<T extends OptionPrimitive = OptionPrimitive> = SelectOption<T> | T
|
|
50
|
+
|
|
45
51
|
// Radio types
|
|
46
52
|
export interface RadioOption {
|
|
47
53
|
value: string | number
|
|
@@ -50,6 +56,8 @@ export interface RadioOption {
|
|
|
50
56
|
description?: string
|
|
51
57
|
}
|
|
52
58
|
|
|
59
|
+
export type RadioOptionInput = RadioOption | OptionPrimitive
|
|
60
|
+
|
|
53
61
|
// Form field types
|
|
54
62
|
export interface FormFieldProps {
|
|
55
63
|
label?: string
|
|
@@ -92,6 +100,8 @@ export interface TopBarPage {
|
|
|
92
100
|
disabled?: boolean
|
|
93
101
|
}
|
|
94
102
|
|
|
103
|
+
export type TopBarPageInput = TopBarPage | string
|
|
104
|
+
|
|
95
105
|
// TopBar tab types (displayed in middle of topbar)
|
|
96
106
|
export interface TopBarTab {
|
|
97
107
|
id: string
|
|
@@ -112,16 +122,30 @@ export interface TopBarTabOption {
|
|
|
112
122
|
disabled?: boolean
|
|
113
123
|
}
|
|
114
124
|
|
|
125
|
+
export type TopBarTabOptionInput = TopBarTabOption | string
|
|
126
|
+
|
|
127
|
+
export type TopBarTabInput = (Omit<TopBarTab, 'children'> & {
|
|
128
|
+
children?: TopBarTabOptionInput[]
|
|
129
|
+
}) | string
|
|
130
|
+
|
|
115
131
|
// TopBar settings config (pass-through for built-in SettingsModal)
|
|
116
132
|
export interface TopBarSettingsConfig {
|
|
117
133
|
title?: string
|
|
118
|
-
tabs?:
|
|
134
|
+
tabs?: SettingsTabInput[]
|
|
119
135
|
showAppearance?: boolean
|
|
120
136
|
size?: 'md' | 'lg' | 'xl'
|
|
121
137
|
layout?: SettingsModalLayout
|
|
122
|
-
/** Schema-driven config — when set, fields auto-render via
|
|
138
|
+
/** Schema-driven config — when set, fields auto-render via SDK form components. */
|
|
123
139
|
schema?: SettingsModalSchema
|
|
124
|
-
/**
|
|
140
|
+
/** Model returned by defineControlModel(), or a raw nested ControlModel for one-step settings generation. */
|
|
141
|
+
model?:
|
|
142
|
+
| import('../composables/useControlSchema').ControlModel
|
|
143
|
+
| import('../composables/useControlSchema').ControlModelBinding
|
|
144
|
+
/** Compact controls model — converted to `schema` when `schema` is not set. */
|
|
145
|
+
controls?: import('../composables/useControlSchema').ControlSchema
|
|
146
|
+
/** Conversion options for `controls`, such as section labels and columns. */
|
|
147
|
+
controlOptions?: import('../composables/useControlSchema').ControlSchemaOptions
|
|
148
|
+
/** Initial values when using `schema`, `model`, or `controls`. AppTopBar emits `settings-values-change` on change. */
|
|
125
149
|
values?: Record<string, unknown>
|
|
126
150
|
/** Dynamic enhancements (validators, dynamic options, callbacks). Forwarded to SettingsModal. */
|
|
127
151
|
enhancements?: import('./form-builder').FormEnhancements
|
|
@@ -131,11 +155,14 @@ export interface TopBarSettingsConfig {
|
|
|
131
155
|
export interface PillNavItem {
|
|
132
156
|
id: string
|
|
133
157
|
label: string
|
|
158
|
+
icon?: string | string[]
|
|
134
159
|
to?: string
|
|
135
160
|
href?: string
|
|
136
161
|
disabled?: boolean
|
|
137
162
|
}
|
|
138
163
|
|
|
164
|
+
export type PillNavItemInput = PillNavItem | string
|
|
165
|
+
|
|
139
166
|
// TopBar page selector items (left-side "go to page" dropdown)
|
|
140
167
|
export interface PageSelectorItem {
|
|
141
168
|
id: string
|
|
@@ -147,6 +174,8 @@ export interface PageSelectorItem {
|
|
|
147
174
|
disabled?: boolean
|
|
148
175
|
}
|
|
149
176
|
|
|
177
|
+
export type PageSelectorItemInput = PageSelectorItem | string
|
|
178
|
+
|
|
150
179
|
// TopBar plugin switcher info
|
|
151
180
|
export interface PluginSwitcherPlugin {
|
|
152
181
|
id: string
|
|
@@ -385,6 +414,8 @@ export interface SegmentedOption {
|
|
|
385
414
|
disabled?: boolean
|
|
386
415
|
}
|
|
387
416
|
|
|
417
|
+
export type SegmentedOptionInput = SegmentedOption | OptionPrimitive
|
|
418
|
+
|
|
388
419
|
export type SegmentedControlVariant = 'simple' | 'card'
|
|
389
420
|
export type SegmentedControlSize = 'sm' | 'md' | 'lg'
|
|
390
421
|
|
|
@@ -395,6 +426,8 @@ export interface MultiSelectOption {
|
|
|
395
426
|
disabled?: boolean
|
|
396
427
|
}
|
|
397
428
|
|
|
429
|
+
export type MultiSelectOptionInput = MultiSelectOption | OptionPrimitive
|
|
430
|
+
|
|
398
431
|
export type MultiSelectSize = 'sm' | 'md' | 'lg'
|
|
399
432
|
|
|
400
433
|
// Pill types
|
|
@@ -514,6 +547,8 @@ export interface BreadcrumbItem {
|
|
|
514
547
|
href?: string
|
|
515
548
|
}
|
|
516
549
|
|
|
550
|
+
export type BreadcrumbItemInput = BreadcrumbItem | string
|
|
551
|
+
|
|
517
552
|
// Tooltip types
|
|
518
553
|
export type TooltipPosition = 'top' | 'bottom' | 'left' | 'right'
|
|
519
554
|
|
|
@@ -533,10 +568,12 @@ export interface SettingsTab {
|
|
|
533
568
|
description?: string
|
|
534
569
|
}
|
|
535
570
|
|
|
571
|
+
export type SettingsTabInput = SettingsTab | string
|
|
572
|
+
|
|
536
573
|
export type SettingsModalLayout = 'horizontal' | 'vertical'
|
|
537
574
|
|
|
538
575
|
/**
|
|
539
|
-
* Declarative settings group — becomes both a tab and a
|
|
576
|
+
* Declarative settings group — becomes both a tab and a generated form section.
|
|
540
577
|
* Plugin authors describe their parameters once and the modal auto-renders
|
|
541
578
|
* SDK form components (BaseInput / BaseSelect / NumberInput / Toggle / …)
|
|
542
579
|
* via the same registry that powers FormBuilder.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { FieldRules } from '../composables/useForm'
|
|
2
|
+
import type { OptionPrimitive, SelectOption } from './components'
|
|
2
3
|
|
|
3
4
|
// ---------------------------------------------------------------------------
|
|
4
5
|
// Field types
|
|
@@ -88,6 +89,8 @@ export interface FormFieldSchema {
|
|
|
88
89
|
props?: Record<string, unknown>
|
|
89
90
|
}
|
|
90
91
|
|
|
92
|
+
export type FormOptionInput = SelectOption<unknown> | OptionPrimitive
|
|
93
|
+
|
|
91
94
|
// ---------------------------------------------------------------------------
|
|
92
95
|
// Section schema
|
|
93
96
|
// ---------------------------------------------------------------------------
|
|
@@ -147,7 +150,7 @@ export interface FieldEnhancement<T extends Record<string, unknown> = Record<str
|
|
|
147
150
|
/** Dynamic visibility (overrides schema condition if both present). */
|
|
148
151
|
visible?: (data: T) => boolean
|
|
149
152
|
/** Dynamic options for select/multiselect/radio fields. */
|
|
150
|
-
options?: (data: T) =>
|
|
153
|
+
options?: (data: T) => FormOptionInput[]
|
|
151
154
|
/** Dynamic extra props merged into the component. */
|
|
152
155
|
props?: (data: T) => Record<string, unknown>
|
|
153
156
|
}
|
|
@@ -181,7 +184,7 @@ export interface UseFormBuilderReturn<T extends Record<string, unknown>> {
|
|
|
181
184
|
/** Resolve final component props for a field. */
|
|
182
185
|
getResolvedFieldProps: (field: FormFieldSchema) => Record<string, unknown>
|
|
183
186
|
/** Get options for a select/radio/multiselect field. */
|
|
184
|
-
getFieldOptions: (name: string) =>
|
|
187
|
+
getFieldOptions: (name: string) => FormOptionInput[] | undefined
|
|
185
188
|
|
|
186
189
|
// Wizard-specific
|
|
187
190
|
currentStep: import('vue').Ref<number>
|
|
@@ -194,4 +197,6 @@ export interface UseFormBuilderReturn<T extends Record<string, unknown>> {
|
|
|
194
197
|
validate: () => boolean
|
|
195
198
|
reset: (values?: Partial<T>) => void
|
|
196
199
|
submit: () => Promise<void>
|
|
200
|
+
/** Replace the active schema and rebuild field state for still-mounted forms. */
|
|
201
|
+
updateSchema: (schema: FormSchema, values?: Partial<T>) => void
|
|
197
202
|
}
|
package/src/types/index.ts
CHANGED
|
@@ -9,18 +9,27 @@ export type {
|
|
|
9
9
|
AlertType,
|
|
10
10
|
Toast,
|
|
11
11
|
TabItem,
|
|
12
|
+
TabItemInput,
|
|
13
|
+
OptionPrimitive,
|
|
12
14
|
SelectOption,
|
|
15
|
+
SelectOptionInput,
|
|
13
16
|
RadioOption,
|
|
17
|
+
RadioOptionInput,
|
|
14
18
|
FormFieldProps,
|
|
15
19
|
SidebarToolSection,
|
|
16
20
|
CollapsibleState,
|
|
17
21
|
TopBarVariant,
|
|
18
22
|
TopBarPage,
|
|
23
|
+
TopBarPageInput,
|
|
19
24
|
TopBarTab,
|
|
25
|
+
TopBarTabInput,
|
|
20
26
|
TopBarTabOption,
|
|
27
|
+
TopBarTabOptionInput,
|
|
21
28
|
TopBarSettingsConfig,
|
|
22
29
|
PillNavItem,
|
|
30
|
+
PillNavItemInput,
|
|
23
31
|
PageSelectorItem,
|
|
32
|
+
PageSelectorItemInput,
|
|
24
33
|
PluginSwitcherPlugin,
|
|
25
34
|
PluginSwitcherInfo,
|
|
26
35
|
AccountMenuItem,
|
|
@@ -58,10 +67,12 @@ export type {
|
|
|
58
67
|
FileUploaderMode,
|
|
59
68
|
// SegmentedControl types
|
|
60
69
|
SegmentedOption,
|
|
70
|
+
SegmentedOptionInput,
|
|
61
71
|
SegmentedControlVariant,
|
|
62
72
|
SegmentedControlSize,
|
|
63
73
|
// MultiSelect types
|
|
64
74
|
MultiSelectOption,
|
|
75
|
+
MultiSelectOptionInput,
|
|
65
76
|
MultiSelectSize,
|
|
66
77
|
// Pill types
|
|
67
78
|
PillVariant,
|
|
@@ -93,12 +104,14 @@ export type {
|
|
|
93
104
|
EmptyStateSize,
|
|
94
105
|
// Breadcrumb types
|
|
95
106
|
BreadcrumbItem,
|
|
107
|
+
BreadcrumbItemInput,
|
|
96
108
|
// Tooltip types
|
|
97
109
|
TooltipPosition,
|
|
98
110
|
// ConfirmDialog types
|
|
99
111
|
ConfirmVariant,
|
|
100
112
|
// SettingsModal types
|
|
101
113
|
SettingsTab,
|
|
114
|
+
SettingsTabInput,
|
|
102
115
|
SettingsModalLayout,
|
|
103
116
|
SettingsGroup,
|
|
104
117
|
SettingsModalSchema,
|
|
@@ -163,6 +176,7 @@ export type {
|
|
|
163
176
|
FieldCondition,
|
|
164
177
|
FieldValidation,
|
|
165
178
|
FormFieldSchema,
|
|
179
|
+
FormOptionInput,
|
|
166
180
|
FormSectionSchema,
|
|
167
181
|
FormStepSchema,
|
|
168
182
|
FormSchema,
|
package/src/types/platform.ts
CHANGED
|
@@ -14,10 +14,14 @@ export interface PluginInfo {
|
|
|
14
14
|
|
|
15
15
|
// Plugin navigation item
|
|
16
16
|
export interface PluginNavItem {
|
|
17
|
-
id
|
|
17
|
+
id?: string
|
|
18
18
|
label: string
|
|
19
19
|
path: string
|
|
20
20
|
icon?: string
|
|
21
|
+
description?: string
|
|
22
|
+
requiresAuth?: boolean
|
|
23
|
+
requiresAdmin?: boolean
|
|
24
|
+
requiresFeature?: string
|
|
21
25
|
children?: PluginNavItem[]
|
|
22
26
|
}
|
|
23
27
|
|
|
@@ -82,7 +86,9 @@ export interface PlatformContext {
|
|
|
82
86
|
|
|
83
87
|
// Features enabled in platform
|
|
84
88
|
features?: {
|
|
89
|
+
admin?: boolean
|
|
85
90
|
experiments?: boolean
|
|
91
|
+
samples?: boolean
|
|
86
92
|
passkey?: boolean
|
|
87
93
|
multiUser?: boolean
|
|
88
94
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { FormSchema } from '../types/form-builder'
|
|
2
|
+
|
|
3
|
+
export function recordValuesEqualForKeys(
|
|
4
|
+
left: Record<string, unknown>,
|
|
5
|
+
right: Record<string, unknown>,
|
|
6
|
+
keys: readonly string[],
|
|
7
|
+
): boolean {
|
|
8
|
+
for (const key of keys) {
|
|
9
|
+
if (!valuesEqual(left[key], right[key])) return false
|
|
10
|
+
}
|
|
11
|
+
return true
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function pickRecordKeys(
|
|
15
|
+
source: Record<string, unknown>,
|
|
16
|
+
keys: readonly string[],
|
|
17
|
+
): Record<string, unknown> {
|
|
18
|
+
return Object.fromEntries(keys.map(key => [key, source[key]]))
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function pickExistingRecordKeys(
|
|
22
|
+
source: Record<string, unknown>,
|
|
23
|
+
keys: readonly string[],
|
|
24
|
+
): Record<string, unknown> {
|
|
25
|
+
return Object.fromEntries(
|
|
26
|
+
keys
|
|
27
|
+
.filter(key => Object.prototype.hasOwnProperty.call(source, key))
|
|
28
|
+
.map(key => [key, source[key]]),
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function formSchemaFieldNames(schema: FormSchema): string[] {
|
|
33
|
+
const sections = schema.steps
|
|
34
|
+
? schema.steps.flatMap(step => step.sections)
|
|
35
|
+
: schema.sections
|
|
36
|
+
return sections.flatMap(section => section.fields.map(field => field.name))
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function valuesEqual(left: unknown, right: unknown): boolean {
|
|
40
|
+
if (Object.is(left, right)) return true
|
|
41
|
+
if (Array.isArray(left) && Array.isArray(right)) {
|
|
42
|
+
return left.length === right.length && left.every((item, index) => valuesEqual(item, right[index]))
|
|
43
|
+
}
|
|
44
|
+
if (isRecord(left) && isRecord(right)) {
|
|
45
|
+
return recordValuesEqualForKeys(left, right, [...new Set([...Object.keys(left), ...Object.keys(right)])])
|
|
46
|
+
}
|
|
47
|
+
return false
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
51
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value)
|
|
52
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export type ItemWithLabel = {
|
|
2
|
+
label: string
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export type ItemWithId = ItemWithLabel & {
|
|
6
|
+
id: string
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function normalizeItemInput<TItem extends ItemWithId>(
|
|
10
|
+
item: TItem | string,
|
|
11
|
+
): TItem {
|
|
12
|
+
if (typeof item === 'object') return item
|
|
13
|
+
|
|
14
|
+
return {
|
|
15
|
+
id: item,
|
|
16
|
+
label: item,
|
|
17
|
+
} as TItem
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function normalizeLabelItemInput<TItem extends ItemWithLabel>(
|
|
21
|
+
item: TItem | string,
|
|
22
|
+
): TItem {
|
|
23
|
+
if (typeof item === 'object') return item
|
|
24
|
+
|
|
25
|
+
return {
|
|
26
|
+
label: item,
|
|
27
|
+
} as TItem
|
|
28
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type OptionLike<TValue extends string | number> = {
|
|
2
|
+
value: TValue
|
|
3
|
+
label: string
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export function normalizeOptionInput<
|
|
7
|
+
TValue extends string | number,
|
|
8
|
+
TOption extends OptionLike<TValue>,
|
|
9
|
+
>(option: TOption | TValue): TOption {
|
|
10
|
+
if (typeof option === 'object') return option
|
|
11
|
+
|
|
12
|
+
return {
|
|
13
|
+
value: option,
|
|
14
|
+
label: String(option),
|
|
15
|
+
} as TOption
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function findOptionByDomValue<
|
|
19
|
+
TValue extends string | number,
|
|
20
|
+
TOption extends OptionLike<TValue>,
|
|
21
|
+
>(options: TOption[], value: string): TOption | undefined {
|
|
22
|
+
return options.find(option => String(option.value) === value)
|
|
23
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export type PluginIconFormat = 'path' | 'data-url' | 'https-url' | 'fallback'
|
|
2
|
+
|
|
3
|
+
export interface DetectedPluginIcon {
|
|
4
|
+
format: PluginIconFormat
|
|
5
|
+
value: string
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// MINT canonical plugin placeholder — page-with-corner-fold glyph.
|
|
9
|
+
export const PLUGIN_ICON_FALLBACK_PATH = 'M14 7v4a1 1 0 0 0 1 1h4M5 3h9l5 5v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z'
|
|
10
|
+
|
|
11
|
+
const PATH_REGEX = /^[Mm][\s,\d\-.]/
|
|
12
|
+
const RASTER_DATA_URL_REGEX = /^data:image\/(png|jpeg|jpg|gif|webp);/
|
|
13
|
+
|
|
14
|
+
export function normalizePluginIconSource(icon?: string): string {
|
|
15
|
+
return (icon ?? '').replace(/^[\s]+/, '')
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function detectPluginIcon(icon?: string): DetectedPluginIcon {
|
|
19
|
+
const raw = normalizePluginIconSource(icon)
|
|
20
|
+
if (!raw) return { format: 'fallback', value: PLUGIN_ICON_FALLBACK_PATH }
|
|
21
|
+
if (PATH_REGEX.test(raw)) return { format: 'path', value: raw }
|
|
22
|
+
if (RASTER_DATA_URL_REGEX.test(raw)) return { format: 'data-url', value: raw }
|
|
23
|
+
if (raw.startsWith('https://')) return { format: 'https-url', value: raw }
|
|
24
|
+
return { format: 'fallback', value: PLUGIN_ICON_FALLBACK_PATH }
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function isPluginIconFormat(icon?: string): boolean {
|
|
28
|
+
const raw = normalizePluginIconSource(icon)
|
|
29
|
+
return !!raw && detectPluginIcon(raw).format !== 'fallback'
|
|
30
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auth-DsI0rQ7_.js","names":[],"sources":["../src/stores/settings.ts","../src/stores/auth.ts"],"sourcesContent":["import { defineStore } from 'pinia'\nimport { ref, watch } from 'vue'\nimport type { ThemeMode, ColorPalette, TableDensity } from '../types'\n\ndeclare global {\n interface ImportMetaEnv {\n readonly VITE_API_PREFIX?: string\n }\n\n interface ImportMeta {\n readonly env: ImportMetaEnv\n }\n}\n\nexport interface SettingsState {\n serverHost: string\n serverPort: number\n requestTimeout: number\n wsAutoReconnect: boolean\n wsReconnectInterval: number\n theme: ThemeMode\n colorPalette: ColorPalette\n tableDensity: TableDensity\n}\n\nconst STORAGE_KEY = 'mint-settings'\n\nfunction getDefaultServerHost(): string {\n if (typeof window !== 'undefined' && window.location.hostname !== 'localhost') {\n return window.location.hostname\n }\n return 'localhost'\n}\n\nfunction getDefaultServerPort(): number {\n if (typeof window !== 'undefined') {\n if (window.location.port) {\n return parseInt(window.location.port, 10)\n }\n // Standard ports: 443 for HTTPS, 80 for HTTP (browser omits from location.port)\n return window.location.protocol === 'https:' ? 443 : 80\n }\n return 8000\n}\n\nconst defaultSettings: SettingsState = {\n serverHost: getDefaultServerHost(),\n serverPort: getDefaultServerPort(),\n requestTimeout: 120000,\n wsAutoReconnect: true,\n wsReconnectInterval: 5000,\n theme: 'system',\n colorPalette: 'default',\n tableDensity: 'normal',\n}\n\nexport const colorPalettes: Record<ColorPalette, { name: string; hues: [number, number] }> = {\n default: { name: 'Default (Cyan-Pink)', hues: [180, 320] },\n colorblind: { name: 'Colorblind-friendly', hues: [45, 260] },\n viridis: { name: 'Viridis', hues: [280, 80] },\n pastel: { name: 'Pastel', hues: [200, 340] },\n}\n\nfunction loadSettings(): SettingsState {\n try {\n const stored = localStorage.getItem(STORAGE_KEY)\n if (stored) {\n const parsed = JSON.parse(stored)\n return { ...defaultSettings, ...parsed }\n }\n } catch (e) {\n console.warn('Failed to load settings from localStorage:', e)\n }\n return { ...defaultSettings }\n}\n\nfunction saveSettings(settings: SettingsState): void {\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(settings))\n } catch (e) {\n console.warn('Failed to save settings to localStorage:', e)\n }\n}\n\nexport const useSettingsStore = defineStore('mint-settings', () => {\n // State\n const serverHost = ref(defaultSettings.serverHost)\n const serverPort = ref(defaultSettings.serverPort)\n const requestTimeout = ref(defaultSettings.requestTimeout)\n const wsAutoReconnect = ref(defaultSettings.wsAutoReconnect)\n const wsReconnectInterval = ref(defaultSettings.wsReconnectInterval)\n const theme = ref<ThemeMode>(defaultSettings.theme)\n const colorPalette = ref<ColorPalette>(defaultSettings.colorPalette)\n const tableDensity = ref<TableDensity>(defaultSettings.tableDensity)\n\n // API prefix - can be configured via env variable VITE_API_PREFIX\n const apiPrefix: string = (import.meta.env?.VITE_API_PREFIX as string | undefined) ?? '/api'\n\n function _isSameOrigin(): { same: boolean; currentHost: string; currentPort: string } {\n const currentHost = typeof window !== 'undefined' ? window.location.hostname : 'localhost'\n const currentPort = typeof window !== 'undefined' ? window.location.port : '8000'\n const effectivePort = currentPort || (window.location.protocol === 'https:' ? '443' : '80')\n const same =\n (serverHost.value === currentHost && String(serverPort.value) === effectivePort) ||\n (serverHost.value === 'localhost' && currentHost !== 'localhost')\n return { same, currentHost, currentPort }\n }\n\n function getApiBaseUrl(): string {\n const { same } = _isSameOrigin()\n if (same) return apiPrefix\n return `http://${serverHost.value}:${serverPort.value}${apiPrefix}`\n }\n\n function getWsBaseUrl(): string {\n const { same, currentHost, currentPort } = _isSameOrigin()\n const protocol = typeof window !== 'undefined' && window.location.protocol === 'https:' ? 'wss:' : 'ws:'\n if (same) return `${protocol}//${currentHost}${currentPort ? ':' + currentPort : ''}${apiPrefix}`\n return `ws://${serverHost.value}:${serverPort.value}${apiPrefix}`\n }\n\n let _initialized = false\n\n function initialize() {\n if (_initialized) return\n _initialized = true\n\n const loaded = loadSettings()\n serverHost.value = loaded.serverHost\n serverPort.value = loaded.serverPort\n requestTimeout.value = loaded.requestTimeout\n wsAutoReconnect.value = loaded.wsAutoReconnect\n wsReconnectInterval.value = loaded.wsReconnectInterval\n theme.value = loaded.theme\n colorPalette.value = loaded.colorPalette\n tableDensity.value = loaded.tableDensity\n\n applyTheme()\n }\n\n function applyTheme() {\n const dark = theme.value === 'system'\n ? window.matchMedia('(prefers-color-scheme: dark)').matches\n : theme.value === 'dark'\n document.documentElement.classList.toggle('dark', dark)\n }\n\n watch(theme, () => {\n applyTheme()\n persistSettings()\n })\n\n if (typeof window !== 'undefined') {\n window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {\n if (theme.value === 'system') {\n applyTheme()\n }\n })\n }\n\n function persistSettings() {\n saveSettings({\n serverHost: serverHost.value,\n serverPort: serverPort.value,\n requestTimeout: requestTimeout.value,\n wsAutoReconnect: wsAutoReconnect.value,\n wsReconnectInterval: wsReconnectInterval.value,\n theme: theme.value,\n colorPalette: colorPalette.value,\n tableDensity: tableDensity.value,\n })\n }\n\n watch([serverHost, serverPort, requestTimeout, wsAutoReconnect, wsReconnectInterval, colorPalette, tableDensity], () => {\n persistSettings()\n })\n\n function resetToDefaults() {\n serverHost.value = defaultSettings.serverHost\n serverPort.value = defaultSettings.serverPort\n requestTimeout.value = defaultSettings.requestTimeout\n wsAutoReconnect.value = defaultSettings.wsAutoReconnect\n wsReconnectInterval.value = defaultSettings.wsReconnectInterval\n theme.value = defaultSettings.theme\n colorPalette.value = defaultSettings.colorPalette\n tableDensity.value = defaultSettings.tableDensity\n }\n\n function getPaletteHues(): [number, number] {\n return colorPalettes[colorPalette.value].hues\n }\n\n function isDark(): boolean {\n if (theme.value === 'system') {\n return window.matchMedia('(prefers-color-scheme: dark)').matches\n }\n return theme.value === 'dark'\n }\n\n return {\n serverHost,\n serverPort,\n requestTimeout,\n wsAutoReconnect,\n wsReconnectInterval,\n theme,\n colorPalette,\n tableDensity,\n initialize,\n applyTheme,\n persistSettings,\n resetToDefaults,\n getPaletteHues,\n isDark,\n getApiBaseUrl,\n getWsBaseUrl,\n }\n})\n","import { defineStore } from 'pinia'\nimport { ref, computed } from 'vue'\nimport type { AuthConfig, UserInfo } from '../types'\n\nconst AUTH_TOKEN_KEY = 'mint-auth-token'\nconst AUTH_EXPIRES_KEY = 'mint-auth-expires'\n\nconst hasLocalStorage = typeof localStorage !== 'undefined' && typeof localStorage.getItem === 'function'\n\nexport const useAuthStore = defineStore('mint-auth', () => {\n // State\n const token = ref<string | null>(null)\n const tokenExpires = ref<Date | null>(null)\n const username = ref<string | null>(null)\n const userInfo = ref<UserInfo | null>(null)\n const authConfig = ref<AuthConfig>({\n authRequired: true,\n passkeyEnabled: false,\n passkeyRegistered: false,\n registrationEnabled: false,\n databaseMode: 'none',\n })\n const isInitialized = ref(false)\n const isLoading = ref(false)\n const error = ref<string | null>(null)\n\n // Computed\n const isAuthenticated = computed(() => {\n if (!authConfig.value.authRequired) {\n return true\n }\n if (!token.value) {\n return false\n }\n if (tokenExpires.value && tokenExpires.value < new Date()) {\n return false\n }\n return true\n })\n\n const needsAuth = computed(() => {\n return authConfig.value.authRequired && !isAuthenticated.value\n })\n\n const isAdmin = computed(() => {\n return userInfo.value?.role === 'admin'\n })\n\n const canRegister = computed(() => {\n return authConfig.value.registrationEnabled\n })\n\n // Actions\n function initialize() {\n if (hasLocalStorage) {\n const storedToken = localStorage.getItem(AUTH_TOKEN_KEY)\n const storedExpires = localStorage.getItem(AUTH_EXPIRES_KEY)\n\n if (storedToken) {\n token.value = storedToken\n\n if (storedExpires) {\n const expires = new Date(storedExpires)\n if (expires > new Date()) {\n tokenExpires.value = expires\n } else {\n clearToken()\n }\n }\n }\n }\n\n isInitialized.value = true\n }\n\n function setToken(accessToken: string, expiresIn: number) {\n token.value = accessToken\n const expires = new Date(Date.now() + expiresIn * 1000)\n tokenExpires.value = expires\n\n if (hasLocalStorage) {\n localStorage.setItem(AUTH_TOKEN_KEY, accessToken)\n localStorage.setItem(AUTH_EXPIRES_KEY, expires.toISOString())\n }\n }\n\n function clearToken() {\n token.value = null\n tokenExpires.value = null\n username.value = null\n userInfo.value = null\n\n if (hasLocalStorage) {\n localStorage.removeItem(AUTH_TOKEN_KEY)\n localStorage.removeItem(AUTH_EXPIRES_KEY)\n }\n }\n\n function setUserInfo(info: UserInfo) {\n userInfo.value = info\n username.value = info.username\n }\n\n function setAuthConfig(config: AuthConfig) {\n authConfig.value = config\n }\n\n function setUsername(name: string) {\n username.value = name\n }\n\n function setError(message: string | null) {\n error.value = message\n }\n\n function setLoading(loading: boolean) {\n isLoading.value = loading\n }\n\n function logout() {\n clearToken()\n }\n\n return {\n // State\n token,\n tokenExpires,\n username,\n userInfo,\n authConfig,\n isInitialized,\n isLoading,\n error,\n\n // Computed\n isAuthenticated,\n needsAuth,\n isAdmin,\n canRegister,\n\n // Actions\n initialize,\n setToken,\n clearToken,\n setAuthConfig,\n setUsername,\n setUserInfo,\n setError,\n setLoading,\n logout,\n }\n})\n"],"mappings":"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"}
|