@morscherlab/mint-sdk 1.2.0-beta.1 → 1.2.0-beta.10
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 +35 -5
- package/dist/{ExperimentPopover-tLwJ7XF4.js → ExperimentPopover-oL0fg_A0.js} +6 -4
- package/dist/ExperimentPopover-oL0fg_A0.js.map +1 -0
- package/dist/{ExperimentSelectorModal-DyPAUCLw.js → ExperimentSelectorModal-BeEOomw_.js} +5 -5
- package/dist/ExperimentSelectorModal-BeEOomw_.js.map +1 -0
- package/dist/{SettingsModal-BgKY93zh.js → SettingsModal-Dphh3RrI.js} +5 -8
- package/dist/SettingsModal-Dphh3RrI.js.map +1 -0
- package/dist/{EmptyState-p90quq8Z.js → Skeleton-DxtwJ5gt.js} +111 -93
- package/dist/Skeleton-DxtwJ5gt.js.map +1 -0
- package/dist/__tests__/components/ExperimentTimeline.test.d.ts +1 -0
- package/dist/__tests__/components/PluginWorkspaceView.internal.test.d.ts +1 -0
- package/dist/__tests__/components/SecretInput.test.d.ts +1 -0
- package/dist/__tests__/components/WellEditPopupInternal.test.d.ts +1 -0
- package/dist/__tests__/composables/useListReorder.test.d.ts +1 -0
- package/dist/__tests__/composables/usePluginConfig.test.d.ts +15 -0
- package/dist/__tests__/styles/cssTokens.test.d.ts +1 -0
- package/dist/components/ActionMenu.vue.d.ts +1 -1
- package/dist/components/AppAvatarMenu.vue.d.ts +4 -0
- package/dist/components/AppPluginSwitcher.vue.d.ts +2 -0
- package/dist/components/AppSidebar.vue.d.ts +1 -1
- package/dist/components/AuditTrail.vue.d.ts +13 -0
- package/dist/components/AutoGroupModal.vue.d.ts +1 -1
- package/dist/components/BatchProgressList.vue.d.ts +17 -0
- package/dist/components/BioTemplateExperimentWorkspaceView.vue.d.ts +2 -2
- package/dist/components/DataFrame.vue.d.ts +14 -2
- package/dist/components/DatePicker.vue.d.ts +1 -1
- package/dist/components/DateTimePicker.vue.d.ts +2 -0
- package/dist/components/DropdownButton.vue.d.ts +2 -0
- package/dist/components/ExperimentDataViewer.vue.d.ts +26 -1
- package/dist/components/ExperimentPopover.vue.d.ts +1 -0
- package/dist/components/ExperimentTimeline.vue.d.ts +29 -1
- package/dist/components/FitPanel.vue.d.ts +1 -1
- package/dist/components/JobsStatusTray.vue.d.ts +9 -2
- package/dist/components/LcmsSequenceTable.vue.d.ts +29 -1
- package/dist/components/PluginWorkspaceView.props.d.ts +29 -1
- package/dist/components/PluginWorkspaceView.vue.d.ts +5 -5
- package/dist/components/ProgressBar.vue.d.ts +1 -1
- package/dist/components/ProtocolStepEditor.vue.d.ts +1 -0
- package/dist/components/ReagentList.vue.d.ts +29 -1
- package/dist/components/SampleHierarchyTree.vue.d.ts +29 -1
- package/dist/components/SampleLegend.vue.d.ts +1 -1
- package/dist/components/SampleSelector.drag.d.ts +13 -0
- package/dist/components/SampleSelector.tree.d.ts +2 -0
- package/dist/components/SampleSelector.vue.d.ts +35 -2
- package/dist/components/ScheduleCalendar.vue.d.ts +20 -0
- package/dist/components/SecretInput.vue.d.ts +28 -0
- package/dist/components/SettingsModal.vue.d.ts +1 -1
- package/dist/components/SmartGroupFieldRecipe.vue.d.ts +2 -1
- package/dist/components/TimePicker.vue.d.ts +1 -0
- package/dist/components/WellPlate.geometry.d.ts +15 -0
- package/dist/components/WellPlate.interaction.d.ts +13 -0
- package/dist/components/WellPlate.vue.d.ts +29 -0
- package/dist/components/index.d.ts +9 -0
- package/dist/components/index.js +8 -8
- package/dist/components/internal/AppTopBarPageSelectorInternal.vue.d.ts +2 -0
- package/dist/components/internal/DataStateInternal.vue.d.ts +43 -0
- package/dist/components/internal/WellEditPopupInternal.vue.d.ts +3 -1
- package/dist/components/internal/WorkspaceControlsInternal.vue.d.ts +23 -0
- package/dist/components/internal/WorkspaceShellInternal.vue.d.ts +70 -0
- package/dist/components/internal/WorkspaceSidebarInternal.vue.d.ts +43 -0
- package/dist/{components-DkHddRMl.js → components-CgAUzF8F.js} +2497 -2235
- package/dist/components-CgAUzF8F.js.map +1 -0
- package/dist/composables/controlSchemaTypes.d.ts +34 -0
- package/dist/composables/flattenWorkspaceBindings.d.ts +61 -0
- package/dist/composables/index.d.ts +9 -2
- package/dist/composables/index.js +10 -10
- package/dist/composables/pluginWorkspaceModel.d.ts +164 -0
- package/dist/composables/useAsync.d.ts +5 -1
- package/dist/composables/useBioTemplateWorkspace.d.ts +4 -20
- package/dist/composables/useCommandHistory.d.ts +5 -1
- package/dist/composables/useDropdownState.d.ts +18 -2
- package/dist/composables/useEventStream.d.ts +9 -0
- package/dist/composables/useFocusTrap.d.ts +21 -0
- package/dist/composables/useGeneratedAnalysis.d.ts +3 -1
- package/dist/composables/useJobsStatusTray.d.ts +25 -1
- package/dist/composables/useListReorder.d.ts +90 -0
- package/dist/composables/useMenuKeyboard.d.ts +29 -0
- package/dist/composables/useOptimisticMutation.d.ts +5 -1
- package/dist/composables/usePluginClient.d.ts +2 -0
- package/dist/composables/usePluginConfig.d.ts +27 -0
- package/dist/composables/usePluginWorkspace.d.ts +51 -0
- package/dist/composables/useRequestSyncState.d.ts +42 -2
- package/dist/composables/useResourceCrud.d.ts +5 -1
- package/dist/composables/useRovingFocus.d.ts +24 -0
- package/dist/composables/useScheduleDrag.d.ts +1 -0
- package/dist/composables/useWellPainting.d.ts +5 -1
- package/dist/composables/useWellPlateAdapter.d.ts +5 -1
- package/dist/composables/useWellPlateValidation.d.ts +5 -1
- package/dist/composables/workspaceRecipes.d.ts +188 -0
- package/dist/{composables-C_i90sGS.js → composables-B_pia3hO.js} +209 -82
- package/dist/composables-B_pia3hO.js.map +1 -0
- package/dist/{useApi-J6zFkHmn.js → errors-_W0-LbA6.js} +103 -3
- package/dist/errors-_W0-LbA6.js.map +1 -0
- package/dist/{experiment-Cq145oEW.js → experiment-Cwl9AYxw.js} +3 -8
- package/dist/experiment-Cwl9AYxw.js.map +1 -0
- package/dist/{experiment-utils-CLnzPPq5.js → experiment-utils-DV3DrvE_.js} +70 -51
- package/dist/experiment-utils-DV3DrvE_.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +15 -15
- package/dist/install.js +2 -7
- package/dist/install.js.map +1 -1
- package/dist/permissions.d.ts +42 -1
- package/dist/permissions.js +20 -10
- package/dist/permissions.js.map +1 -1
- package/dist/stores/auth.d.ts +6 -0
- package/dist/stores/index.d.ts +1 -1
- package/dist/stores/index.js +3 -3
- package/dist/stores/settings.d.ts +31 -1
- package/dist/styles.css +11247 -29501
- package/dist/templates/builderReadUtils.d.ts +1 -1
- package/dist/templates/index.js +2 -4
- package/dist/{templates-DsP51i-S.js → templates-Qq113pyZ.js} +303 -106
- package/dist/templates-Qq113pyZ.js.map +1 -0
- package/dist/types/auth.d.ts +1 -0
- package/dist/types/form-builder.d.ts +1 -1
- package/dist/{useControlSchema-BDx2Olha.js → useControlSchema-aMZlb4Sc.js} +462 -1130
- package/dist/useControlSchema-aMZlb4Sc.js.map +1 -0
- package/dist/{useDropdownState-DSb3BC3N.js → useDropdownState-DitCtrTT.js} +22 -6
- package/dist/useDropdownState-DitCtrTT.js.map +1 -0
- package/dist/{useExperimentSelector-CV4iNfMS.js → useExperimentSelector-I8HC8hUu.js} +4 -4
- package/dist/{useExperimentSelector-CV4iNfMS.js.map → useExperimentSelector-I8HC8hUu.js.map} +1 -1
- package/dist/{useFormBuilder-BLxG3BOX.js → useFormBuilder-TCxNnqeb.js} +2 -2
- package/dist/{useFormBuilder-BLxG3BOX.js.map → useFormBuilder-TCxNnqeb.js.map} +1 -1
- package/dist/{useProtocolTemplates-CS_SQl6U.js → useProtocolTemplates-BmX_iVBR.js} +766 -212
- package/dist/useProtocolTemplates-BmX_iVBR.js.map +1 -0
- package/dist/utils/color.d.ts +13 -0
- package/dist/utils/errors.d.ts +9 -0
- package/dist/utils/pluginSecrets.d.ts +53 -0
- package/dist/utils/records.d.ts +4 -0
- package/package.json +1 -1
- package/src/__tests__/components/ActionMenu.test.ts +94 -0
- package/src/__tests__/components/AppAvatarMenu.test.ts +123 -0
- package/src/__tests__/components/BaseTabs.test.ts +67 -0
- package/src/__tests__/components/DataFrame.test.ts +183 -11
- package/src/__tests__/components/DataStates.test.ts +176 -0
- package/src/__tests__/components/DatePicker.test.ts +76 -0
- package/src/__tests__/components/DateTimePicker.test.ts +36 -0
- package/src/__tests__/components/DropdownButton.test.ts +134 -0
- package/src/__tests__/components/ExperimentTimeline.test.ts +63 -0
- package/src/__tests__/components/GroupAssigner.test.ts +53 -0
- package/src/__tests__/components/LcmsSequenceTable.test.ts +22 -0
- package/src/__tests__/components/PluginWorkspaceView.internal.test.ts +230 -0
- package/src/__tests__/components/RackEditor.test.ts +35 -0
- package/src/__tests__/components/ReagentList.test.ts +64 -2
- package/src/__tests__/components/RetiredStyles.test.ts +31 -0
- package/src/__tests__/components/SampleSelector.drag.test.ts +51 -1
- package/src/__tests__/components/ScheduleCalendar.test.ts +63 -0
- package/src/__tests__/components/SecretInput.test.ts +87 -0
- package/src/__tests__/components/SegmentedControl.test.ts +88 -0
- package/src/__tests__/components/TimePicker.test.ts +61 -0
- package/src/__tests__/components/WellEditPopupInternal.test.ts +108 -0
- package/src/__tests__/components/WellPlate.interaction.test.ts +59 -0
- package/src/__tests__/composables/useAuth.test.ts +2 -0
- package/src/__tests__/composables/useDropdownState.test.ts +58 -1
- package/src/__tests__/composables/useListReorder.test.ts +145 -0
- package/src/__tests__/composables/usePluginClient.test.ts +140 -0
- package/src/__tests__/composables/usePluginConfig.test.ts +497 -0
- package/src/__tests__/composables/useRequestSyncState.test.ts +140 -0
- package/src/__tests__/docs/frontendDocsCatalog.test.ts +39 -7
- package/src/__tests__/stores/settings.test.ts +71 -1
- package/src/__tests__/styles/cssTokens.test.ts +131 -0
- package/src/__tests__/utils/permissions.test.ts +68 -0
- package/src/components/ActionMenu.vue +45 -88
- package/src/components/AlertBox.vue +0 -4
- package/src/components/AppAvatarMenu.vue +26 -7
- package/src/components/AppLayout.vue +0 -4
- package/src/components/AppPluginSwitcher.story.vue +87 -0
- package/src/components/AppPluginSwitcher.vue +2 -5
- package/src/components/AppSidebar.vue +0 -4
- package/src/components/AppToastContainer.vue +6 -8
- package/src/components/AppTopBar.vue +0 -4
- package/src/components/ArtifactSaveDialog.vue +0 -4
- package/src/components/ArtifactSelectorModal.vue +0 -4
- package/src/components/AuditTrail.story.vue +18 -0
- package/src/components/AuditTrail.vue +27 -7
- package/src/components/AutoGroupModal.vue +0 -4
- package/src/components/Avatar.vue +0 -4
- package/src/components/BaseButton.vue +0 -4
- package/src/components/BaseCheckbox.vue +0 -4
- package/src/components/BaseInput.vue +0 -4
- package/src/components/BaseModal.vue +8 -60
- package/src/components/BasePill.vue +0 -4
- package/src/components/BaseRadioGroup.vue +0 -4
- package/src/components/BaseSelect.vue +0 -4
- package/src/components/BaseSlider.vue +0 -4
- package/src/components/BaseTabs.vue +26 -5
- package/src/components/BaseTextarea.vue +0 -4
- package/src/components/BaseToggle.vue +0 -4
- package/src/components/BatchProgressList.story.vue +18 -0
- package/src/components/BatchProgressList.vue +32 -4
- package/src/components/BioTemplateExperimentWorkspaceView.vue +10 -21
- package/src/components/BioTemplatePackWorkspaceView.vue +11 -15
- package/src/components/BioTemplatePresetWorkspaceView.vue +8 -13
- package/src/components/Breadcrumb.vue +0 -4
- package/src/components/Calendar.vue +0 -4
- package/src/components/ChartContainer.story.vue +1 -1
- package/src/components/ChartContainer.vue +0 -4
- package/src/components/ChemicalFormula.vue +0 -4
- package/src/components/CollapsibleCard.vue +0 -4
- package/src/components/ColorSlider.vue +0 -4
- package/src/components/ComponentBindingRenderer.vue +1 -3
- package/src/components/ConcentrationInput.vue +0 -4
- package/src/components/ConfirmDialog.vue +0 -4
- package/src/components/ControlWorkspaceView.vue +11 -22
- package/src/components/DataFrame.story.vue +14 -0
- package/src/components/DataFrame.vue +97 -23
- package/src/components/DatePicker.vue +73 -27
- package/src/components/DateTimePicker.vue +45 -17
- package/src/components/Divider.vue +0 -4
- package/src/components/DoseCalculator.vue +0 -4
- package/src/components/DoseDesignWorkspaceView.vue +6 -25
- package/src/components/DropdownButton.vue +24 -6
- package/src/components/EmptyState.vue +0 -4
- package/src/components/ExperimentCodeBadge.vue +0 -4
- package/src/components/ExperimentDataViewer.story.vue +3 -0
- package/src/components/ExperimentDataViewer.vue +33 -13
- package/src/components/ExperimentPopover.vue +2 -5
- package/src/components/ExperimentSelectorModal.vue +0 -4
- package/src/components/ExperimentTimeline.story.vue +18 -0
- package/src/components/ExperimentTimeline.vue +81 -75
- package/src/components/FileUploader.vue +0 -4
- package/src/components/FitPanel.vue +0 -4
- package/src/components/FormActions.story.vue +96 -0
- package/src/components/FormActions.vue +0 -4
- package/src/components/FormBuilder.vue +0 -4
- package/src/components/FormField.vue +0 -4
- package/src/components/FormulaInput.vue +0 -4
- package/src/components/GeneratedPathInput.story.vue +68 -0
- package/src/components/GeneratedPlotlyResult.story.vue +96 -0
- package/src/components/GeneratedPlotlyResult.vue +3 -3
- package/src/components/GeneratedPluginView.story.vue +145 -0
- package/src/components/GeneratedPluginView.vue +10 -10
- package/src/components/GeneratedResultRenderer.story.vue +117 -0
- package/src/components/GeneratedResultRenderer.vue +4 -4
- package/src/components/GroupAssigner.vue +67 -5
- package/src/components/IconButton.vue +0 -4
- package/src/components/InstrumentAlertLog.vue +0 -4
- package/src/components/InstrumentStateBadge.vue +0 -4
- package/src/components/InstrumentStatusCard.vue +0 -4
- package/src/components/JobsStatusTray.vue +16 -5
- package/src/components/LcmsSequenceTable.vue +81 -50
- package/src/components/LoadingSpinner.vue +0 -4
- package/src/components/MobileSupportGate.vue +0 -4
- package/src/components/MoleculeInput.vue +0 -4
- package/src/components/MultiSelect.vue +0 -4
- package/src/components/NumberInput.vue +0 -4
- package/src/components/PlateMapEditor.vue +3 -14
- package/src/components/PluginIcon.vue +0 -4
- package/src/components/PluginWorkspaceView.props.ts +38 -0
- package/src/components/PluginWorkspaceView.vue +53 -224
- package/src/components/ProgressBar.vue +0 -4
- package/src/components/ProtocolStepEditor.vue +2 -4
- package/src/components/RackEditor.vue +51 -70
- package/src/components/ReagentEditor.vue +0 -4
- package/src/components/ReagentList.story.vue +18 -0
- package/src/components/ReagentList.vue +127 -82
- package/src/components/ResourceCard.vue +0 -4
- package/src/components/RuntimeUpdateNotice.story.vue +49 -0
- package/src/components/RuntimeUpdateNotice.vue +4 -4
- package/src/components/SampleHierarchyTree.story.vue +18 -0
- package/src/components/SampleHierarchyTree.vue +32 -9
- package/src/components/SampleLegend.vue +2 -8
- package/src/components/SampleSelector.drag.ts +51 -0
- package/src/components/SampleSelector.story.vue +6 -0
- package/src/components/SampleSelector.tree.ts +2 -0
- package/src/components/SampleSelector.vue +49 -10
- package/src/components/SampleSelectorGroupNode.vue +19 -0
- package/src/components/ScheduleCalendar.story.vue +6 -0
- package/src/components/ScheduleCalendar.vue +82 -7
- package/src/components/ScientificNumber.vue +0 -4
- package/src/components/SecretInput.story.vue +79 -0
- package/src/components/SecretInput.vue +150 -0
- package/src/components/SectionCard.vue +0 -4
- package/src/components/SegmentedControl.vue +48 -5
- package/src/components/SequenceInput.vue +0 -4
- package/src/components/SequenceProgressBar.story.vue +110 -0
- package/src/components/SequenceProgressBar.vue +0 -4
- package/src/components/SettingsModal.vue +0 -4
- package/src/components/Skeleton.vue +0 -4
- package/src/components/SmartGroupFieldRecipe.vue +8 -6
- package/src/components/SmartGroupManual.vue +0 -4
- package/src/components/StatusIndicator.vue +0 -4
- package/src/components/StepWizard.vue +0 -4
- package/src/components/TagsInput.vue +4 -6
- package/src/components/ThemeToggle.vue +0 -4
- package/src/components/TimePicker.vue +36 -7
- package/src/components/TimeRangeInput.vue +0 -4
- package/src/components/Tooltip.story.vue +3 -3
- package/src/components/Tooltip.vue +0 -4
- package/src/components/UnitInput.vue +0 -4
- package/src/components/WellPlate.geometry.ts +60 -1
- package/src/components/WellPlate.interaction.ts +44 -0
- package/src/components/WellPlate.story.vue +8 -0
- package/src/components/WellPlate.vue +53 -7
- package/src/components/index.ts +9 -0
- package/src/components/internal/AppTopBarPageSelectorInternal.vue +2 -5
- package/src/components/internal/AppTopBarPillNavInternal.vue +0 -4
- package/src/components/internal/DataStateInternal.vue +74 -0
- package/src/components/internal/FormSectionRenderer.vue +0 -4
- package/src/components/internal/WellEditPopupInternal.vue +20 -5
- package/src/components/internal/WorkspaceControlsInternal.vue +20 -0
- package/src/components/internal/WorkspaceShellInternal.vue +125 -0
- package/src/components/internal/WorkspaceSidebarInternal.vue +82 -0
- package/src/composables/controlSchemaTypes.ts +34 -0
- package/src/composables/experimentDesignData.ts +1 -3
- package/src/composables/flattenWorkspaceBindings.ts +104 -0
- package/src/composables/formBuilderRegistry.ts +5 -0
- package/src/composables/index.ts +43 -0
- package/src/composables/pluginWorkspaceModel.ts +182 -0
- package/src/composables/useAsync.ts +5 -1
- package/src/composables/useAuth.ts +3 -0
- package/src/composables/useBioTemplatePackWorkspace.ts +15 -9
- package/src/composables/useBioTemplatePresetWorkspace.ts +14 -15
- package/src/composables/useBioTemplateWorkspace.ts +18 -43
- package/src/composables/useCommandHistory.ts +5 -1
- package/src/composables/useDropdownState.ts +35 -5
- package/src/composables/useEventStream.ts +14 -2
- package/src/composables/useFileImport.ts +2 -7
- package/src/composables/useFocusTrap.ts +91 -0
- package/src/composables/useGeneratedAnalysis.ts +22 -10
- package/src/composables/useJobsStatusTray.ts +184 -17
- package/src/composables/useListReorder.story.vue +143 -0
- package/src/composables/useListReorder.ts +242 -0
- package/src/composables/useMenuKeyboard.ts +90 -0
- package/src/composables/useOptimisticMutation.ts +6 -16
- package/src/composables/usePluginClient.ts +47 -4
- package/src/composables/usePluginConfig.ts +252 -0
- package/src/composables/usePluginWorkspace.ts +208 -0
- package/src/composables/useRackEditor.ts +2 -11
- package/src/composables/useRequestSyncState.ts +98 -28
- package/src/composables/useResourceCrud.ts +6 -16
- package/src/composables/useRovingFocus.ts +66 -0
- package/src/composables/useScheduleDrag.ts +37 -0
- package/src/composables/useWellPainting.ts +10 -30
- package/src/composables/useWellPlateAdapter.ts +5 -1
- package/src/composables/useWellPlateEditor.ts +1 -11
- package/src/composables/useWellPlateValidation.ts +5 -1
- package/src/composables/workspaceRecipes.ts +267 -0
- package/src/index.ts +16 -0
- package/src/permissions.ts +48 -9
- package/src/stores/auth.ts +1 -0
- package/src/stores/experiment.ts +2 -7
- package/src/stores/index.ts +9 -1
- package/src/stores/settings.ts +93 -1
- package/src/styles/components/audit-trail.css +5 -5
- package/src/styles/components/batch-progress-list.css +7 -0
- package/src/styles/components/color-slider.css +2 -2
- package/src/styles/components/data-state.css +30 -0
- package/src/styles/components/dataframe.css +29 -35
- package/src/styles/components/experiment-data-viewer.css +4 -4
- package/src/styles/components/experiment-timeline.css +3 -30
- package/src/styles/components/form-builder.css +5 -5
- package/src/styles/components/lcms-sequence-table.css +16 -1
- package/src/styles/components/multi-select.css +1 -1
- package/src/styles/components/reagent-list.css +38 -31
- package/src/styles/components/sample-hierarchy-tree.css +5 -19
- package/src/styles/components/sample-selector.css +9 -2
- package/src/styles/components/schedule-calendar.css +8 -0
- package/src/styles/components/scientific-number.css +1 -1
- package/src/styles/components/secret-input.css +60 -0
- package/src/styles/components/well-plate.css +8 -0
- package/src/styles/index.css +9 -0
- package/src/styles/variables.css +29 -0
- package/src/templates/builderPresetControls.ts +1 -1
- package/src/templates/builderReadUtils.ts +1 -3
- package/src/templates/componentPlateHelpers.ts +3 -1
- package/src/templates/componentTargetResolvers.ts +1 -3
- package/src/templates/controlSchemaTargets.ts +1 -3
- package/src/templates/doseResponseAdapters.ts +2 -13
- package/src/templates/elisaAssayCollectionBuilder.ts +2 -2
- package/src/templates/plateMapBuilder.ts +2 -2
- package/src/templates/qpcrPlateBuilder.ts +1 -1
- package/src/templates/templateValidators.ts +1 -1
- package/src/templates/timeCourseBuilder.ts +2 -2
- package/src/templates/wellPlateScreenCollectionBuilder.ts +2 -2
- package/src/types/auth.ts +1 -0
- package/src/types/form-builder.ts +1 -0
- package/src/utils/color.ts +51 -0
- package/src/utils/errors.ts +29 -0
- package/src/utils/formModelSync.ts +1 -3
- package/src/utils/pluginIcon.ts +1 -3
- package/src/utils/pluginSecrets.ts +102 -0
- package/src/utils/records.ts +9 -0
- package/dist/EmptyState-p90quq8Z.js.map +0 -1
- package/dist/ExperimentPopover-tLwJ7XF4.js.map +0 -1
- package/dist/ExperimentSelectorModal-DyPAUCLw.js.map +0 -1
- package/dist/SettingsModal-BgKY93zh.js.map +0 -1
- package/dist/components-DkHddRMl.js.map +0 -1
- package/dist/composables/autoGroupConstants.d.ts +0 -1
- package/dist/composables/autoGroupGrouping.d.ts +0 -3
- package/dist/composables/useAutoGroupInputSources.d.ts +0 -32
- package/dist/composables-C_i90sGS.js.map +0 -1
- package/dist/experiment-Cq145oEW.js.map +0 -1
- package/dist/experiment-utils-CLnzPPq5.js.map +0 -1
- package/dist/templates/builderDefaults.d.ts +0 -1
- package/dist/templates/plateGeometry.d.ts +0 -4
- package/dist/templates-DsP51i-S.js.map +0 -1
- package/dist/useApi-J6zFkHmn.js.map +0 -1
- package/dist/useControlSchema-BDx2Olha.js.map +0 -1
- package/dist/useDropdownState-DSb3BC3N.js.map +0 -1
- package/dist/useProtocolTemplates-CS_SQl6U.js.map +0 -1
- package/src/__tests__/composables/useAutoGroupInputSources.test.ts +0 -127
- package/src/composables/autoGroupConstants.ts +0 -4
- package/src/composables/autoGroupGrouping.ts +0 -148
- package/src/composables/useAutoGroupInputSources.ts +0 -147
- package/src/templates/builderDefaults.ts +0 -11
- package/src/templates/plateGeometry.ts +0 -62
- /package/dist/__tests__/{composables/useAutoGroupInputSources.test.d.ts → components/DataStates.test.d.ts} +0 -0
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import { nextTick, ref, type Ref } from 'vue'
|
|
2
|
+
|
|
3
|
+
/** Inline style for a visually hidden `aria-live` region (no global utility class in the SDK). */
|
|
4
|
+
export const REORDER_ANNOUNCER_STYLE = Object.freeze({
|
|
5
|
+
position: 'absolute',
|
|
6
|
+
width: '1px',
|
|
7
|
+
height: '1px',
|
|
8
|
+
padding: '0',
|
|
9
|
+
margin: '-1px',
|
|
10
|
+
overflow: 'hidden',
|
|
11
|
+
clip: 'rect(0, 0, 0, 0)',
|
|
12
|
+
whiteSpace: 'nowrap',
|
|
13
|
+
border: '0',
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
export interface UseReorderAnnouncerReturn {
|
|
17
|
+
/** Bind to a polite live region's text content. */
|
|
18
|
+
announcement: Ref<string>
|
|
19
|
+
/** Publishes a message to the live region. */
|
|
20
|
+
announce: (message: string) => void
|
|
21
|
+
/** Bind to the live region's `style` so it stays visually hidden. */
|
|
22
|
+
announcerStyle: typeof REORDER_ANNOUNCER_STYLE
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Screen-reader announcements for drag/keyboard move interactions. Bind
|
|
27
|
+
* `announcement` to a `role="status" aria-live="polite"` element styled with
|
|
28
|
+
* `announcerStyle`.
|
|
29
|
+
*/
|
|
30
|
+
export function useReorderAnnouncer(): UseReorderAnnouncerReturn {
|
|
31
|
+
const announcement = ref('')
|
|
32
|
+
|
|
33
|
+
function announce(message: string) {
|
|
34
|
+
// Re-announce identical consecutive messages by clearing first.
|
|
35
|
+
if (announcement.value === message) announcement.value = ''
|
|
36
|
+
void nextTick(() => {
|
|
37
|
+
announcement.value = message
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return { announcement, announce, announcerStyle: REORDER_ANNOUNCER_STYLE }
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface ListReorderMove<T> {
|
|
45
|
+
/** Index the item moved from, within `items()`. */
|
|
46
|
+
fromIndex: number
|
|
47
|
+
/** Index the item moved to, within `items()`. */
|
|
48
|
+
toIndex: number
|
|
49
|
+
/** The reordered array (a copy — `items()` is never mutated). */
|
|
50
|
+
items: T[]
|
|
51
|
+
/** Whether the move came from the keyboard or a pointer drag. */
|
|
52
|
+
source: 'keyboard' | 'drag'
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface UseListReorderOptions<T> {
|
|
56
|
+
/** The list being reordered, in its canonical (not merely rendered) order. */
|
|
57
|
+
items: () => T[]
|
|
58
|
+
/** Stable id for an item; falls back to the render index when ids repeat. */
|
|
59
|
+
getId: (item: T, index: number) => string
|
|
60
|
+
/** Applies the move. The composable never mutates the source array. */
|
|
61
|
+
onReorder: (move: ListReorderMove<T>) => void
|
|
62
|
+
/** Human-readable name used in announcements. Defaults to the item's id. */
|
|
63
|
+
getLabel?: (item: T, index: number) => string
|
|
64
|
+
/** Blocks every reorder while it returns `true` (readonly / non-sortable lists). */
|
|
65
|
+
disabled?: () => boolean
|
|
66
|
+
/** Resolves the focusable element for an id so keyboard moves keep focus on the item. */
|
|
67
|
+
getElement?: (id: string) => HTMLElement | null | undefined
|
|
68
|
+
/** Noun used in announcements, e.g. `'Reagent'`. Default `'Item'`. */
|
|
69
|
+
itemNoun?: string
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface UseListReorderReturn<T> {
|
|
73
|
+
/** Id of the item currently being dragged, or `null`. */
|
|
74
|
+
draggingId: Ref<string | null>
|
|
75
|
+
/** Id of the item the pointer is hovering as a drop target, or `null`. */
|
|
76
|
+
dragOverId: Ref<string | null>
|
|
77
|
+
isDragging: (id: string) => boolean
|
|
78
|
+
isDragOver: (id: string) => boolean
|
|
79
|
+
announcement: Ref<string>
|
|
80
|
+
announcerStyle: typeof REORDER_ANNOUNCER_STYLE
|
|
81
|
+
announce: (message: string) => void
|
|
82
|
+
/** Bind to the draggable element's `@dragstart`. */
|
|
83
|
+
onDragStart: (event: DragEvent, item: T, index: number) => void
|
|
84
|
+
/** Bind to `@dragover` — calls `preventDefault()` so the drop is accepted. */
|
|
85
|
+
onDragOver: (event: DragEvent, item: T, index: number) => void
|
|
86
|
+
/** Bind to `@dragleave`. */
|
|
87
|
+
onDragLeave: () => void
|
|
88
|
+
/** Bind to `@drop`. */
|
|
89
|
+
onDrop: (event: DragEvent, item: T, index: number) => void
|
|
90
|
+
/** Bind to `@dragend`. */
|
|
91
|
+
onDragEnd: () => void
|
|
92
|
+
/**
|
|
93
|
+
* Bind to the item's (or its drag handle's) `@keydown`: Alt+ArrowUp / Alt+ArrowLeft
|
|
94
|
+
* moves the item one position earlier, Alt+ArrowDown / Alt+ArrowRight one later.
|
|
95
|
+
*/
|
|
96
|
+
onKeydown: (event: KeyboardEvent, item: T, index: number) => void
|
|
97
|
+
/** Moves an item between two indices of `items()` programmatically. */
|
|
98
|
+
move: (fromIndex: number, toIndex: number, source?: 'keyboard' | 'drag') => void
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** Pure helper: a copy of `items` with the entry at `from` moved to `to`. */
|
|
102
|
+
export function reorderList<T>(items: T[], from: number, to: number): T[] {
|
|
103
|
+
const next = [...items]
|
|
104
|
+
const [moved] = next.splice(from, 1)
|
|
105
|
+
next.splice(to, 0, moved)
|
|
106
|
+
return next
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Keyboard-accessible list reordering shared by the SDK's drag-to-reorder lists.
|
|
111
|
+
* It owns the HTML5 drag state, the drop-index maths, and an Alt+Arrow keyboard
|
|
112
|
+
* alternative that announces every move through a polite live region — so a
|
|
113
|
+
* reorder never depends on a pointer.
|
|
114
|
+
*/
|
|
115
|
+
export function useListReorder<T>(options: UseListReorderOptions<T>): UseListReorderReturn<T> {
|
|
116
|
+
const draggingId = ref<string | null>(null)
|
|
117
|
+
const dragOverId = ref<string | null>(null)
|
|
118
|
+
const { announcement, announce, announcerStyle } = useReorderAnnouncer()
|
|
119
|
+
const noun = options.itemNoun ?? 'Item'
|
|
120
|
+
|
|
121
|
+
function isDisabled(): boolean {
|
|
122
|
+
return options.disabled?.() === true
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function idFor(item: T, index: number): string {
|
|
126
|
+
return options.getId(item, index)
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/** Index within `items()`, resolved by id so filtered/sorted renders still map back. */
|
|
130
|
+
function indexOf(item: T, renderIndex: number): number {
|
|
131
|
+
const id = idFor(item, renderIndex)
|
|
132
|
+
const found = options.items().findIndex((candidate, index) => idFor(candidate, index) === id)
|
|
133
|
+
return found === -1 ? renderIndex : found
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function labelFor(index: number): string {
|
|
137
|
+
const item = options.items()[index]
|
|
138
|
+
if (item === undefined) return noun
|
|
139
|
+
return options.getLabel?.(item, index) ?? idFor(item, index)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function clearDragState() {
|
|
143
|
+
draggingId.value = null
|
|
144
|
+
dragOverId.value = null
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function move(fromIndex: number, toIndex: number, source: 'keyboard' | 'drag' = 'keyboard') {
|
|
148
|
+
if (isDisabled()) return
|
|
149
|
+
const items = options.items()
|
|
150
|
+
if (
|
|
151
|
+
fromIndex === toIndex ||
|
|
152
|
+
fromIndex < 0 ||
|
|
153
|
+
toIndex < 0 ||
|
|
154
|
+
fromIndex >= items.length ||
|
|
155
|
+
toIndex >= items.length
|
|
156
|
+
) return
|
|
157
|
+
|
|
158
|
+
const movedId = idFor(items[fromIndex], fromIndex)
|
|
159
|
+
const label = labelFor(fromIndex)
|
|
160
|
+
options.onReorder({
|
|
161
|
+
fromIndex,
|
|
162
|
+
toIndex,
|
|
163
|
+
items: reorderList(items, fromIndex, toIndex),
|
|
164
|
+
source,
|
|
165
|
+
})
|
|
166
|
+
announce(`${label} moved to position ${toIndex + 1} of ${items.length}.`)
|
|
167
|
+
void nextTick(() => options.getElement?.(movedId)?.focus())
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function onDragStart(event: DragEvent, item: T, index: number) {
|
|
171
|
+
if (isDisabled()) return
|
|
172
|
+
const id = idFor(item, index)
|
|
173
|
+
draggingId.value = id
|
|
174
|
+
if (event.dataTransfer) {
|
|
175
|
+
event.dataTransfer.effectAllowed = 'move'
|
|
176
|
+
event.dataTransfer.setData('text/plain', id)
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function onDragOver(event: DragEvent, item: T, index: number) {
|
|
181
|
+
if (isDisabled() || draggingId.value === null) return
|
|
182
|
+
event.preventDefault()
|
|
183
|
+
if (event.dataTransfer) event.dataTransfer.dropEffect = 'move'
|
|
184
|
+
const id = idFor(item, index)
|
|
185
|
+
dragOverId.value = id === draggingId.value ? null : id
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function onDragLeave() {
|
|
189
|
+
dragOverId.value = null
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function onDrop(event: DragEvent, item: T, index: number) {
|
|
193
|
+
if (isDisabled() || draggingId.value === null) {
|
|
194
|
+
clearDragState()
|
|
195
|
+
return
|
|
196
|
+
}
|
|
197
|
+
event.preventDefault()
|
|
198
|
+
|
|
199
|
+
const items = options.items()
|
|
200
|
+
const fromIndex = items.findIndex((candidate, i) => idFor(candidate, i) === draggingId.value)
|
|
201
|
+
const toIndex = indexOf(item, index)
|
|
202
|
+
clearDragState()
|
|
203
|
+
if (fromIndex === -1) return
|
|
204
|
+
move(fromIndex, toIndex, 'drag')
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function onDragEnd() {
|
|
208
|
+
clearDragState()
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function onKeydown(event: KeyboardEvent, item: T, index: number) {
|
|
212
|
+
if (isDisabled() || !event.altKey) return
|
|
213
|
+
const direction =
|
|
214
|
+
event.key === 'ArrowUp' || event.key === 'ArrowLeft'
|
|
215
|
+
? -1
|
|
216
|
+
: event.key === 'ArrowDown' || event.key === 'ArrowRight'
|
|
217
|
+
? 1
|
|
218
|
+
: 0
|
|
219
|
+
if (direction === 0) return
|
|
220
|
+
|
|
221
|
+
event.preventDefault()
|
|
222
|
+
const fromIndex = indexOf(item, index)
|
|
223
|
+
move(fromIndex, fromIndex + direction, 'keyboard')
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return {
|
|
227
|
+
draggingId,
|
|
228
|
+
dragOverId,
|
|
229
|
+
isDragging: (id: string) => draggingId.value === id,
|
|
230
|
+
isDragOver: (id: string) => dragOverId.value === id,
|
|
231
|
+
announcement,
|
|
232
|
+
announcerStyle,
|
|
233
|
+
announce,
|
|
234
|
+
onDragStart,
|
|
235
|
+
onDragOver,
|
|
236
|
+
onDragLeave,
|
|
237
|
+
onDrop,
|
|
238
|
+
onDragEnd,
|
|
239
|
+
onKeydown,
|
|
240
|
+
move,
|
|
241
|
+
}
|
|
242
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { nextTick } from 'vue'
|
|
2
|
+
|
|
3
|
+
export interface UseMenuKeyboardOptions {
|
|
4
|
+
/** Returns the currently navigable items inside the open panel, in DOM order. */
|
|
5
|
+
items: () => HTMLElement[]
|
|
6
|
+
/** True while the panel is open. */
|
|
7
|
+
isOpen: () => boolean
|
|
8
|
+
/** Opens the panel. */
|
|
9
|
+
open: () => void
|
|
10
|
+
/** Closes the panel. When `returnFocus` is true, focus should return to the trigger. */
|
|
11
|
+
close: (returnFocus?: boolean) => void
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface UseMenuKeyboardReturn {
|
|
15
|
+
/**
|
|
16
|
+
* Bind to the trigger's `@keydown`. ArrowDown/Enter/Space open the panel (when
|
|
17
|
+
* closed) and focus its first item; ArrowUp opens it focused on the last item.
|
|
18
|
+
*/
|
|
19
|
+
handleTriggerKeydown: (event: KeyboardEvent) => void
|
|
20
|
+
/**
|
|
21
|
+
* Bind to the open panel's `@keydown`. ArrowUp/ArrowDown cycle focus with
|
|
22
|
+
* wraparound, Home/End jump to the first/last item, Escape closes and returns
|
|
23
|
+
* focus to the trigger, and Tab closes without moving focus.
|
|
24
|
+
*/
|
|
25
|
+
handlePanelKeydown: (event: KeyboardEvent) => void
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Shared keyboard contract for menu- and listbox-style disclosure panels (the
|
|
30
|
+
* WAI-ARIA menu button pattern). Used by ActionMenu, AppAvatarMenu and DropdownButton,
|
|
31
|
+
* each pairing it with `useDropdownState` for the disclosure state itself.
|
|
32
|
+
*/
|
|
33
|
+
export function useMenuKeyboard(options: UseMenuKeyboardOptions): UseMenuKeyboardReturn {
|
|
34
|
+
function focusItem(position: 'first' | 'last') {
|
|
35
|
+
void nextTick(() => {
|
|
36
|
+
const items = options.items()
|
|
37
|
+
const target = position === 'first' ? items[0] : items[items.length - 1]
|
|
38
|
+
target?.focus()
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function handleTriggerKeydown(event: KeyboardEvent) {
|
|
43
|
+
if (options.isOpen()) return
|
|
44
|
+
|
|
45
|
+
if (event.key === 'ArrowDown' || event.key === 'Enter' || event.key === ' ') {
|
|
46
|
+
event.preventDefault()
|
|
47
|
+
options.open()
|
|
48
|
+
focusItem('first')
|
|
49
|
+
return
|
|
50
|
+
}
|
|
51
|
+
if (event.key === 'ArrowUp') {
|
|
52
|
+
event.preventDefault()
|
|
53
|
+
options.open()
|
|
54
|
+
focusItem('last')
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function handlePanelKeydown(event: KeyboardEvent) {
|
|
59
|
+
const items = options.items()
|
|
60
|
+
const currentIndex = items.indexOf(document.activeElement as HTMLElement)
|
|
61
|
+
|
|
62
|
+
if (event.key === 'Escape') {
|
|
63
|
+
event.preventDefault()
|
|
64
|
+
options.close(true)
|
|
65
|
+
return
|
|
66
|
+
}
|
|
67
|
+
if (event.key === 'Tab') {
|
|
68
|
+
options.close()
|
|
69
|
+
return
|
|
70
|
+
}
|
|
71
|
+
if (event.key === 'Home') {
|
|
72
|
+
event.preventDefault()
|
|
73
|
+
items[0]?.focus()
|
|
74
|
+
return
|
|
75
|
+
}
|
|
76
|
+
if (event.key === 'End') {
|
|
77
|
+
event.preventDefault()
|
|
78
|
+
items[items.length - 1]?.focus()
|
|
79
|
+
return
|
|
80
|
+
}
|
|
81
|
+
if (event.key !== 'ArrowDown' && event.key !== 'ArrowUp') return
|
|
82
|
+
|
|
83
|
+
event.preventDefault()
|
|
84
|
+
const direction = event.key === 'ArrowDown' ? 1 : -1
|
|
85
|
+
const nextIndex = (Math.max(currentIndex, 0) + direction + items.length) % items.length
|
|
86
|
+
items[nextIndex]?.focus()
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return { handleTriggerKeydown, handlePanelKeydown }
|
|
90
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { computed, ref, shallowRef, type ComputedRef, type Ref, type ShallowRef } from 'vue'
|
|
2
|
+
import { readErrorMessage } from '../utils/errors'
|
|
2
3
|
|
|
3
4
|
export interface OptimisticMutationContext<TVariables, TSnapshot> {
|
|
4
5
|
variables: TVariables
|
|
@@ -32,7 +33,11 @@ export interface UseOptimisticMutationReturn<TVariables, TData, TSnapshot = unkn
|
|
|
32
33
|
reset: () => void
|
|
33
34
|
}
|
|
34
35
|
|
|
35
|
-
/**
|
|
36
|
+
/**
|
|
37
|
+
* Run async mutations with optional optimistic local updates and rollback.
|
|
38
|
+
*
|
|
39
|
+
* @deprecated Unused by the MINT platform and scheduled for removal in MINT 1.3; use `useRequestSyncState()` instead.
|
|
40
|
+
*/
|
|
36
41
|
export function useOptimisticMutation<TVariables, TData, TSnapshot = unknown>(
|
|
37
42
|
options: UseOptimisticMutationOptions<TVariables, TData, TSnapshot>,
|
|
38
43
|
): UseOptimisticMutationReturn<TVariables, TData, TSnapshot> {
|
|
@@ -90,18 +95,3 @@ export function useOptimisticMutation<TVariables, TData, TSnapshot = unknown>(
|
|
|
90
95
|
reset,
|
|
91
96
|
}
|
|
92
97
|
}
|
|
93
|
-
|
|
94
|
-
function readErrorMessage(value: unknown): string {
|
|
95
|
-
if (value instanceof Error && value.message) return value.message
|
|
96
|
-
if (typeof value === 'string' && value.trim()) return value
|
|
97
|
-
if (
|
|
98
|
-
typeof value === 'object'
|
|
99
|
-
&& value !== null
|
|
100
|
-
&& 'message' in value
|
|
101
|
-
&& typeof (value as { message?: unknown }).message === 'string'
|
|
102
|
-
&& (value as { message: string }).message.trim()
|
|
103
|
-
) {
|
|
104
|
-
return (value as { message: string }).message
|
|
105
|
-
}
|
|
106
|
-
return 'Request failed.'
|
|
107
|
-
}
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
import { usePlatformContext } from './usePlatformContext'
|
|
16
16
|
import { useRequestSyncState } from './useRequestSyncState'
|
|
17
17
|
import { useAuthStore } from '../stores/auth'
|
|
18
|
+
import { PLUGIN_SECRET_FORMAT_KEY } from '../utils/pluginSecrets'
|
|
18
19
|
import {
|
|
19
20
|
currentExperimentFromContext,
|
|
20
21
|
getInjectedPlatformContext,
|
|
@@ -538,8 +539,33 @@ function normalizePluginSettingsOptions(options: UsePluginSettingsOptions | stri
|
|
|
538
539
|
return typeof options === 'string' ? { pluginName: options } : options
|
|
539
540
|
}
|
|
540
541
|
|
|
542
|
+
/** @deprecated Use `useGeneratedPluginClient()` for generated clients. */
|
|
543
|
+
export function usePluginClient<TClient>(client: TClient): TClient {
|
|
544
|
+
return client
|
|
545
|
+
}
|
|
546
|
+
|
|
541
547
|
const PLATFORM_OWNED_SETTINGS_KEY = 'allowed_experiment_types'
|
|
542
548
|
|
|
549
|
+
/**
|
|
550
|
+
* Secret settings travel as `{ "$secret": "<id>" }` references, so an untouched
|
|
551
|
+
* secret round-trips without ever exposing its value. Declaring the format on
|
|
552
|
+
* every write keeps a `null` unambiguous: it clears the stored secret instead of
|
|
553
|
+
* meaning "unchanged", which is what the deprecated placeholder form meant.
|
|
554
|
+
*/
|
|
555
|
+
function withSecretFormat(
|
|
556
|
+
payload: Record<string, unknown>,
|
|
557
|
+
secretFormat: string | null,
|
|
558
|
+
): Record<string, unknown> {
|
|
559
|
+
if (!secretFormat) return payload
|
|
560
|
+
return { ...payload, [PLUGIN_SECRET_FORMAT_KEY]: secretFormat }
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
function responseSecretFormat(response: unknown): string | null {
|
|
564
|
+
if (!response || typeof response !== 'object') return null
|
|
565
|
+
const format = (response as Record<string, unknown>)[PLUGIN_SECRET_FORMAT_KEY]
|
|
566
|
+
return typeof format === 'string' && format ? format : null
|
|
567
|
+
}
|
|
568
|
+
|
|
543
569
|
function cloneRecord(value: Record<string, unknown>): Record<string, unknown> {
|
|
544
570
|
return JSON.parse(JSON.stringify(value)) as Record<string, unknown>
|
|
545
571
|
}
|
|
@@ -613,6 +639,7 @@ export function usePluginSettings<TSettings = Record<string, unknown>>(
|
|
|
613
639
|
const values = ref({}) as Ref<PluginSettingsValues<TSettings>>
|
|
614
640
|
const savedValues = shallowRef<Record<string, unknown>>({})
|
|
615
641
|
const revision = ref<string | null>(null)
|
|
642
|
+
const secretFormat = ref<string | null>(null)
|
|
616
643
|
const request = useRequestSyncState('Plugin settings request failed.')
|
|
617
644
|
const isLoading = ref(false)
|
|
618
645
|
const isSaving = ref(false)
|
|
@@ -645,11 +672,16 @@ export function usePluginSettings<TSettings = Record<string, unknown>>(
|
|
|
645
672
|
values.value = cloneRecord(nextValues) as PluginSettingsValues<TSettings>
|
|
646
673
|
}
|
|
647
674
|
|
|
648
|
-
function applyLoaded(
|
|
675
|
+
function applyLoaded(
|
|
676
|
+
nextValues: Record<string, unknown>,
|
|
677
|
+
nextRevision: string | null,
|
|
678
|
+
nextSecretFormat: string | null = secretFormat.value,
|
|
679
|
+
): void {
|
|
649
680
|
const cloned = cloneRecord(nextValues)
|
|
650
681
|
values.value = cloned as PluginSettingsValues<TSettings>
|
|
651
682
|
savedValues.value = cloneRecord(cloned)
|
|
652
683
|
revision.value = nextRevision
|
|
684
|
+
secretFormat.value = nextSecretFormat
|
|
653
685
|
}
|
|
654
686
|
|
|
655
687
|
async function load(): Promise<void> {
|
|
@@ -669,6 +701,7 @@ export function usePluginSettings<TSettings = Record<string, unknown>>(
|
|
|
669
701
|
applyLoaded(
|
|
670
702
|
responseSettingsPayload(response),
|
|
671
703
|
responseSettingsRevision(response),
|
|
704
|
+
responseSecretFormat(response),
|
|
672
705
|
)
|
|
673
706
|
} catch {
|
|
674
707
|
// Error state is handled by request.run().
|
|
@@ -702,7 +735,12 @@ export function usePluginSettings<TSettings = Record<string, unknown>>(
|
|
|
702
735
|
revision?: string
|
|
703
736
|
}>(
|
|
704
737
|
`/plugins/${encodeURIComponent(resolvedPluginName.value)}/config`,
|
|
705
|
-
{
|
|
738
|
+
{
|
|
739
|
+
config: withSecretFormat(
|
|
740
|
+
topLevelSettingsPatch(payload, typedKeys),
|
|
741
|
+
secretFormat.value,
|
|
742
|
+
),
|
|
743
|
+
},
|
|
706
744
|
),
|
|
707
745
|
{ success: 'save', errorMessage: 'Failed to save plugin settings' },
|
|
708
746
|
)
|
|
@@ -725,7 +763,11 @@ export function usePluginSettings<TSettings = Record<string, unknown>>(
|
|
|
725
763
|
}
|
|
726
764
|
|
|
727
765
|
if (!response) return true
|
|
728
|
-
applyLoaded(
|
|
766
|
+
applyLoaded(
|
|
767
|
+
responseSettingsPayload(response),
|
|
768
|
+
nextRevision,
|
|
769
|
+
responseSecretFormat(response) ?? secretFormat.value,
|
|
770
|
+
)
|
|
729
771
|
return true
|
|
730
772
|
} else {
|
|
731
773
|
const ifMatch = revision.value
|
|
@@ -736,13 +778,14 @@ export function usePluginSettings<TSettings = Record<string, unknown>>(
|
|
|
736
778
|
settings: Record<string, unknown>
|
|
737
779
|
mode?: string
|
|
738
780
|
revision?: string
|
|
739
|
-
}>('/settings', payload, ifMatch),
|
|
781
|
+
}>('/settings', withSecretFormat(payload, secretFormat.value), ifMatch),
|
|
740
782
|
{ success: 'save', errorMessage: 'Failed to save plugin settings' },
|
|
741
783
|
)
|
|
742
784
|
}
|
|
743
785
|
applyLoaded(
|
|
744
786
|
responseSettingsPayload(response),
|
|
745
787
|
responseSettingsRevision(response) ?? revision.value,
|
|
788
|
+
responseSecretFormat(response) ?? secretFormat.value,
|
|
746
789
|
)
|
|
747
790
|
return true
|
|
748
791
|
} catch {
|