@morscherlab/mint-sdk 1.0.0-beta.1 → 1.0.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +218 -6
- package/dist/__tests__/components/ActionItem.test.d.ts +1 -0
- package/dist/__tests__/components/AppAvatarMenu.test.d.ts +1 -0
- package/dist/__tests__/components/AppPageSelector.test.d.ts +1 -0
- package/dist/__tests__/components/AppPillNav.test.d.ts +1 -0
- package/dist/__tests__/components/AppPluginSwitcher.test.d.ts +1 -0
- package/dist/__tests__/components/AppToastContainer.test.d.ts +1 -0
- package/dist/__tests__/components/BaseRadioGroup.test.d.ts +1 -0
- package/dist/__tests__/components/BaseSelect.test.d.ts +1 -0
- package/dist/__tests__/components/BaseTabs.test.d.ts +1 -0
- package/dist/__tests__/components/BatchProgressList.test.d.ts +1 -0
- package/dist/__tests__/components/BioTemplateExperimentWorkspaceView.test.d.ts +1 -0
- package/dist/__tests__/components/BioTemplatePackWorkspaceView.test.d.ts +1 -0
- package/dist/__tests__/components/BioTemplatePresetWorkspaceView.test.d.ts +1 -0
- package/dist/__tests__/components/BioTemplateRenderer.test.d.ts +1 -0
- package/dist/__tests__/components/Breadcrumb.test.d.ts +1 -0
- package/dist/__tests__/components/CalendarGridPanel.test.d.ts +1 -0
- package/dist/__tests__/components/ConcentrationInput.test.d.ts +1 -0
- package/dist/__tests__/components/ControlWorkspaceView.test.d.ts +1 -0
- package/dist/__tests__/components/DatePicker.test.d.ts +1 -0
- package/dist/__tests__/components/DateTimePicker.test.d.ts +1 -0
- package/dist/__tests__/components/EmptyState.test.d.ts +1 -0
- package/dist/__tests__/components/ExperimentPopover.test.d.ts +1 -0
- package/dist/__tests__/components/FormBuilder.test.d.ts +1 -0
- package/dist/__tests__/components/FormCompatibility.test.d.ts +1 -0
- package/dist/__tests__/components/GroupAssigner.test.d.ts +1 -0
- package/dist/__tests__/components/GroupingModal.test.d.ts +1 -0
- package/dist/__tests__/components/MultiSelect.test.d.ts +1 -0
- package/dist/__tests__/components/PluginIcon.test.d.ts +1 -0
- package/dist/__tests__/components/ProtocolStepEditor.test.d.ts +1 -0
- package/dist/__tests__/components/ReagentList.test.d.ts +1 -0
- package/dist/__tests__/components/SampleHierarchyTree.test.d.ts +1 -0
- package/dist/__tests__/components/SampleSelector.test.d.ts +1 -0
- package/dist/__tests__/components/SegmentedControl.test.d.ts +1 -0
- package/dist/__tests__/components/SettingsButton.test.d.ts +1 -0
- package/dist/__tests__/components/SettingsModal.test.d.ts +1 -0
- package/dist/__tests__/components/TagsInput.test.d.ts +1 -0
- package/dist/__tests__/components/ThemeToggle.test.d.ts +1 -0
- package/dist/__tests__/components/TimePicker.test.d.ts +1 -0
- package/dist/__tests__/composables/useBioTemplatePackWorkspace.test.d.ts +1 -0
- package/dist/__tests__/composables/useBioTemplatePresetWorkspace.test.d.ts +1 -0
- package/dist/__tests__/composables/useBioTemplateWorkspace.test.d.ts +1 -0
- package/dist/__tests__/composables/useCalendarGrid.test.d.ts +1 -0
- package/dist/__tests__/composables/useControlSchema.test.d.ts +1 -0
- package/dist/__tests__/composables/useDebouncedWatch.test.d.ts +1 -0
- package/dist/__tests__/composables/useDropdownState.test.d.ts +1 -0
- package/dist/__tests__/composables/useEventListener.test.d.ts +1 -0
- package/dist/__tests__/composables/useExpansionSet.test.d.ts +1 -0
- package/dist/__tests__/composables/useExperimentData.test.d.ts +1 -0
- package/dist/__tests__/composables/useExperimentSelector.test.d.ts +1 -0
- package/dist/__tests__/composables/useGroupAssignment.test.d.ts +1 -0
- package/dist/__tests__/composables/useListSelection.test.d.ts +1 -0
- package/dist/__tests__/composables/usePluginClient.test.d.ts +1 -0
- package/dist/__tests__/composables/usePluginConfig.test.d.ts +1 -0
- package/dist/__tests__/composables/useRequestSyncState.test.d.ts +1 -0
- package/dist/__tests__/composables/useSampleGroups.test.d.ts +1 -0
- package/dist/__tests__/composables/useSelectionLimit.test.d.ts +1 -0
- package/dist/__tests__/composables/useSortedItems.test.d.ts +1 -0
- package/dist/__tests__/composables/useTemplateCollection.test.d.ts +1 -0
- package/dist/__tests__/composables/useTextSearch.test.d.ts +1 -0
- package/dist/__tests__/composables/useTheme.test.d.ts +1 -0
- package/dist/__tests__/composables/useTimeUtils.test.d.ts +1 -0
- package/dist/__tests__/docs/frontendDocsCatalog.test.d.ts +1 -0
- package/dist/__tests__/templates/templates.test.d.ts +1 -0
- package/dist/{auth-DsI0rQ7_.js → auth-QQj2kkze.js} +12 -5
- package/dist/auth-QQj2kkze.js.map +1 -0
- package/dist/components/ActionItem.vue.d.ts +32 -0
- package/dist/components/AppAvatarMenu.vue.d.ts +2 -7
- package/dist/components/AppPageSelector.vue.d.ts +3 -6
- package/dist/components/AppPillNav.vue.d.ts +2 -2
- package/dist/components/AppSidebar.vue.d.ts +56 -3
- package/dist/components/AppToastContainer.vue.d.ts +2 -0
- package/dist/components/AppTopBar.vue.d.ts +43 -10
- package/dist/components/BaseButton.vue.d.ts +2 -2
- package/dist/components/BaseCheckbox.vue.d.ts +1 -1
- package/dist/components/BaseInput.vue.d.ts +2 -2
- package/dist/components/BasePill.vue.d.ts +3 -3
- package/dist/components/BaseRadioGroup.vue.d.ts +4 -4
- package/dist/components/BaseSelect.vue.d.ts +4 -4
- package/dist/components/BaseSlider.vue.d.ts +1 -1
- package/dist/components/BaseTabs.vue.d.ts +2 -2
- package/dist/components/BaseTextarea.vue.d.ts +2 -2
- package/dist/components/BaseToggle.vue.d.ts +1 -1
- package/dist/components/BioTemplateExperimentWorkspaceView.vue.d.ts +117 -0
- package/dist/components/BioTemplatePackWorkspaceView.vue.d.ts +92 -0
- package/dist/components/BioTemplatePresetWorkspaceView.vue.d.ts +82 -0
- package/dist/components/BioTemplateRenderer.vue.d.ts +29 -0
- package/dist/components/Breadcrumb.vue.d.ts +2 -2
- package/dist/components/Calendar.vue.d.ts +1 -1
- package/dist/components/CalendarGridPanel.vue.d.ts +25 -0
- package/dist/components/CollapsibleCard.vue.d.ts +1 -1
- package/dist/components/ColorSlider.vue.d.ts +1 -1
- package/dist/components/ConcentrationInput.vue.d.ts +2 -2
- package/dist/components/ConfirmDialog.vue.d.ts +2 -2
- package/dist/components/ControlWorkspaceView.vue.d.ts +130 -0
- package/dist/components/DatePicker.vue.d.ts +2 -2
- package/dist/components/DateTimePicker.vue.d.ts +3 -3
- package/dist/components/DropdownButton.vue.d.ts +4 -4
- package/dist/components/EmptyState.vue.d.ts +1 -2
- package/dist/components/ExperimentDataViewer.vue.d.ts +1 -1
- package/dist/components/ExperimentTimeline.vue.d.ts +2 -2
- package/dist/components/FileUploader.vue.d.ts +2 -2
- package/dist/components/FitPanel.vue.d.ts +1 -1
- package/dist/components/FormActions.vue.d.ts +4 -4
- package/dist/components/FormBuilder.vue.d.ts +22 -8
- package/dist/components/FormFieldRenderer.vue.d.ts +7 -10
- package/dist/components/FormSection.vue.d.ts +11 -24
- package/dist/components/FormulaInput.vue.d.ts +2 -2
- package/dist/components/IconButton.vue.d.ts +1 -1
- package/dist/components/LoadingSpinner.vue.d.ts +1 -1
- package/dist/components/MoleculeInput.vue.d.ts +2 -2
- package/dist/components/MultiSelect.vue.d.ts +3 -3
- package/dist/components/NumberInput.vue.d.ts +2 -2
- package/dist/components/PluginIcon.vue.d.ts +11 -0
- package/dist/components/ProgressBar.vue.d.ts +2 -2
- package/dist/components/ProtocolStepEditor.vue.d.ts +3 -1
- package/dist/components/RackEditor.vue.d.ts +2 -2
- package/dist/components/ReagentEditor.vue.d.ts +1 -1
- package/dist/components/ResourceCard.vue.d.ts +1 -1
- package/dist/components/SampleLegend.vue.d.ts +2 -2
- package/dist/components/SampleSelector.vue.d.ts +1 -1
- package/dist/components/ScheduleCalendar.vue.d.ts +2 -2
- package/dist/components/ScientificNumber.vue.d.ts +1 -1
- package/dist/components/SegmentedControl.vue.d.ts +3 -3
- package/dist/components/SequenceInput.vue.d.ts +3 -3
- package/dist/components/SettingsButton.vue.d.ts +2 -2
- package/dist/components/SettingsModal.vue.d.ts +32 -4
- package/dist/components/StatusIndicator.vue.d.ts +1 -1
- package/dist/components/TagsInput.vue.d.ts +3 -2
- package/dist/components/TimePicker.vue.d.ts +3 -3
- package/dist/components/TimeRangeInput.vue.d.ts +2 -2
- package/dist/components/UnitInput.vue.d.ts +2 -2
- package/dist/components/WellPlate.vue.d.ts +8 -8
- package/dist/components/index.d.ts +12 -1
- package/dist/components/index.js +3 -3
- package/dist/components/internal/FormFieldRendererInternal.vue.d.ts +31 -0
- package/dist/components/internal/FormSectionRenderer.vue.d.ts +43 -0
- package/dist/{components-CzbQQPCb.js → components-D_Sr0adg.js} +9629 -8647
- package/dist/components-D_Sr0adg.js.map +1 -0
- package/dist/composables/index.d.ts +21 -2
- package/dist/composables/index.js +4 -3
- package/dist/composables/platformContextHelpers.d.ts +14 -0
- package/dist/composables/useBioTemplateComponents.d.ts +20 -0
- package/dist/composables/useBioTemplateControls.d.ts +6 -0
- package/dist/composables/useBioTemplatePackWorkspace.d.ts +45 -0
- package/dist/composables/useBioTemplatePresetWorkspace.d.ts +74 -0
- package/dist/composables/useBioTemplateWorkspace.d.ts +50 -0
- package/dist/composables/useCalendarGrid.d.ts +26 -0
- package/dist/composables/useControlSchema.d.ts +321 -0
- package/dist/composables/useDebouncedWatch.d.ts +20 -0
- package/dist/composables/useDropdownState.d.ts +19 -0
- package/dist/composables/useEventListener.d.ts +13 -0
- package/dist/composables/useExpansionSet.d.ts +21 -0
- package/dist/composables/useExperimentData.d.ts +10 -0
- package/dist/composables/useExperimentSave.d.ts +31 -2
- package/dist/composables/useExperimentSelector.d.ts +20 -0
- package/dist/composables/useForm.d.ts +2 -0
- package/dist/composables/useGroupAssignment.d.ts +31 -0
- package/dist/composables/useListSelection.d.ts +35 -0
- package/dist/composables/usePlatformContext.d.ts +24 -3
- package/dist/composables/usePluginApi.d.ts +7 -14
- package/dist/composables/usePluginClient.d.ts +109 -0
- package/dist/composables/usePluginConfig.d.ts +12 -0
- package/dist/composables/useRequestSyncState.d.ts +34 -0
- package/dist/composables/useSampleGroups.d.ts +32 -0
- package/dist/composables/useSelectionLimit.d.ts +17 -0
- package/dist/composables/useSortedItems.d.ts +32 -0
- package/dist/composables/useTemplateCollection.d.ts +58 -0
- package/dist/composables/useTextSearch.d.ts +18 -0
- package/dist/composables/useTimeUtils.d.ts +8 -0
- package/dist/{composables-BXklV5ii.js → composables-C3dpXQN5.js} +228 -146
- package/dist/composables-C3dpXQN5.js.map +1 -0
- package/dist/index.d.ts +12 -3
- package/dist/index.js +6 -5
- package/dist/install.d.ts +7 -2
- package/dist/install.js +2 -2
- package/dist/install.js.map +1 -1
- package/dist/stores/auth.d.ts +1 -1
- package/dist/stores/index.js +1 -1
- package/dist/stores/settings.d.ts +4 -1
- package/dist/styles.css +5255 -5654
- package/dist/templates/adapters.d.ts +43 -0
- package/dist/templates/builders.d.ts +63 -0
- package/dist/templates/catalog.d.ts +188 -0
- package/dist/templates/componentBindings.d.ts +58 -0
- package/dist/templates/controlSchemas.d.ts +25 -0
- package/dist/templates/index.d.ts +15 -0
- package/dist/templates/index.js +2 -0
- package/dist/templates/lookup.d.ts +4 -0
- package/dist/templates/packs.d.ts +18 -0
- package/dist/templates/presets.d.ts +90 -0
- package/dist/templates/types.d.ts +531 -0
- package/dist/templates-50NPjaxL.js +9333 -0
- package/dist/templates-50NPjaxL.js.map +1 -0
- package/dist/types/components.d.ts +62 -1
- package/dist/types/form-builder.d.ts +6 -8
- package/dist/types/index.d.ts +2 -2
- package/dist/types/platform.d.ts +8 -1
- package/dist/useScheduleDrag-D4oWdh41.js +4371 -0
- package/dist/useScheduleDrag-D4oWdh41.js.map +1 -0
- package/dist/utils/formModelSync.d.ts +5 -0
- package/dist/utils/items.d.ts +8 -0
- package/dist/utils/options.d.ts +6 -0
- package/dist/utils/pluginIcon.d.ts +9 -0
- package/package.json +7 -2
- package/src/__tests__/components/ActionItem.test.ts +99 -0
- package/src/__tests__/components/AppAvatarMenu.test.ts +27 -0
- package/src/__tests__/components/AppPageSelector.test.ts +134 -0
- package/src/__tests__/components/AppPillNav.test.ts +78 -0
- package/src/__tests__/components/AppPluginSwitcher.test.ts +44 -0
- package/src/__tests__/components/AppSidebar.test.ts +370 -0
- package/src/__tests__/components/AppToastContainer.test.ts +48 -0
- package/src/__tests__/components/AppTopBar.test.ts +414 -13
- package/src/__tests__/components/BaseRadioGroup.test.ts +25 -0
- package/src/__tests__/components/BaseSelect.test.ts +21 -0
- package/src/__tests__/components/BaseTabs.test.ts +25 -0
- package/src/__tests__/components/BatchProgressList.test.ts +52 -0
- package/src/__tests__/components/BioTemplateExperimentWorkspaceView.test.ts +153 -0
- package/src/__tests__/components/BioTemplatePackWorkspaceView.test.ts +161 -0
- package/src/__tests__/components/BioTemplatePresetWorkspaceView.test.ts +281 -0
- package/src/__tests__/components/BioTemplateRenderer.test.ts +71 -0
- package/src/__tests__/components/Breadcrumb.test.ts +23 -0
- package/src/__tests__/components/CalendarGridPanel.test.ts +36 -0
- package/src/__tests__/components/ConcentrationInput.test.ts +45 -0
- package/src/__tests__/components/ControlWorkspaceView.test.ts +1031 -0
- package/src/__tests__/components/DataFrame.test.ts +11 -0
- package/src/__tests__/components/DatePicker.test.ts +45 -0
- package/src/__tests__/components/DateTimePicker.test.ts +48 -0
- package/src/__tests__/components/DropdownButton.test.ts +23 -0
- package/src/__tests__/components/EmptyState.test.ts +23 -0
- package/src/__tests__/components/ExperimentPopover.test.ts +56 -0
- package/src/__tests__/components/FormBuilder.test.ts +296 -0
- package/src/__tests__/components/FormCompatibility.test.ts +94 -0
- package/src/__tests__/components/GroupAssigner.test.ts +30 -0
- package/src/__tests__/components/GroupingModal.test.ts +73 -0
- package/src/__tests__/components/MultiSelect.test.ts +48 -0
- package/src/__tests__/components/PluginIcon.test.ts +119 -0
- package/src/__tests__/components/ProtocolStepEditor.test.ts +33 -0
- package/src/__tests__/components/ReagentList.test.ts +82 -0
- package/src/__tests__/components/SampleHierarchyTree.test.ts +53 -0
- package/src/__tests__/components/SampleSelector.test.ts +60 -0
- package/src/__tests__/components/SegmentedControl.test.ts +24 -0
- package/src/__tests__/components/SettingsButton.test.ts +44 -0
- package/src/__tests__/components/SettingsModal.test.ts +296 -0
- package/src/__tests__/components/TagsInput.test.ts +75 -0
- package/src/__tests__/components/ThemeToggle.test.ts +47 -0
- package/src/__tests__/components/TimePicker.test.ts +38 -0
- package/src/__tests__/composables/useBioTemplatePackWorkspace.test.ts +122 -0
- package/src/__tests__/composables/useBioTemplatePresetWorkspace.test.ts +199 -0
- package/src/__tests__/composables/useBioTemplateWorkspace.test.ts +99 -0
- package/src/__tests__/composables/useCalendarGrid.test.ts +38 -0
- package/src/__tests__/composables/useControlSchema.test.ts +919 -0
- package/src/__tests__/composables/useDebouncedWatch.test.ts +93 -0
- package/src/__tests__/composables/useDropdownState.test.ts +95 -0
- package/src/__tests__/composables/useEventListener.test.ts +116 -0
- package/src/__tests__/composables/useExpansionSet.test.ts +62 -0
- package/src/__tests__/composables/useExperimentData.test.ts +4 -0
- package/src/__tests__/composables/useExperimentSave.test.ts +203 -8
- package/src/__tests__/composables/useExperimentSelector.test.ts +164 -0
- package/src/__tests__/composables/useForm.test.ts +58 -0
- package/src/__tests__/composables/useFormBuilder.test.ts +77 -0
- package/src/__tests__/composables/useGroupAssignment.test.ts +73 -0
- package/src/__tests__/composables/useListSelection.test.ts +66 -0
- package/src/__tests__/composables/usePluginClient.test.ts +444 -0
- package/src/__tests__/composables/usePluginConfig.test.ts +5 -0
- package/src/__tests__/composables/useRequestSyncState.test.ts +92 -0
- package/src/__tests__/composables/useSampleGroups.test.ts +66 -0
- package/src/__tests__/composables/useSelectionLimit.test.ts +41 -0
- package/src/__tests__/composables/useSortedItems.test.ts +87 -0
- package/src/__tests__/composables/useTemplateCollection.test.ts +147 -0
- package/src/__tests__/composables/useTextSearch.test.ts +55 -0
- package/src/__tests__/composables/useTheme.test.ts +91 -0
- package/src/__tests__/composables/useTimeUtils.test.ts +35 -0
- package/src/__tests__/docs/frontendDocsCatalog.test.ts +229 -0
- package/src/__tests__/fixtures/templates/dose-response.json +81 -0
- package/src/__tests__/fixtures/templates/plate-map.json +54 -0
- package/src/__tests__/fixtures/templates/qpcr-plate.json +96 -0
- package/src/__tests__/fixtures/templates/sample-sheet.json +71 -0
- package/src/__tests__/templates/templates.test.ts +1043 -0
- package/src/components/ActionItem.vue +82 -0
- package/src/components/AppAvatarMenu.vue +15 -69
- package/src/components/AppLayout.story.vue +25 -25
- package/src/components/AppPageSelector.vue +63 -94
- package/src/components/AppPillNav.vue +44 -39
- package/src/components/AppPluginSwitcher.vue +41 -145
- package/src/components/AppSidebar.story.vue +94 -0
- package/src/components/AppSidebar.vue +187 -12
- package/src/components/{ToastNotification.story.vue → AppToastContainer.story.vue} +6 -6
- package/src/components/AppToastContainer.vue +62 -0
- package/src/components/AppTopBar.story.vue +7 -30
- package/src/components/AppTopBar.vue +283 -84
- package/src/components/BaseModal.vue +3 -5
- package/src/components/BaseRadioGroup.vue +7 -3
- package/src/components/BaseSelect.vue +11 -7
- package/src/components/BaseTabs.vue +6 -4
- package/src/components/BatchProgressList.vue +5 -8
- package/src/components/BioTemplateExperimentWorkspaceView.story.vue +123 -0
- package/src/components/BioTemplateExperimentWorkspaceView.vue +337 -0
- package/src/components/BioTemplatePackWorkspaceView.story.vue +107 -0
- package/src/components/BioTemplatePackWorkspaceView.vue +176 -0
- package/src/components/BioTemplatePresetWorkspaceView.story.vue +151 -0
- package/src/components/BioTemplatePresetWorkspaceView.vue +392 -0
- package/src/components/BioTemplateRenderer.story.vue +57 -0
- package/src/components/BioTemplateRenderer.vue +269 -0
- package/src/components/Breadcrumb.vue +14 -8
- package/src/components/CalendarGridPanel.vue +120 -0
- package/src/components/ConcentrationInput.vue +27 -64
- package/src/components/ControlWorkspaceView.story.vue +336 -0
- package/src/components/ControlWorkspaceView.vue +347 -0
- package/src/components/DataFrame.vue +34 -50
- package/src/components/DatePicker.vue +59 -192
- package/src/components/DateTimePicker.vue +50 -171
- package/src/components/DropdownButton.vue +14 -32
- package/src/components/EmptyState.vue +4 -2
- package/src/components/ExperimentPopover.vue +5 -22
- package/src/components/FormBuilder.vue +124 -27
- package/src/components/FormFieldRenderer.vue +15 -38
- package/src/components/FormSection.vue +20 -73
- package/src/components/GroupAssigner.vue +24 -56
- package/src/components/GroupingModal.story.vue +3 -3
- package/src/components/GroupingModal.vue +30 -391
- package/src/components/MultiSelect.vue +17 -12
- package/src/components/PlateMapEditor.vue +3 -8
- package/src/components/PluginIcon.story.vue +71 -0
- package/src/components/PluginIcon.vue +68 -0
- package/src/components/ProtocolStepEditor.vue +13 -22
- package/src/components/ReagentList.vue +25 -33
- package/src/components/SampleHierarchyTree.vue +12 -23
- package/src/components/SampleSelector.vue +42 -122
- package/src/components/SegmentedControl.vue +7 -3
- package/src/components/SettingsButton.story.vue +1 -1
- package/src/components/SettingsButton.vue +15 -27
- package/src/components/SettingsModal.story.vue +337 -45
- package/src/components/SettingsModal.vue +344 -66
- package/src/components/TagsInput.vue +29 -14
- package/src/components/ThemeToggle.vue +9 -7
- package/src/components/TimePicker.vue +19 -41
- package/src/components/ToastNotification.vue +4 -57
- package/src/components/Tooltip.vue +7 -12
- package/src/components/WellEditPopup.vue +3 -8
- package/src/components/WellPlate.vue +4 -10
- package/src/components/index.ts +12 -1
- package/src/components/internal/FormFieldRendererInternal.vue +50 -0
- package/src/components/internal/FormSectionRenderer.vue +78 -0
- package/src/composables/index.ts +212 -0
- package/src/composables/platformContextHelpers.ts +74 -0
- package/src/composables/useBioTemplateComponents.ts +93 -0
- package/src/composables/useBioTemplateControls.ts +41 -0
- package/src/composables/useBioTemplatePackWorkspace.ts +181 -0
- package/src/composables/useBioTemplatePresetWorkspace.ts +337 -0
- package/src/composables/useBioTemplateWorkspace.ts +139 -0
- package/src/composables/useCalendarGrid.ts +140 -0
- package/src/composables/useControlSchema.ts +1274 -0
- package/src/composables/useDebouncedWatch.ts +119 -0
- package/src/composables/useDropdownState.ts +83 -0
- package/src/composables/useEventListener.ts +111 -0
- package/src/composables/useExpansionSet.ts +117 -0
- package/src/composables/useExperimentData.ts +20 -11
- package/src/composables/useExperimentSave.ts +202 -50
- package/src/composables/useExperimentSelector.ts +86 -72
- package/src/composables/useForm.ts +49 -4
- package/src/composables/useFormBuilder.ts +93 -42
- package/src/composables/useGroupAssignment.ts +148 -0
- package/src/composables/useListSelection.ts +158 -0
- package/src/composables/usePluginApi.ts +7 -14
- package/src/composables/usePluginClient.ts +425 -0
- package/src/composables/usePluginConfig.ts +34 -13
- package/src/composables/useRequestSyncState.ts +126 -0
- package/src/composables/useSampleGroups.ts +126 -0
- package/src/composables/useSelectionLimit.ts +57 -0
- package/src/composables/useSortedItems.ts +118 -0
- package/src/composables/useTemplateCollection.ts +229 -0
- package/src/composables/useTextSearch.ts +60 -0
- package/src/composables/useTheme.ts +2 -28
- package/src/composables/useTimeUtils.ts +26 -2
- package/src/composables/useWellPlateEditor.ts +13 -9
- package/src/index.ts +228 -4
- package/src/install.ts +11 -4
- package/src/stores/settings.ts +13 -9
- package/src/styles/components/app-page-selector.css +23 -0
- package/src/styles/components/app-pill-nav.css +8 -2
- package/src/styles/components/app-top-bar.css +35 -2
- package/src/styles/components/button.css +3 -7
- package/src/styles/components/concentration-input.css +3 -142
- package/src/styles/components/dropdown-button.css +4 -4
- package/src/styles/components/empty-state.css +0 -16
- package/src/styles/components/input.css +4 -5
- package/src/styles/components/number-input.css +3 -3
- package/src/styles/components/plugin-icon.css +38 -0
- package/src/styles/components/segmented-control.css +4 -7
- package/src/styles/components/settings-button.css +3 -66
- package/src/styles/components/settings-modal.css +184 -0
- package/src/styles/components/tabs.css +1 -2
- package/src/styles/components/textarea.css +4 -5
- package/src/styles/components/theme-toggle.css +3 -66
- package/src/styles/components/unit-input.css +3 -3
- package/src/styles/index.css +0 -1
- package/src/templates/adapters.ts +785 -0
- package/src/templates/builders.ts +2149 -0
- package/src/templates/catalog.ts +245 -0
- package/src/templates/componentBindings.ts +615 -0
- package/src/templates/controlSchemas.ts +718 -0
- package/src/templates/index.ts +314 -0
- package/src/templates/lookup.ts +18 -0
- package/src/templates/packs.ts +156 -0
- package/src/templates/presets.ts +146 -0
- package/src/templates/types.ts +668 -0
- package/src/types/components.ts +80 -1
- package/src/types/form-builder.ts +7 -2
- package/src/types/index.ts +17 -0
- package/src/types/platform.ts +8 -1
- package/src/utils/formModelSync.ts +52 -0
- package/src/utils/items.ts +28 -0
- package/src/utils/options.ts +23 -0
- package/src/utils/pluginIcon.ts +30 -0
- package/dist/auth-DsI0rQ7_.js.map +0 -1
- package/dist/components-CzbQQPCb.js.map +0 -1
- package/dist/composables-BXklV5ii.js.map +0 -1
- package/dist/useScheduleDrag-CxBeqYcu.js +0 -7181
- package/dist/useScheduleDrag-CxBeqYcu.js.map +0 -1
- package/src/styles/components/grouping-modal.css +0 -323
|
@@ -1,18 +1,27 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
/** Full application top bar with brand logo, page selector or plugin switcher, centered pill nav, experiment popover, and avatar menu. */
|
|
3
|
-
import { ref, computed, inject
|
|
3
|
+
import { ref, computed, inject } from 'vue'
|
|
4
4
|
import type {
|
|
5
5
|
TopBarPage,
|
|
6
|
+
TopBarPageInput,
|
|
6
7
|
TopBarTab,
|
|
8
|
+
TopBarTabInput,
|
|
7
9
|
TopBarTabOption,
|
|
10
|
+
TopBarTabOptionInput,
|
|
8
11
|
TopBarSettingsConfig,
|
|
9
12
|
TopBarVariant,
|
|
10
13
|
PillNavItem,
|
|
14
|
+
PillNavItemInput,
|
|
11
15
|
PageSelectorItem,
|
|
16
|
+
PageSelectorItemInput,
|
|
12
17
|
PluginSwitcherInfo,
|
|
13
18
|
PluginSwitcherPlugin,
|
|
14
19
|
AccountMenuItem,
|
|
20
|
+
SettingsTab,
|
|
15
21
|
} from '../types/components'
|
|
22
|
+
import type { PluginNavItem } from '../types/platform'
|
|
23
|
+
import { normalizeItemInput } from '../utils/items'
|
|
24
|
+
import { isPluginIconFormat } from '../utils/pluginIcon'
|
|
16
25
|
import ThemeToggle from './ThemeToggle.vue'
|
|
17
26
|
import SettingsModal from './SettingsModal.vue'
|
|
18
27
|
import ExperimentPopover from './ExperimentPopover.vue'
|
|
@@ -21,49 +30,75 @@ import AppPageSelector from './AppPageSelector.vue'
|
|
|
21
30
|
import AppPillNav from './AppPillNav.vue'
|
|
22
31
|
import AppAvatarMenu from './AppAvatarMenu.vue'
|
|
23
32
|
import AppPluginSwitcher from './AppPluginSwitcher.vue'
|
|
33
|
+
import PluginIcon from './PluginIcon.vue'
|
|
24
34
|
import { usePlatformContext } from '../composables/usePlatformContext'
|
|
25
35
|
import { APP_EXPERIMENT_KEY } from '../composables/useAppExperiment'
|
|
26
|
-
|
|
27
|
-
|
|
36
|
+
import { useEventListener } from '../composables/useEventListener'
|
|
37
|
+
import { useDropdownState } from '../composables/useDropdownState'
|
|
28
38
|
|
|
29
39
|
interface Props {
|
|
30
|
-
|
|
40
|
+
/** App or plugin title shown in the left title group when no page selector is present. */
|
|
31
41
|
title?: string
|
|
42
|
+
/** Secondary title copy shown under the title in title-group layouts. */
|
|
32
43
|
subtitle?: string
|
|
44
|
+
/** Show the default MINT logo when the icon/logo slot is not provided. */
|
|
33
45
|
showLogo?: boolean
|
|
46
|
+
/** Top bar visual treatment. */
|
|
34
47
|
variant?: TopBarVariant
|
|
35
|
-
|
|
36
|
-
pages?: TopBarPage[]
|
|
37
|
-
currentPageId?: string
|
|
38
|
-
tabs?: TopBarTab[]
|
|
39
|
-
currentTabId?: string
|
|
48
|
+
/** Home link used by classic breadcrumb layouts. */
|
|
40
49
|
homePath?: string
|
|
41
50
|
|
|
42
|
-
|
|
43
|
-
pageSelector?:
|
|
51
|
+
/** Preferred route-level page switch entries for plugin and platform pages. */
|
|
52
|
+
pageSelector?: PageSelectorItemInput[]
|
|
53
|
+
/** Active id for the preferred page selector. */
|
|
44
54
|
currentPageSelectorId?: string
|
|
55
|
+
/** Optional plugin switcher shown in the left navigation position instead of pageSelector. */
|
|
45
56
|
pluginSwitcher?: PluginSwitcherInfo
|
|
46
57
|
|
|
47
|
-
|
|
48
|
-
pillNav?:
|
|
58
|
+
/** Preferred centered navigation for local modes inside the current route. */
|
|
59
|
+
pillNav?: PillNavItemInput[]
|
|
60
|
+
/** Active id for the preferred centered pill navigation. */
|
|
49
61
|
currentPillId?: string
|
|
50
62
|
|
|
51
|
-
|
|
63
|
+
/** Account dropdown entries. Takes precedence over the classic profile button. */
|
|
52
64
|
accountMenu?: AccountMenuItem[]
|
|
65
|
+
/** Show the notifications icon button. */
|
|
53
66
|
showNotifications?: boolean
|
|
67
|
+
/** Draw a notification dot on the notifications icon. */
|
|
54
68
|
hasNotificationDot?: boolean
|
|
55
69
|
|
|
56
|
-
|
|
70
|
+
/** Compatibility breadcrumb plugin name. Prefer pageSelector for route-level pages. */
|
|
71
|
+
pluginName?: string
|
|
72
|
+
/** Compatibility page dropdown items. Prefer pageSelector for new route-level navigation. */
|
|
73
|
+
pages?: TopBarPageInput[]
|
|
74
|
+
/** Active id for the compatibility page dropdown. */
|
|
75
|
+
currentPageId?: string
|
|
76
|
+
/** Compatibility center tabs. Prefer pillNav for new in-page modes. */
|
|
77
|
+
tabs?: TopBarTabInput[]
|
|
78
|
+
/** Active id for compatibility center tabs. */
|
|
79
|
+
currentTabId?: string
|
|
80
|
+
|
|
81
|
+
/** Show the theme toggle button. */
|
|
57
82
|
showThemeToggle?: boolean
|
|
83
|
+
/** Show the settings button and modal. */
|
|
58
84
|
showSettings?: boolean
|
|
85
|
+
/** Built-in SettingsModal configuration. */
|
|
59
86
|
settingsConfig?: TopBarSettingsConfig
|
|
87
|
+
/** Show the standalone badge when the plugin is not integrated into the platform. */
|
|
60
88
|
showStandaloneLabel?: boolean
|
|
89
|
+
/** Custom standalone badge label. */
|
|
61
90
|
standaloneLabel?: string
|
|
91
|
+
/** Show the classic admin shortcut. */
|
|
62
92
|
showAdmin?: boolean
|
|
93
|
+
/** Route used by the classic admin shortcut. */
|
|
63
94
|
adminPath?: string
|
|
95
|
+
/** Show the classic profile button when accountMenu is not provided. */
|
|
64
96
|
showProfile?: boolean
|
|
97
|
+
/** Classic profile display name. */
|
|
65
98
|
userName?: string
|
|
99
|
+
/** Explicit classic profile initial. */
|
|
66
100
|
userInitial?: string
|
|
101
|
+
/** Classic profile email, used by avatar/account layouts. */
|
|
67
102
|
userEmail?: string
|
|
68
103
|
}
|
|
69
104
|
|
|
@@ -96,6 +131,7 @@ const emit = defineEmits<{
|
|
|
96
131
|
'account-menu-select': [item: AccountMenuItem]
|
|
97
132
|
'sign-out': []
|
|
98
133
|
'notifications-click': []
|
|
134
|
+
'settings-values-change': [data: Record<string, unknown>]
|
|
99
135
|
}>()
|
|
100
136
|
|
|
101
137
|
const settingsOpen = ref(false)
|
|
@@ -103,10 +139,7 @@ const { isIntegrated, plugin } = usePlatformContext()
|
|
|
103
139
|
const isStandalone = computed(() => !isIntegrated.value)
|
|
104
140
|
const appExperiment = inject(APP_EXPERIMENT_KEY, null)
|
|
105
141
|
|
|
106
|
-
const
|
|
107
|
-
const icon = plugin.value?.icon
|
|
108
|
-
return icon && icon.startsWith(SVG_PATH_PREFIX) ? icon : null
|
|
109
|
-
})
|
|
142
|
+
const hasPluginIcon = computed(() => !!plugin.value?.icon)
|
|
110
143
|
|
|
111
144
|
const profileInitial = computed(() => {
|
|
112
145
|
if (props.userInitial) return props.userInitial
|
|
@@ -114,21 +147,22 @@ const profileInitial = computed(() => {
|
|
|
114
147
|
return 'U'
|
|
115
148
|
})
|
|
116
149
|
|
|
150
|
+
const hasPlatformPages = computed(() => props.pages === undefined && !!plugin.value?.nav_items?.length)
|
|
151
|
+
const effectivePluginName = computed(() => props.pluginName ?? (hasPlatformPages.value ? plugin.value?.name : '') ?? '')
|
|
117
152
|
const hasPageSelector = computed(() => !!props.pageSelector?.length)
|
|
118
153
|
const hasPluginSwitcher = computed(() => !!props.pluginSwitcher)
|
|
119
154
|
const hasPillNav = computed(() => !!props.pillNav?.length)
|
|
120
155
|
const hasAccountMenu = computed(() => !!props.accountMenu?.length)
|
|
121
156
|
const hasLegacyBreadcrumb = computed(
|
|
122
|
-
() => !hasPageSelector.value && !hasPluginSwitcher.value && (!!
|
|
157
|
+
() => !hasPageSelector.value && !hasPluginSwitcher.value && (!!effectivePluginName.value || normalizedPages.value.length > 0),
|
|
123
158
|
)
|
|
124
159
|
const hasTitleGroup = computed(
|
|
125
160
|
() =>
|
|
126
161
|
!hasPageSelector.value &&
|
|
127
162
|
!hasPluginSwitcher.value &&
|
|
163
|
+
!hasLegacyBreadcrumb.value &&
|
|
128
164
|
!!props.title &&
|
|
129
|
-
!!props.subtitle
|
|
130
|
-
!props.pluginName &&
|
|
131
|
-
!props.pages?.length,
|
|
165
|
+
!!props.subtitle
|
|
132
166
|
)
|
|
133
167
|
const hasTitleOnly = computed(
|
|
134
168
|
() =>
|
|
@@ -138,25 +172,104 @@ const hasTitleOnly = computed(
|
|
|
138
172
|
!hasLegacyBreadcrumb.value &&
|
|
139
173
|
!!props.title,
|
|
140
174
|
)
|
|
175
|
+
const normalizedPages = computed<TopBarPage[]>(() =>
|
|
176
|
+
props.pages !== undefined
|
|
177
|
+
? props.pages.map(normalizeItemInput)
|
|
178
|
+
: plugin.value?.nav_items?.map(pluginNavItemToPage) ?? [],
|
|
179
|
+
)
|
|
180
|
+
const normalizedTabs = computed<TopBarTab[]>(() => props.tabs?.map(normalizeTopBarTabInput) ?? [])
|
|
181
|
+
const normalizedPageSelector = computed<PageSelectorItem[]>(() => props.pageSelector?.map(normalizeItemInput) ?? [])
|
|
182
|
+
const normalizedPillNav = computed<PillNavItem[]>(() => props.pillNav?.map(normalizeItemInput) ?? [])
|
|
183
|
+
const normalizedSettingsTabs = computed<SettingsTab[]>(() =>
|
|
184
|
+
props.settingsConfig?.tabs?.map(normalizeItemInput) ?? [],
|
|
185
|
+
)
|
|
186
|
+
const effectiveCurrentPageId = computed(() =>
|
|
187
|
+
props.currentPageId
|
|
188
|
+
?? (hasPlatformPages.value ? currentPageIdFromLocation(normalizedPages.value) : undefined)
|
|
189
|
+
?? (hasPlatformPages.value ? normalizedPages.value[0]?.id : undefined),
|
|
190
|
+
)
|
|
191
|
+
const currentLegacyPage = computed(() =>
|
|
192
|
+
normalizedPages.value.find((page) => page.id === effectiveCurrentPageId.value),
|
|
193
|
+
)
|
|
194
|
+
const effectiveTitle = computed(() =>
|
|
195
|
+
props.title ?? (hasPlatformPages.value ? currentLegacyPage.value?.label : undefined),
|
|
196
|
+
)
|
|
141
197
|
|
|
142
|
-
const
|
|
143
|
-
|
|
198
|
+
const {
|
|
199
|
+
isOpen: showPagesDropdown,
|
|
200
|
+
rootRef: dropdownRef,
|
|
201
|
+
close: closePagesDropdown,
|
|
202
|
+
toggle: togglePagesDropdownBase,
|
|
203
|
+
} = useDropdownState()
|
|
144
204
|
const openTabDropdown = ref<string | null>(null)
|
|
145
205
|
const tabDropdownRefs = ref<Map<string, HTMLElement>>(new Map())
|
|
146
206
|
|
|
147
207
|
function togglePagesDropdown() {
|
|
148
|
-
|
|
208
|
+
togglePagesDropdownBase()
|
|
149
209
|
openTabDropdown.value = null
|
|
150
210
|
}
|
|
151
211
|
|
|
212
|
+
function normalizeTopBarTabInput(tab: TopBarTabInput): TopBarTab {
|
|
213
|
+
const normalized = normalizeItemInput<Omit<TopBarTab, 'children'> & { children?: TopBarTabOptionInput[] }>(tab)
|
|
214
|
+
return {
|
|
215
|
+
...normalized,
|
|
216
|
+
children: normalized.children?.map(normalizeItemInput),
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function isSvgTabIcon(icon?: string): icon is string {
|
|
221
|
+
return !!icon && (icon.startsWith('M') || icon.startsWith('m'))
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function normalizeNavPath(path?: string): string {
|
|
225
|
+
const raw = path?.trim() || '/'
|
|
226
|
+
const prefixed = raw.startsWith('/') ? raw : `/${raw}`
|
|
227
|
+
return prefixed.replace(/\/+$/, '') || '/'
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function pageIdFromPath(path: string, fallback: string): string {
|
|
231
|
+
const normalized = normalizeNavPath(path)
|
|
232
|
+
if (normalized === '/') return 'dashboard'
|
|
233
|
+
return normalized.replace(/^\/+/, '').replace(/\/+/g, '-') || fallback
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
function pluginNavItemToPage(item: PluginNavItem, index: number): TopBarPage {
|
|
237
|
+
const path = normalizeNavPath(item.path)
|
|
238
|
+
return {
|
|
239
|
+
id: item.id || pageIdFromPath(path, `page-${index + 1}`),
|
|
240
|
+
label: item.label,
|
|
241
|
+
to: path,
|
|
242
|
+
icon: item.icon || plugin.value?.icon,
|
|
243
|
+
description: item.description,
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function currentPagePath(): string | undefined {
|
|
248
|
+
if (typeof window === 'undefined') return undefined
|
|
249
|
+
const pathname = normalizeNavPath(window.location.pathname)
|
|
250
|
+
const routePrefix = normalizeNavPath(plugin.value?.route_prefix)
|
|
251
|
+
|
|
252
|
+
if (pathname === routePrefix) return '/'
|
|
253
|
+
if (routePrefix !== '/' && pathname.startsWith(`${routePrefix}/`)) {
|
|
254
|
+
return normalizeNavPath(pathname.slice(routePrefix.length))
|
|
255
|
+
}
|
|
256
|
+
return pathname
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
function currentPageIdFromLocation(pages: TopBarPage[]): string | undefined {
|
|
260
|
+
const path = currentPagePath()
|
|
261
|
+
if (!path) return undefined
|
|
262
|
+
return pages.find((page) => normalizeNavPath(page.to || page.href) === path)?.id
|
|
263
|
+
}
|
|
264
|
+
|
|
152
265
|
function handlePageClick(page: TopBarPage) {
|
|
153
266
|
if (page.disabled) return
|
|
154
267
|
emit('page-select', page)
|
|
155
|
-
|
|
268
|
+
closePagesDropdown()
|
|
156
269
|
}
|
|
157
270
|
|
|
158
271
|
function toggleTabDropdown(tabId: string) {
|
|
159
|
-
|
|
272
|
+
closePagesDropdown()
|
|
160
273
|
openTabDropdown.value = openTabDropdown.value === tabId ? null : tabId
|
|
161
274
|
}
|
|
162
275
|
|
|
@@ -187,10 +300,6 @@ function setTabDropdownRef(el: HTMLElement | null, tabId: string) {
|
|
|
187
300
|
function handleClickOutside(event: MouseEvent) {
|
|
188
301
|
const target = event.target as Node
|
|
189
302
|
|
|
190
|
-
if (showPagesDropdown.value && dropdownRef.value && !dropdownRef.value.contains(target)) {
|
|
191
|
-
showPagesDropdown.value = false
|
|
192
|
-
}
|
|
193
|
-
|
|
194
303
|
if (openTabDropdown.value !== null) {
|
|
195
304
|
const clickedInside = Array.from(tabDropdownRefs.value.values()).some((el) => el.contains(target))
|
|
196
305
|
if (!clickedInside) {
|
|
@@ -199,13 +308,7 @@ function handleClickOutside(event: MouseEvent) {
|
|
|
199
308
|
}
|
|
200
309
|
}
|
|
201
310
|
|
|
202
|
-
|
|
203
|
-
document.addEventListener('click', handleClickOutside)
|
|
204
|
-
})
|
|
205
|
-
|
|
206
|
-
onUnmounted(() => {
|
|
207
|
-
document.removeEventListener('click', handleClickOutside)
|
|
208
|
-
})
|
|
311
|
+
useEventListener(() => document, 'click', handleClickOutside)
|
|
209
312
|
</script>
|
|
210
313
|
|
|
211
314
|
<template>
|
|
@@ -224,13 +327,14 @@ onUnmounted(() => {
|
|
|
224
327
|
class="mint-topbar-home-link"
|
|
225
328
|
>
|
|
226
329
|
<slot name="icon">
|
|
227
|
-
<
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
330
|
+
<PluginIcon
|
|
331
|
+
v-if="hasPluginIcon"
|
|
332
|
+
class="mint-topbar__plugin-icon"
|
|
333
|
+
:icon="plugin!.icon"
|
|
334
|
+
:tone="plugin!.color"
|
|
335
|
+
size="md"
|
|
336
|
+
variant="solid"
|
|
337
|
+
/>
|
|
234
338
|
<slot v-else name="logo">
|
|
235
339
|
<div v-if="showLogo" class="mint-topbar__logo">
|
|
236
340
|
<div class="mint-topbar__logo-icon">
|
|
@@ -246,13 +350,14 @@ onUnmounted(() => {
|
|
|
246
350
|
class="mint-topbar-home-link"
|
|
247
351
|
>
|
|
248
352
|
<slot name="icon">
|
|
249
|
-
<
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
353
|
+
<PluginIcon
|
|
354
|
+
v-if="hasPluginIcon"
|
|
355
|
+
class="mint-topbar__plugin-icon"
|
|
356
|
+
:icon="plugin!.icon"
|
|
357
|
+
:tone="plugin!.color"
|
|
358
|
+
size="md"
|
|
359
|
+
variant="solid"
|
|
360
|
+
/>
|
|
256
361
|
<slot v-else name="logo">
|
|
257
362
|
<div v-if="showLogo" class="mint-topbar__logo">
|
|
258
363
|
<div class="mint-topbar__logo-icon">
|
|
@@ -264,13 +369,14 @@ onUnmounted(() => {
|
|
|
264
369
|
</router-link>
|
|
265
370
|
<template v-else>
|
|
266
371
|
<slot name="icon">
|
|
267
|
-
<
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
372
|
+
<PluginIcon
|
|
373
|
+
v-if="hasPluginIcon"
|
|
374
|
+
class="mint-topbar__plugin-icon"
|
|
375
|
+
:icon="plugin!.icon"
|
|
376
|
+
:tone="plugin!.color"
|
|
377
|
+
size="md"
|
|
378
|
+
variant="solid"
|
|
379
|
+
/>
|
|
274
380
|
<slot v-else name="logo">
|
|
275
381
|
<div v-if="showLogo" class="mint-topbar__logo">
|
|
276
382
|
<div class="mint-topbar__logo-icon">
|
|
@@ -293,8 +399,8 @@ onUnmounted(() => {
|
|
|
293
399
|
@install-click="emit('plugin-switcher-install')"
|
|
294
400
|
/>
|
|
295
401
|
<AppPageSelector
|
|
296
|
-
v-else-if="hasPageSelector
|
|
297
|
-
:pages="
|
|
402
|
+
v-else-if="hasPageSelector"
|
|
403
|
+
:pages="normalizedPageSelector"
|
|
298
404
|
:current-page-id="currentPageSelectorId"
|
|
299
405
|
@select="emit('page-selector-select', $event)"
|
|
300
406
|
>
|
|
@@ -314,12 +420,12 @@ onUnmounted(() => {
|
|
|
314
420
|
|
|
315
421
|
<div v-else-if="hasLegacyBreadcrumb" ref="dropdownRef" class="mint-topbar-breadcrumb">
|
|
316
422
|
<button
|
|
317
|
-
v-if="
|
|
423
|
+
v-if="normalizedPages.length"
|
|
318
424
|
type="button"
|
|
319
425
|
class="mint-topbar-plugin-name"
|
|
320
426
|
@click.stop="togglePagesDropdown"
|
|
321
427
|
>
|
|
322
|
-
{{
|
|
428
|
+
{{ effectivePluginName }}
|
|
323
429
|
<svg
|
|
324
430
|
class="mint-topbar-chevron"
|
|
325
431
|
:class="{ 'mint-topbar-chevron--open': showPagesDropdown }"
|
|
@@ -335,10 +441,10 @@ onUnmounted(() => {
|
|
|
335
441
|
<path d="m6 9 6 6 6-6" />
|
|
336
442
|
</svg>
|
|
337
443
|
</button>
|
|
338
|
-
<span v-else class="mint-topbar-plugin-name--static">{{
|
|
444
|
+
<span v-else class="mint-topbar-plugin-name--static">{{ effectivePluginName }}</span>
|
|
339
445
|
|
|
340
446
|
<svg
|
|
341
|
-
v-if="
|
|
447
|
+
v-if="effectiveTitle"
|
|
342
448
|
class="mint-topbar-separator"
|
|
343
449
|
width="16"
|
|
344
450
|
height="16"
|
|
@@ -351,36 +457,69 @@ onUnmounted(() => {
|
|
|
351
457
|
>
|
|
352
458
|
<path d="m9 18 6-6-6-6" />
|
|
353
459
|
</svg>
|
|
354
|
-
<span v-if="
|
|
460
|
+
<span v-if="effectiveTitle" class="mint-topbar-current-page">{{ effectiveTitle }}</span>
|
|
355
461
|
|
|
356
462
|
<div v-show="showPagesDropdown" class="mint-topbar-dropdown">
|
|
357
|
-
<template v-for="page in
|
|
463
|
+
<template v-for="page in normalizedPages" :key="page.id">
|
|
358
464
|
<a
|
|
359
465
|
v-if="page.href"
|
|
360
466
|
:href="page.href"
|
|
361
|
-
:class="['mint-topbar-dropdown-item', { 'mint-topbar-dropdown-item--active': page.id ===
|
|
362
|
-
@click="
|
|
467
|
+
:class="['mint-topbar-dropdown-item', { 'mint-topbar-dropdown-item--active': page.id === effectiveCurrentPageId, 'mint-topbar-dropdown-item--disabled': page.disabled }]"
|
|
468
|
+
@click="closePagesDropdown"
|
|
363
469
|
>
|
|
364
|
-
<span class="mint-topbar-dropdown-
|
|
365
|
-
|
|
470
|
+
<span class="mint-topbar-dropdown-item__page">
|
|
471
|
+
<PluginIcon
|
|
472
|
+
v-if="isPluginIconFormat(page.icon)"
|
|
473
|
+
class="mint-topbar-dropdown-item__icon"
|
|
474
|
+
:icon="page.icon"
|
|
475
|
+
size="sm"
|
|
476
|
+
variant="tinted"
|
|
477
|
+
/>
|
|
478
|
+
<span class="mint-topbar-dropdown-item__copy">
|
|
479
|
+
<span class="mint-topbar-dropdown-item__label">{{ page.label }}</span>
|
|
480
|
+
<span v-if="page.description" class="mint-topbar-dropdown-item__description">{{ page.description }}</span>
|
|
481
|
+
</span>
|
|
482
|
+
</span>
|
|
366
483
|
</a>
|
|
367
484
|
<router-link
|
|
368
485
|
v-else-if="page.to"
|
|
369
486
|
:to="page.to"
|
|
370
|
-
:class="['mint-topbar-dropdown-item', { 'mint-topbar-dropdown-item--active': page.id ===
|
|
371
|
-
@click="
|
|
487
|
+
:class="['mint-topbar-dropdown-item', { 'mint-topbar-dropdown-item--active': page.id === effectiveCurrentPageId, 'mint-topbar-dropdown-item--disabled': page.disabled }]"
|
|
488
|
+
@click="closePagesDropdown"
|
|
372
489
|
>
|
|
373
|
-
<span class="mint-topbar-dropdown-
|
|
374
|
-
|
|
490
|
+
<span class="mint-topbar-dropdown-item__page">
|
|
491
|
+
<PluginIcon
|
|
492
|
+
v-if="isPluginIconFormat(page.icon)"
|
|
493
|
+
class="mint-topbar-dropdown-item__icon"
|
|
494
|
+
:icon="page.icon"
|
|
495
|
+
size="sm"
|
|
496
|
+
variant="tinted"
|
|
497
|
+
/>
|
|
498
|
+
<span class="mint-topbar-dropdown-item__copy">
|
|
499
|
+
<span class="mint-topbar-dropdown-item__label">{{ page.label }}</span>
|
|
500
|
+
<span v-if="page.description" class="mint-topbar-dropdown-item__description">{{ page.description }}</span>
|
|
501
|
+
</span>
|
|
502
|
+
</span>
|
|
375
503
|
</router-link>
|
|
376
504
|
<button
|
|
377
505
|
v-else
|
|
378
506
|
type="button"
|
|
379
|
-
:class="['mint-topbar-dropdown-item', { 'mint-topbar-dropdown-item--active': page.id ===
|
|
507
|
+
:class="['mint-topbar-dropdown-item', { 'mint-topbar-dropdown-item--active': page.id === effectiveCurrentPageId, 'mint-topbar-dropdown-item--disabled': page.disabled }]"
|
|
380
508
|
@click="handlePageClick(page)"
|
|
381
509
|
>
|
|
382
|
-
<span class="mint-topbar-dropdown-
|
|
383
|
-
|
|
510
|
+
<span class="mint-topbar-dropdown-item__page">
|
|
511
|
+
<PluginIcon
|
|
512
|
+
v-if="isPluginIconFormat(page.icon)"
|
|
513
|
+
class="mint-topbar-dropdown-item__icon"
|
|
514
|
+
:icon="page.icon"
|
|
515
|
+
size="sm"
|
|
516
|
+
variant="tinted"
|
|
517
|
+
/>
|
|
518
|
+
<span class="mint-topbar-dropdown-item__copy">
|
|
519
|
+
<span class="mint-topbar-dropdown-item__label">{{ page.label }}</span>
|
|
520
|
+
<span v-if="page.description" class="mint-topbar-dropdown-item__description">{{ page.description }}</span>
|
|
521
|
+
</span>
|
|
522
|
+
</span>
|
|
384
523
|
</button>
|
|
385
524
|
</template>
|
|
386
525
|
</div>
|
|
@@ -396,7 +535,7 @@ onUnmounted(() => {
|
|
|
396
535
|
<slot name="center">
|
|
397
536
|
<AppPillNav
|
|
398
537
|
v-if="hasPillNav && pillNav"
|
|
399
|
-
:items="
|
|
538
|
+
:items="normalizedPillNav"
|
|
400
539
|
:current-item-id="currentPillId"
|
|
401
540
|
@select="emit('pill-select', $event)"
|
|
402
541
|
/>
|
|
@@ -406,9 +545,9 @@ onUnmounted(() => {
|
|
|
406
545
|
<!-- Center: classic tabs (when no pillNav) — wrapped in the same centered
|
|
407
546
|
container as AppPillNav so classic :tabs consumers get centered pill
|
|
408
547
|
layout without migrating to :pill-nav. -->
|
|
409
|
-
<div v-if="!hasPillNav &&
|
|
548
|
+
<div v-if="!hasPillNav && normalizedTabs.length" class="mint-topbar__center">
|
|
410
549
|
<div class="mint-topbar__tabs">
|
|
411
|
-
<template v-for="tab in
|
|
550
|
+
<template v-for="tab in normalizedTabs" :key="tab.id">
|
|
412
551
|
<div
|
|
413
552
|
:ref="(el) => tab.children?.length ? setTabDropdownRef(el as HTMLElement, tab.id) : null"
|
|
414
553
|
class="mint-topbar-tab-wrapper"
|
|
@@ -423,6 +562,19 @@ onUnmounted(() => {
|
|
|
423
562
|
]"
|
|
424
563
|
@click.stop="handleTabClick(tab)"
|
|
425
564
|
>
|
|
565
|
+
<svg
|
|
566
|
+
v-if="isSvgTabIcon(tab.icon)"
|
|
567
|
+
class="mint-topbar-tab-icon"
|
|
568
|
+
viewBox="0 0 24 24"
|
|
569
|
+
fill="none"
|
|
570
|
+
stroke="currentColor"
|
|
571
|
+
stroke-width="2"
|
|
572
|
+
stroke-linecap="round"
|
|
573
|
+
stroke-linejoin="round"
|
|
574
|
+
aria-hidden="true"
|
|
575
|
+
>
|
|
576
|
+
<path :d="tab.icon" />
|
|
577
|
+
</svg>
|
|
426
578
|
{{ tab.label }}
|
|
427
579
|
<svg
|
|
428
580
|
class="mint-topbar-tab-chevron"
|
|
@@ -449,6 +601,19 @@ onUnmounted(() => {
|
|
|
449
601
|
{ 'mint-topbar-tab--disabled': tab.disabled }
|
|
450
602
|
]"
|
|
451
603
|
>
|
|
604
|
+
<svg
|
|
605
|
+
v-if="isSvgTabIcon(tab.icon)"
|
|
606
|
+
class="mint-topbar-tab-icon"
|
|
607
|
+
viewBox="0 0 24 24"
|
|
608
|
+
fill="none"
|
|
609
|
+
stroke="currentColor"
|
|
610
|
+
stroke-width="2"
|
|
611
|
+
stroke-linecap="round"
|
|
612
|
+
stroke-linejoin="round"
|
|
613
|
+
aria-hidden="true"
|
|
614
|
+
>
|
|
615
|
+
<path :d="tab.icon" />
|
|
616
|
+
</svg>
|
|
452
617
|
{{ tab.label }}
|
|
453
618
|
</a>
|
|
454
619
|
<router-link
|
|
@@ -460,6 +625,19 @@ onUnmounted(() => {
|
|
|
460
625
|
{ 'mint-topbar-tab--disabled': tab.disabled }
|
|
461
626
|
]"
|
|
462
627
|
>
|
|
628
|
+
<svg
|
|
629
|
+
v-if="isSvgTabIcon(tab.icon)"
|
|
630
|
+
class="mint-topbar-tab-icon"
|
|
631
|
+
viewBox="0 0 24 24"
|
|
632
|
+
fill="none"
|
|
633
|
+
stroke="currentColor"
|
|
634
|
+
stroke-width="2"
|
|
635
|
+
stroke-linecap="round"
|
|
636
|
+
stroke-linejoin="round"
|
|
637
|
+
aria-hidden="true"
|
|
638
|
+
>
|
|
639
|
+
<path :d="tab.icon" />
|
|
640
|
+
</svg>
|
|
463
641
|
{{ tab.label }}
|
|
464
642
|
</router-link>
|
|
465
643
|
<button
|
|
@@ -472,6 +650,19 @@ onUnmounted(() => {
|
|
|
472
650
|
]"
|
|
473
651
|
@click="handleTabClick(tab)"
|
|
474
652
|
>
|
|
653
|
+
<svg
|
|
654
|
+
v-if="isSvgTabIcon(tab.icon)"
|
|
655
|
+
class="mint-topbar-tab-icon"
|
|
656
|
+
viewBox="0 0 24 24"
|
|
657
|
+
fill="none"
|
|
658
|
+
stroke="currentColor"
|
|
659
|
+
stroke-width="2"
|
|
660
|
+
stroke-linecap="round"
|
|
661
|
+
stroke-linejoin="round"
|
|
662
|
+
aria-hidden="true"
|
|
663
|
+
>
|
|
664
|
+
<path :d="tab.icon" />
|
|
665
|
+
</svg>
|
|
475
666
|
{{ tab.label }}
|
|
476
667
|
</button>
|
|
477
668
|
|
|
@@ -634,11 +825,19 @@ onUnmounted(() => {
|
|
|
634
825
|
v-if="showSettings"
|
|
635
826
|
v-model="settingsOpen"
|
|
636
827
|
:title="settingsConfig?.title"
|
|
637
|
-
:tabs="
|
|
828
|
+
:tabs="normalizedSettingsTabs"
|
|
638
829
|
:show-appearance="settingsConfig?.showAppearance ?? true"
|
|
639
830
|
:size="settingsConfig?.size"
|
|
831
|
+
:layout="settingsConfig?.layout"
|
|
832
|
+
:schema="settingsConfig?.schema"
|
|
833
|
+
:model="settingsConfig?.model"
|
|
834
|
+
:controls="settingsConfig?.controls"
|
|
835
|
+
:control-options="settingsConfig?.controlOptions"
|
|
836
|
+
:values="settingsConfig?.values"
|
|
837
|
+
:enhancements="settingsConfig?.enhancements"
|
|
838
|
+
@update:values="emit('settings-values-change', $event)"
|
|
640
839
|
>
|
|
641
|
-
<template v-for="tab in
|
|
840
|
+
<template v-for="tab in normalizedSettingsTabs" :key="tab.id" #[`tab-${tab.id}`]>
|
|
642
841
|
<slot :name="`settings-tab-${tab.id}`" />
|
|
643
842
|
</template>
|
|
644
843
|
<template #appearance>
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
/** Modal dialog with backdrop, focus trap, Escape-to-close, and configurable size/variant. */
|
|
3
|
-
import { ref, watch, nextTick,
|
|
3
|
+
import { ref, watch, nextTick, onUnmounted } from 'vue'
|
|
4
4
|
import type { ModalSize, ModalVariant } from '../types'
|
|
5
|
+
import { useEventListener } from '../composables/useEventListener'
|
|
5
6
|
|
|
6
7
|
interface Props {
|
|
7
8
|
modelValue: boolean
|
|
@@ -101,12 +102,9 @@ watch(() => props.modelValue, async (isOpen) => {
|
|
|
101
102
|
}
|
|
102
103
|
})
|
|
103
104
|
|
|
104
|
-
|
|
105
|
-
document.addEventListener('keydown', handleKeydown)
|
|
106
|
-
})
|
|
105
|
+
useEventListener(() => document, 'keydown', handleKeydown)
|
|
107
106
|
|
|
108
107
|
onUnmounted(() => {
|
|
109
|
-
document.removeEventListener('keydown', handleKeydown)
|
|
110
108
|
document.body.style.overflow = ''
|
|
111
109
|
})
|
|
112
110
|
</script>
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
/** Renders a group of radio buttons in list or tile layout, horizontal or vertical. */
|
|
3
|
-
import
|
|
3
|
+
import { computed } from 'vue'
|
|
4
|
+
import type { RadioOption, RadioOptionInput } from '../types'
|
|
5
|
+
import { normalizeOptionInput } from '../utils/options'
|
|
4
6
|
|
|
5
7
|
interface Props {
|
|
6
8
|
modelValue?: string | number
|
|
7
|
-
options:
|
|
9
|
+
options: RadioOptionInput[]
|
|
8
10
|
name: string
|
|
9
11
|
disabled?: boolean
|
|
10
12
|
direction?: 'horizontal' | 'vertical'
|
|
@@ -23,6 +25,8 @@ const emit = defineEmits<{
|
|
|
23
25
|
'update:modelValue': [value: string | number]
|
|
24
26
|
}>()
|
|
25
27
|
|
|
28
|
+
const normalizedOptions = computed<RadioOption[]>(() => props.options.map(normalizeOptionInput))
|
|
29
|
+
|
|
26
30
|
function handleChange(value: string | number) {
|
|
27
31
|
emit('update:modelValue', value)
|
|
28
32
|
}
|
|
@@ -34,7 +38,7 @@ function handleChange(value: string | number) {
|
|
|
34
38
|
role="radiogroup"
|
|
35
39
|
>
|
|
36
40
|
<label
|
|
37
|
-
v-for="option in
|
|
41
|
+
v-for="option in normalizedOptions"
|
|
38
42
|
:key="String(option.value)"
|
|
39
43
|
:class="[
|
|
40
44
|
'mint-radio-option',
|