@morscherlab/mint-sdk 1.2.10 → 1.3.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 +45 -137
- package/dist/ResourcePickerListInternal-CFAw4vTZ.js +605 -0
- package/dist/ResourcePickerListInternal-CFAw4vTZ.js.map +1 -0
- package/dist/__stories__/experiment-helpers.d.ts +12 -1
- package/dist/__tests__/components/ScientificNumber.test.d.ts +1 -0
- package/dist/__tests__/components/SequenceInput.test.d.ts +1 -0
- package/dist/__tests__/components/Skeleton.test.d.ts +1 -0
- package/dist/__tests__/components/SmartGroupFieldRecipe.test.d.ts +1 -0
- package/dist/__tests__/components/SmartGroupModal.test.d.ts +1 -0
- package/dist/__tests__/components/StepWizard.test.d.ts +1 -0
- package/dist/__tests__/components/TimeRangeInput.test.d.ts +1 -0
- package/dist/__tests__/components/UnitInput.test.d.ts +1 -0
- package/dist/__tests__/components/WellPlate.keyboard.test.d.ts +1 -0
- package/dist/__tests__/components/WellPlate.sampleTypeIndicator.test.d.ts +1 -0
- package/dist/__tests__/composables/useChemicalFormula.test.d.ts +1 -0
- package/dist/__tests__/composables/useRackEditor.test.d.ts +1 -0
- package/dist/__tests__/composables/useSequenceUtils.test.d.ts +1 -0
- package/dist/__tests__/styles/baseControlsRules.test.d.ts +1 -0
- package/dist/__tests__/styles/controlRefreshRules.test.d.ts +1 -0
- package/dist/__tests__/styles/darkModeRules.test.d.ts +1 -0
- package/dist/__tests__/styles/menusShellRefresh.test.d.ts +1 -0
- package/dist/__tests__/templates/templatesDeprecation.test.d.ts +1 -0
- package/dist/__tests__/utils/plotlyTemplate.test.d.ts +1 -0
- package/dist/__tests__/utils/sampleTypeMarker.test.d.ts +1 -0
- package/dist/{analysisArtifactTypes-DQ0MjwHZ.js → analysisArtifactTypes-Cy3D0Ipg.js} +1 -1
- package/dist/{analysisArtifactTypes-DQ0MjwHZ.js.map → analysisArtifactTypes-Cy3D0Ipg.js.map} +1 -1
- package/dist/components/ActionMenu.vue.d.ts +17 -5
- package/dist/components/AdductText.vue.d.ts +3 -2
- package/dist/components/AlertBox.vue.d.ts +11 -14
- package/dist/components/AppAvatarMenu.vue.d.ts +18 -28
- package/dist/components/AppContainer.vue.d.ts +7 -11
- package/dist/components/AppLayout.vue.d.ts +11 -13
- package/dist/components/AppSidebar.vue.d.ts +30 -28
- package/dist/components/AppToastContainer.vue.d.ts +2 -1
- package/dist/components/AppTopBar.vue.d.ts +45 -44
- package/dist/components/ArtifactSaveDialog.vue.d.ts +3 -2
- package/dist/components/ArtifactSelectorModal.vue.d.ts +5 -6
- package/dist/components/AuditTrail.vue.d.ts +17 -18
- package/dist/components/AutoGroupModal.vue.d.ts +4 -3
- package/dist/components/Avatar.vue.d.ts +2 -1
- package/dist/components/BaseButton.vue.d.ts +11 -13
- package/dist/components/BaseCheckbox.vue.d.ts +7 -1
- package/dist/components/BaseInput.vue.d.ts +15 -2
- package/dist/components/BaseModal.vue.d.ts +20 -23
- package/dist/components/BasePill.vue.d.ts +10 -13
- package/dist/components/BaseRadioGroup.vue.d.ts +2 -1
- package/dist/components/BaseSelect.vue.d.ts +3 -2
- package/dist/components/BaseSlider.vue.d.ts +18 -1
- package/dist/components/BaseTabs.vue.d.ts +2 -1
- package/dist/components/BaseTextarea.vue.d.ts +2 -1
- package/dist/components/BaseToggle.vue.d.ts +2 -1
- package/dist/components/BatchProgressList.vue.d.ts +22 -26
- package/dist/components/BioTemplateExperimentWorkspaceView.vue.d.ts +7 -14
- package/dist/components/BioTemplatePackWorkspaceView.vue.d.ts +6 -13
- package/dist/components/BioTemplatePresetWorkspaceView.vue.d.ts +7 -14
- package/dist/components/BioTemplateRenderer.vue.d.ts +2 -1
- package/dist/components/Breadcrumb.vue.d.ts +13 -16
- package/dist/components/Calendar.vue.d.ts +21 -23
- package/dist/components/ChartContainer.vue.d.ts +19 -25
- package/dist/components/ChemicalFormula.vue.d.ts +7 -11
- package/dist/components/CollapsibleCard.vue.d.ts +7 -11
- package/dist/components/ComponentBindingRenderer.vue.d.ts +2 -1
- package/dist/components/ConcentrationInput.vue.d.ts +2 -1
- package/dist/components/ConfirmDialog.vue.d.ts +10 -13
- package/dist/components/ControlWorkspaceView.vue.d.ts +9 -18
- package/dist/components/DataFrame.vue.d.ts +27 -24
- package/dist/components/DatePicker.vue.d.ts +3 -6
- package/dist/components/DateTimePicker.vue.d.ts +3 -6
- package/dist/components/Divider.vue.d.ts +3 -2
- package/dist/components/DoseCalculator.vue.d.ts +2 -1
- package/dist/components/DoseCalculatorVolumeField.vue.d.ts +2 -1
- package/dist/components/DoseDesignWorkspaceView.vue.d.ts +9 -18
- package/dist/components/EmptyState.vue.d.ts +9 -12
- package/dist/components/ExperimentCodeBadge.vue.d.ts +2 -1
- package/dist/components/ExperimentDataViewer.vue.d.ts +13 -15
- package/dist/components/ExperimentPopover.vue.d.ts +3 -5
- package/dist/components/ExperimentSelectorModal.vue.d.ts +3 -4
- package/dist/components/ExperimentTimeline.vue.d.ts +13 -15
- package/dist/components/FilePicker.vue.d.ts +10 -5
- package/dist/components/FileUploader.vue.d.ts +8 -16
- package/dist/components/FitPanel.vue.d.ts +26 -16
- package/dist/components/FormActions.vue.d.ts +2 -1
- package/dist/components/FormBuilder.vue.d.ts +54 -250
- package/dist/components/FormField.vue.d.ts +14 -16
- package/dist/components/FormulaInput.vue.d.ts +2 -1
- package/dist/components/GeneratedPathInput.vue.d.ts +6 -5
- package/dist/components/GeneratedPlotlyResult.vue.d.ts +2 -1
- package/dist/components/GeneratedPluginView.vue.d.ts +2 -1
- package/dist/components/GeneratedResultRenderer.vue.d.ts +2 -1
- package/dist/components/GroupAssigner.vue.d.ts +2 -1
- package/dist/components/IconButton.vue.d.ts +7 -11
- package/dist/components/InstrumentStateBadge.vue.d.ts +4 -3
- package/dist/components/JobsStatusTray.vue.d.ts +13 -29
- package/dist/components/LayoutResizeHandle.vue.d.ts +2 -1
- package/dist/components/LoadingSpinner.vue.d.ts +2 -1
- package/dist/components/MobileSupportGate.vue.d.ts +5 -13
- package/dist/components/MoleculeInput.vue.d.ts +3 -4
- package/dist/components/MultiSelect.vue.d.ts +2 -1
- package/dist/components/NumberInput.vue.d.ts +2 -1
- package/dist/components/PlateEditor.vue.d.ts +147 -0
- package/dist/components/PlotlyChart.vue.d.ts +21 -31
- package/dist/components/PluginIcon.vue.d.ts +2 -1
- package/dist/components/PluginWorkspaceView.props.d.ts +2 -6
- package/dist/components/PluginWorkspaceView.vue.d.ts +23 -51
- package/dist/components/ProgressBar.vue.d.ts +4 -9
- package/dist/components/ProtocolStepEditor.vue.d.ts +7 -5
- package/dist/components/ProtocolStepParameterField.vue.d.ts +2 -1
- package/dist/components/ReagentEditor.vue.d.ts +2 -1
- package/dist/components/ReagentList.presentation.d.ts +2 -1
- package/dist/components/ReagentList.vue.d.ts +15 -17
- package/dist/components/ResourceCard.vue.d.ts +18 -17
- package/dist/components/RuntimeUpdateNotice.vue.d.ts +3 -2
- package/dist/components/SampleHierarchyTree.vue.d.ts +21 -15
- package/dist/components/SampleLegend.vue.d.ts +2 -1
- package/dist/components/SampleSelector.vue.d.ts +15 -21
- package/dist/components/SampleSelectorGroupNode.vue.d.ts +2 -1
- package/dist/components/SampleSelectorSampleRow.vue.d.ts +2 -5
- package/dist/components/ScheduleCalendar.vue.d.ts +34 -36
- package/dist/components/ScientificNumber.vue.d.ts +3 -2
- package/dist/components/SearchableSelect.vue.d.ts +14 -32
- package/dist/components/SecretInput.vue.d.ts +2 -1
- package/dist/components/SectionCard.vue.d.ts +13 -14
- package/dist/components/SegmentedControl.vue.d.ts +2 -1
- package/dist/components/SequenceInput.vue.d.ts +10 -21
- package/dist/components/SequenceProgressBar.vue.d.ts +2 -1
- package/dist/components/SettingsModal.schema.d.ts +1 -1
- package/dist/components/SettingsModal.vue.d.ts +28 -25
- package/dist/components/Skeleton.vue.d.ts +2 -1
- package/dist/components/SmartGroup.types.d.ts +2 -2
- package/dist/components/SmartGroupFieldRecipe.groups.d.ts +2 -0
- package/dist/components/SmartGroupFieldRecipe.vue.d.ts +4 -7
- package/dist/components/SmartGroupManual.vue.d.ts +3 -2
- package/dist/components/SmartGroupModal.vue.d.ts +6 -4
- package/dist/components/StatusIndicator.vue.d.ts +2 -1
- package/dist/components/StepWizard.vue.d.ts +26 -27
- package/dist/components/TagsInput.vue.d.ts +3 -5
- package/dist/components/ThemeToggle.vue.d.ts +2 -1
- package/dist/components/TimePicker.vue.d.ts +6 -6
- package/dist/components/TimeRangeInput.vue.d.ts +9 -2
- package/dist/components/Tooltip.vue.d.ts +8 -18
- package/dist/components/UnitInput.vue.d.ts +2 -1
- package/dist/components/WellPlate.colors.d.ts +2 -4
- package/dist/components/WellPlate.rendering.d.ts +7 -1
- package/dist/components/WellPlate.sampleDrop.d.ts +2 -0
- package/dist/components/WellPlate.vue.d.ts +22 -39
- package/dist/components/index.d.ts +34 -31
- package/dist/components/index.js +5 -8
- package/dist/components/internal/ActionItemInternal.vue.d.ts +11 -13
- package/dist/components/internal/AppTopBarPageSelectorInternal.vue.d.ts +14 -23
- package/dist/components/internal/AppTopBarPillNavInternal.vue.d.ts +2 -1
- package/dist/components/internal/CalendarGridPanelInternal.vue.d.ts +2 -1
- package/dist/components/internal/DataStateInternal.vue.d.ts +7 -11
- package/dist/components/internal/{FilePickerTreeInternal.vue.d.ts → FilePickerListInternal.vue.d.ts} +9 -6
- package/dist/components/internal/FilePickerPreviewInternal.vue.d.ts +4 -3
- package/dist/components/internal/FormFieldRendererInternal.vue.d.ts +16 -18
- package/dist/components/internal/FormSectionRenderer.vue.d.ts +36 -32
- package/dist/components/internal/PlateEditorBindingInternal.vue.d.ts +8 -0
- package/dist/components/internal/ResourcePickerListInternal.vue.d.ts +65 -0
- package/dist/components/internal/SettingsPaneHeadInternal.vue.d.ts +15 -0
- package/dist/components/internal/WellEditPopupInternal.vue.d.ts +12 -4
- package/dist/components/internal/WorkspaceControlsInternal.vue.d.ts +6 -13
- package/dist/components/internal/WorkspaceShellInternal.vue.d.ts +19 -42
- package/dist/components/internal/WorkspaceSidebarInternal.vue.d.ts +9 -19
- package/dist/components/internal/filePickerPresentation.d.ts +8 -0
- package/dist/components/internal/generatedJobsApi.d.ts +9 -0
- package/dist/{components-Bbg_gtzF.js → components-GDDvof8D.js} +7088 -5955
- package/dist/components-GDDvof8D.js.map +1 -0
- package/dist/composables/controlSchemaTypes.d.ts +4 -43
- package/dist/composables/createFilePickerAdapter.d.ts +5 -1
- package/dist/composables/filePicker/usePickerNavigation.d.ts +7 -2
- package/dist/composables/index.d.ts +2 -13
- package/dist/composables/index.js +7 -11
- package/dist/composables/pluginWorkspaceModel.d.ts +1 -3
- package/dist/composables/useAutoGroup.d.ts +10 -0
- package/dist/composables/useBioTemplateComponents.d.ts +15 -3
- package/dist/composables/useBioTemplateControls.d.ts +5 -1
- package/dist/composables/useBioTemplatePackWorkspace.d.ts +2 -0
- package/dist/composables/useBioTemplatePresetWorkspace.d.ts +5 -1
- package/dist/composables/useBioTemplateWorkspace.d.ts +5 -1
- package/dist/composables/useChemicalFormula.d.ts +2 -1
- package/dist/composables/useDropdownState.d.ts +5 -0
- package/dist/composables/useExperimentSave.d.ts +5 -1
- package/dist/composables/useFileBrowser.d.ts +3 -2
- package/dist/composables/useFilePicker.d.ts +25 -13
- package/dist/composables/useFocusTrap.d.ts +2 -1
- package/dist/composables/useGroupAssignment.d.ts +5 -1
- package/dist/composables/useJobsStatusTray.d.ts +5 -5
- package/dist/composables/useMenuKeyboard.d.ts +3 -3
- package/dist/composables/usePlatformContext.d.ts +3 -0
- package/dist/composables/usePluginClient.d.ts +1 -1
- package/dist/composables/useRackEditor.d.ts +36 -1
- package/dist/composables/useSequenceUtils.d.ts +8 -0
- package/dist/composables/useTemplateCollection.d.ts +5 -1
- package/dist/composables/workspaceRecipes.d.ts +1 -0
- package/dist/composables-D6uqp0UF.js +591 -0
- package/dist/composables-D6uqp0UF.js.map +1 -0
- package/dist/{errors-BLuqMee5.js → experiment-DgllIc3I.js} +89 -333
- package/dist/experiment-DgllIc3I.js.map +1 -0
- package/dist/{experiment-utils-CV2Wza3z.js → experiment-utils-DTANyVKV.js} +68 -37
- package/dist/experiment-utils-DTANyVKV.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +122 -17
- package/dist/index.js.map +1 -1
- package/dist/install.js +1 -2
- package/dist/install.js.map +1 -1
- package/dist/instrument.d.ts +6 -0
- package/dist/lcms.d.ts +11 -0
- package/dist/permissions.d.ts +2 -47
- package/dist/permissions.js +2 -26
- package/dist/permissions.js.map +1 -1
- package/dist/settings-BLr8lzw6.js +341 -0
- package/dist/settings-BLr8lzw6.js.map +1 -0
- package/dist/stores/auth.d.ts +2 -150
- package/dist/stores/experiment.d.ts +2 -106
- package/dist/stores/index.js +2 -2
- package/dist/stores/settings.d.ts +2 -44
- package/dist/styles.css +8608 -6950
- package/dist/tailwind.preset.js.map +1 -1
- package/dist/templates/adapters.d.ts +3 -0
- package/dist/templates/assayMatrixAdapters.d.ts +8 -1
- package/dist/templates/assayMatrixBuilder.d.ts +1 -0
- package/dist/templates/builderPresetControls.d.ts +1 -0
- package/dist/templates/calibrationCurveAdapters.d.ts +3 -0
- package/dist/templates/calibrationCurveBuilder.d.ts +1 -0
- package/dist/templates/catalog.d.ts +6 -2
- package/dist/templates/componentBindings.d.ts +31 -5
- package/dist/templates/componentPlateHelpers.d.ts +7 -1
- package/dist/templates/controlSchemas.d.ts +9 -0
- package/dist/templates/defaultBioTemplateBuilder.d.ts +1 -0
- package/dist/templates/doseResponseAdapters.d.ts +2 -0
- package/dist/templates/doseResponseBuilder.d.ts +1 -0
- package/dist/templates/elisaAssayCollectionBuilder.d.ts +1 -0
- package/dist/templates/flowCytometryAssayCollectionBuilder.d.ts +1 -0
- package/dist/templates/flowCytometryPanelBuilder.d.ts +1 -0
- package/dist/templates/flowPanelAdapters.d.ts +3 -0
- package/dist/templates/index.d.ts +1 -1
- package/dist/templates/index.js +2 -3
- package/dist/templates/instrumentRunAdapters.d.ts +13 -2
- package/dist/templates/instrumentRunBuilder.d.ts +1 -0
- package/dist/templates/lcmsBatchCollectionBuilder.d.ts +1 -0
- package/dist/templates/packs.d.ts +4 -0
- package/dist/templates/plateMapAdapters.d.ts +2 -0
- package/dist/templates/plateMapBuilder.d.ts +1 -0
- package/dist/templates/presets.d.ts +6 -2
- package/dist/templates/protocolAdapters.d.ts +4 -0
- package/dist/templates/protocolStepsBuilder.d.ts +1 -0
- package/dist/templates/qpcrAdapters.d.ts +4 -0
- package/dist/templates/qpcrExpressionCollectionBuilder.d.ts +1 -0
- package/dist/templates/qpcrPlateBuilder.d.ts +1 -0
- package/dist/templates/reagentAdapters.d.ts +4 -0
- package/dist/templates/reagentListBuilder.d.ts +1 -0
- package/dist/templates/samplePrepAdapters.d.ts +3 -0
- package/dist/templates/samplePrepBuilder.d.ts +1 -0
- package/dist/templates/sampleSheetAdapters.d.ts +4 -0
- package/dist/templates/sampleSheetBuilder.d.ts +1 -0
- package/dist/templates/targetedMetabolomicsCollectionBuilder.d.ts +1 -0
- package/dist/templates/templateEnvelopes.d.ts +8 -0
- package/dist/templates/templatePackCollectionBuilder.d.ts +1 -0
- package/dist/templates/templatePresetCollectionBuilder.d.ts +2 -0
- package/dist/templates/templateValidators.d.ts +12 -0
- package/dist/templates/timeCourseAdapters.d.ts +4 -0
- package/dist/templates/timeCourseBuilder.d.ts +1 -0
- package/dist/templates/wellPlateScreenCollectionBuilder.d.ts +1 -0
- package/dist/templates/westernBlotAssayCollectionBuilder.d.ts +1 -0
- package/dist/templates-BU1pet28.js +12304 -0
- package/dist/templates-BU1pet28.js.map +1 -0
- package/dist/types/auth.d.ts +0 -27
- package/dist/types/componentLabTypes.d.ts +14 -7
- package/dist/types/componentWorkflowTypes.d.ts +26 -0
- package/dist/types/components.d.ts +40 -17
- package/dist/types/fileBrowserTypes.d.ts +13 -0
- package/dist/types/filePicker.d.ts +19 -1
- package/dist/types/generated-ui.d.ts +13 -0
- package/dist/types/index.d.ts +4 -4
- package/dist/types/index.js +1 -1
- package/dist/types/instrument.d.ts +43 -15
- package/dist/types/platform.d.ts +2 -0
- package/dist/utils/color.d.ts +6 -1
- package/dist/utils/formModelSync.d.ts +1 -0
- package/dist/utils/plotlyTemplate.d.ts +3 -0
- package/dist/utils/rack.d.ts +16 -0
- package/dist/utils/sampleTypeMarker.d.ts +23 -0
- package/dist/{validation-ChMyixAf.js → validation-Dmp9Q5W0.js} +3032 -838
- package/dist/validation-Dmp9Q5W0.js.map +1 -0
- package/package.json +17 -23
- package/src/__stories__/experiment-helpers.ts +8 -4
- package/src/__tests__/components/ActionMenu.test.ts +66 -0
- package/src/__tests__/components/AlertBox.test.ts +21 -0
- package/src/__tests__/components/AppAvatarMenu.test.ts +25 -0
- package/src/__tests__/components/AppTopBar.test.ts +79 -0
- package/src/__tests__/components/AppTopBarPageSelector.test.ts +20 -0
- package/src/__tests__/components/AppTopBarPillNav.test.ts +74 -0
- package/src/__tests__/components/ArtifactSelectorModal.test.ts +20 -6
- package/src/__tests__/components/AuditTrail.test.ts +38 -0
- package/src/__tests__/components/BaseCheckbox.test.ts +43 -0
- package/src/__tests__/components/BaseInput.test.ts +43 -0
- package/src/__tests__/components/BaseModal.test.ts +90 -0
- package/src/__tests__/components/BaseRadioGroup.test.ts +8 -0
- package/src/__tests__/components/BaseSlider.test.ts +116 -0
- package/src/__tests__/components/BaseToggle.test.ts +7 -0
- package/src/__tests__/components/BatchProgressList.test.ts +22 -14
- package/src/__tests__/components/BioTemplateExperimentWorkspaceView.test.ts +4 -4
- package/src/__tests__/components/BioTemplatePackWorkspaceView.test.ts +1 -1
- package/src/__tests__/components/BioTemplatePresetWorkspaceView.test.ts +8 -8
- package/src/__tests__/components/BioTemplateRenderer.test.ts +2 -2
- package/src/__tests__/components/Breadcrumb.test.ts +45 -0
- package/src/__tests__/components/CalendarGridPanel.test.ts +14 -0
- package/src/__tests__/components/ChartContainer.test.ts +23 -0
- package/src/__tests__/components/ChemicalFormula.test.ts +15 -0
- package/src/__tests__/components/CollapsibleCard.test.ts +12 -9
- package/src/__tests__/components/ComponentBindingRenderer.test.ts +45 -17
- package/src/__tests__/components/ConcentrationInput.test.ts +17 -2
- package/src/__tests__/components/DataFrame.test.ts +107 -4
- package/src/__tests__/components/DataStates.test.ts +0 -16
- package/src/__tests__/components/DatePicker.test.ts +10 -0
- package/src/__tests__/components/DoseCalculator.test.ts +47 -0
- package/src/__tests__/components/DoseCalculatorVolumeField.test.ts +37 -34
- package/src/__tests__/components/EmptyState.test.ts +16 -1
- package/src/__tests__/components/ExperimentSelectorModal.test.ts +31 -3
- package/src/__tests__/components/ExperimentTimeline.test.ts +45 -0
- package/src/__tests__/components/FilePicker.state.test.ts +2 -2
- package/src/__tests__/components/FilePicker.test.ts +360 -13
- package/src/__tests__/components/FileUploader.test.ts +15 -0
- package/src/__tests__/components/FitPanel.test.ts +96 -0
- package/src/__tests__/components/FormulaInput.test.ts +97 -0
- package/src/__tests__/components/GeneratedPathInput.test.ts +168 -41
- package/src/__tests__/components/GeneratedPlotlyResult.test.ts +1 -1
- package/src/__tests__/components/GeneratedResultRenderer.test.ts +47 -2
- package/src/__tests__/components/InstrumentStateBadge.test.ts +50 -0
- package/src/__tests__/components/JobsStatusTray.test.ts +27 -0
- package/src/__tests__/components/MoleculeInput.test.ts +78 -0
- package/src/__tests__/components/MultiSelect.test.ts +6 -0
- package/src/__tests__/components/PlateEditor.test.ts +1134 -0
- package/src/__tests__/components/PlateEditorBindingInternal.test.ts +64 -0
- package/src/__tests__/components/PlotlyChart.test.ts +147 -1
- package/src/__tests__/components/ProgressBar.test.ts +18 -0
- package/src/__tests__/components/ProtocolStepEditor.test.ts +106 -18
- package/src/__tests__/components/ProtocolStepParameterField.test.ts +74 -29
- package/src/__tests__/components/ReagentList.presentation.test.ts +10 -5
- package/src/__tests__/components/ReagentList.test.ts +23 -0
- package/src/__tests__/components/ResourcePickerListInternal.test.ts +141 -0
- package/src/__tests__/components/RetiredStyles.test.ts +0 -6
- package/src/__tests__/components/SampleHierarchyTree.test.ts +102 -0
- package/src/__tests__/components/SampleLegend.test.ts +18 -0
- package/src/__tests__/components/SampleSelector.test.ts +92 -1
- package/src/__tests__/components/SampleSelectorSampleRow.test.ts +5 -2
- package/src/__tests__/components/ScheduleCalendar.test.ts +32 -0
- package/src/__tests__/components/ScientificNumber.test.ts +113 -0
- package/src/__tests__/components/SearchableSelect.test.ts +21 -0
- package/src/__tests__/components/SecretInput.test.ts +6 -0
- package/src/__tests__/components/SegmentedControl.test.ts +14 -0
- package/src/__tests__/components/SequenceInput.test.ts +81 -0
- package/src/__tests__/components/SettingsModal.schema.test.ts +5 -5
- package/src/__tests__/components/SettingsModal.test.ts +371 -23
- package/src/__tests__/components/Skeleton.test.ts +23 -0
- package/src/__tests__/components/SmartGroupFieldRecipe.test.ts +12 -0
- package/src/__tests__/components/SmartGroupModal.test.ts +69 -0
- package/src/__tests__/components/StepWizard.test.ts +75 -0
- package/src/__tests__/components/TagsInput.test.ts +16 -0
- package/src/__tests__/components/TimePicker.test.ts +66 -0
- package/src/__tests__/components/TimeRangeInput.test.ts +83 -0
- package/src/__tests__/components/UnitInput.test.ts +147 -0
- package/src/__tests__/components/WellEditPopupInternal.test.ts +434 -2
- package/src/__tests__/components/WellPlate.decoration.test.ts +18 -0
- package/src/__tests__/components/WellPlate.geometry.test.ts +13 -0
- package/src/__tests__/components/WellPlate.interaction.test.ts +213 -0
- package/src/__tests__/components/WellPlate.keyboard.test.ts +24 -0
- package/src/__tests__/components/WellPlate.rendering.test.ts +38 -19
- package/src/__tests__/components/WellPlate.sampleDrop.test.ts +19 -0
- package/src/__tests__/components/WellPlate.sampleTypeIndicator.test.ts +58 -0
- package/src/__tests__/composables/createFilePickerAdapter.test.ts +114 -1
- package/src/__tests__/composables/useBioTemplatePackWorkspace.test.ts +1 -1
- package/src/__tests__/composables/useBioTemplateWorkspace.test.ts +1 -1
- package/src/__tests__/composables/useChemicalFormula.test.ts +60 -0
- package/src/__tests__/composables/useControlSchema.test.ts +15 -5
- package/src/__tests__/composables/useDropdownState.test.ts +20 -1
- package/src/__tests__/composables/useGeneratedAnalysis.test.ts +52 -0
- package/src/__tests__/composables/usePickerNavigation.test.ts +61 -1
- package/src/__tests__/composables/usePlatformFilePickerAdapter.test.ts +18 -6
- package/src/__tests__/composables/useRackEditor.test.ts +270 -0
- package/src/__tests__/composables/useSequenceUtils.test.ts +28 -0
- package/src/__tests__/docs/frontendDocsCatalog.test.ts +44 -9
- package/src/__tests__/styles/baseControlsRules.test.ts +115 -0
- package/src/__tests__/styles/controlRefreshRules.test.ts +218 -0
- package/src/__tests__/styles/cssTokens.test.ts +7 -5
- package/src/__tests__/styles/darkModeRules.test.ts +47 -0
- package/src/__tests__/styles/menusShellRefresh.test.ts +75 -0
- package/src/__tests__/templates/templates.test.ts +65 -15
- package/src/__tests__/templates/templatesDeprecation.test.ts +78 -0
- package/src/__tests__/utils/permissions.test.ts +0 -68
- package/src/__tests__/utils/plotlyTemplate.test.ts +69 -0
- package/src/__tests__/utils/sampleTypeMarker.test.ts +54 -0
- package/src/components/ActionMenu.vue +44 -23
- package/src/components/AdductText.story.vue +18 -0
- package/src/components/AdductText.vue +7 -1
- package/src/components/AlertBox.vue +3 -7
- package/src/components/AppAvatarMenu.vue +12 -10
- package/src/components/AppSidebar.vue +1 -1
- package/src/components/AppTopBar.story.vue +47 -4
- package/src/components/AppTopBar.vue +16 -22
- package/src/components/ArtifactSelectorModal.story.vue +1 -1
- package/src/components/ArtifactSelectorModal.vue +48 -160
- package/src/components/AuditTrail.vue +26 -12
- package/src/components/AutoGroupModal.vue +1 -1
- package/src/components/BaseCheckbox.story.vue +58 -2
- package/src/components/BaseCheckbox.vue +21 -3
- package/src/components/BaseInput.story.vue +51 -0
- package/src/components/BaseInput.vue +62 -1
- package/src/components/BaseModal.story.vue +55 -0
- package/src/components/BaseModal.vue +83 -50
- package/src/components/BaseRadioGroup.vue +1 -1
- package/src/components/BaseSlider.story.vue +36 -0
- package/src/components/BaseSlider.vue +56 -8
- package/src/components/BaseToggle.vue +1 -7
- package/src/components/BatchProgressList.vue +50 -52
- package/src/components/BioTemplatePresetWorkspaceView.vue +1 -1
- package/src/components/Breadcrumb.story.vue +1 -1
- package/src/components/Breadcrumb.vue +50 -15
- package/src/components/ChartContainer.story.vue +42 -0
- package/src/components/ChartContainer.vue +22 -1
- package/src/components/ChemicalFormula.story.vue +11 -11
- package/src/components/ChemicalFormula.vue +1 -0
- package/src/components/CollapsibleCard.vue +12 -32
- package/src/components/ComponentBindingRenderer.vue +6 -8
- package/src/components/ConcentrationInput.story.vue +1 -1
- package/src/components/ConcentrationInput.vue +8 -14
- package/src/components/ControlWorkspaceView.vue +1 -1
- package/src/components/DataFrame.story.vue +45 -2
- package/src/components/DataFrame.vue +28 -13
- package/src/components/DatePicker.story.vue +11 -0
- package/src/components/DatePicker.vue +5 -5
- package/src/components/DateTimePicker.story.vue +1 -1
- package/src/components/DateTimePicker.vue +8 -5
- package/src/components/Divider.story.vue +1 -1
- package/src/components/DoseCalculator.vue +44 -51
- package/src/components/DoseCalculatorVolumeField.vue +22 -35
- package/src/components/DoseDesignWorkspaceView.vue +1 -1
- package/src/components/EmptyState.story.vue +4 -4
- package/src/components/EmptyState.vue +4 -2
- package/src/components/ExperimentPopover.story.vue +2 -2
- package/src/components/ExperimentPopover.vue +6 -4
- package/src/components/ExperimentSelectorModal.story.vue +2 -1
- package/src/components/ExperimentSelectorModal.vue +91 -261
- package/src/components/ExperimentTimeline.story.vue +29 -0
- package/src/components/ExperimentTimeline.vue +20 -0
- package/src/components/FilePicker.story.vue +65 -10
- package/src/components/FilePicker.vue +203 -121
- package/src/components/FitPanel.story.vue +72 -6
- package/src/components/FitPanel.vue +70 -18
- package/src/components/FormField.vue +2 -0
- package/src/components/FormulaInput.story.vue +6 -0
- package/src/components/FormulaInput.vue +49 -70
- package/src/components/GeneratedPathInput.story.vue +121 -8
- package/src/components/GeneratedPathInput.vue +155 -86
- package/src/components/GeneratedPlotlyResult.vue +1 -1
- package/src/components/GeneratedPluginView.vue +4 -4
- package/src/components/GeneratedResultRenderer.vue +19 -0
- package/src/components/InstrumentStateBadge.story.vue +41 -0
- package/src/components/InstrumentStateBadge.vue +24 -14
- package/src/components/JobsStatusTray.vue +30 -8
- package/src/components/MoleculeInput.vue +12 -7
- package/src/components/MultiSelect.vue +3 -3
- package/src/components/PlateEditor.story.vue +333 -0
- package/src/components/PlateEditor.vue +793 -0
- package/src/components/PlotlyChart.story.vue +37 -1
- package/src/components/PlotlyChart.vue +86 -16
- package/src/components/PluginWorkspaceView.props.ts +1 -7
- package/src/components/PluginWorkspaceView.vue +0 -4
- package/src/components/ProgressBar.story.vue +0 -30
- package/src/components/ProgressBar.vue +3 -53
- package/src/components/ProtocolStepEditor.story.vue +8 -0
- package/src/components/ProtocolStepEditor.vue +55 -145
- package/src/components/ProtocolStepParameterField.vue +55 -93
- package/src/components/ReagentList.presentation.ts +7 -6
- package/src/components/ReagentList.vue +18 -17
- package/src/components/SampleHierarchyTree.story.vue +19 -0
- package/src/components/SampleHierarchyTree.vue +47 -14
- package/src/components/SampleLegend.vue +12 -4
- package/src/components/SampleSelector.story.vue +5 -1
- package/src/components/SampleSelector.vue +25 -15
- package/src/components/SampleSelectorGroupNode.vue +10 -20
- package/src/components/SampleSelectorSampleRow.vue +7 -18
- package/src/components/ScheduleCalendar.story.vue +14 -0
- package/src/components/ScheduleCalendar.vue +13 -1
- package/src/components/ScientificNumber.story.vue +15 -2
- package/src/components/ScientificNumber.vue +22 -26
- package/src/components/SearchableSelect.vue +14 -9
- package/src/components/SecretInput.vue +1 -1
- package/src/components/SegmentedControl.story.vue +23 -0
- package/src/components/SegmentedControl.vue +6 -1
- package/src/components/SequenceInput.story.vue +27 -5
- package/src/components/SequenceInput.vue +74 -29
- package/src/components/SequenceProgressBar.vue +0 -1
- package/src/components/SettingsModal.schema.ts +4 -2
- package/src/components/SettingsModal.story.vue +83 -22
- package/src/components/SettingsModal.vue +338 -79
- package/src/components/Skeleton.vue +6 -35
- package/src/components/SmartGroup.types.ts +2 -2
- package/src/components/SmartGroupFieldRecipe.groups.ts +4 -1
- package/src/components/SmartGroupFieldRecipe.vue +14 -8
- package/src/components/SmartGroupManual.vue +14 -11
- package/src/components/StepWizard.vue +16 -19
- package/src/components/TagsInput.story.vue +16 -11
- package/src/components/TagsInput.vue +20 -3
- package/src/components/TimePicker.story.vue +38 -3
- package/src/components/TimePicker.vue +26 -11
- package/src/components/TimeRangeInput.story.vue +50 -1
- package/src/components/TimeRangeInput.vue +36 -17
- package/src/components/UnitInput.story.vue +1 -1
- package/src/components/UnitInput.vue +173 -107
- package/src/components/WellPlate.colors.ts +7 -6
- package/src/components/WellPlate.geometry.ts +3 -0
- package/src/components/WellPlate.interaction.ts +39 -5
- package/src/components/WellPlate.rendering.ts +21 -27
- package/src/components/WellPlate.sampleDrop.ts +20 -12
- package/src/components/WellPlate.story.vue +18 -7
- package/src/components/WellPlate.vue +28 -22
- package/src/components/index.ts +34 -31
- package/src/components/internal/AppTopBarPageSelectorInternal.vue +13 -7
- package/src/components/internal/AppTopBarPillNavInternal.vue +12 -7
- package/src/components/internal/CalendarGridPanelInternal.vue +1 -1
- package/src/components/internal/FilePickerListInternal.vue +318 -0
- package/src/components/internal/FilePickerPreviewInternal.vue +54 -52
- package/src/components/internal/PlateEditorBindingInternal.vue +37 -0
- package/src/components/internal/ResourcePickerListInternal.vue +237 -0
- package/src/components/internal/SettingsPaneHeadInternal.vue +41 -0
- package/src/components/internal/WellEditPopupInternal.vue +219 -146
- package/src/components/internal/WorkspaceShellInternal.vue +0 -6
- package/src/components/internal/filePickerPresentation.ts +30 -0
- package/src/components/internal/generatedJobsApi.ts +12 -0
- package/src/composables/autoGroup/index.ts +3 -0
- package/src/composables/controlSchemaAdapters.ts +0 -4
- package/src/composables/controlSchemaFormFields.ts +0 -4
- package/src/composables/controlSchemaTypes.ts +4 -43
- package/src/composables/createFilePickerAdapter.ts +90 -22
- package/src/composables/filePicker/localFiles.ts +1 -0
- package/src/composables/filePicker/usePickerNavigation.ts +29 -2
- package/src/composables/index.ts +2 -71
- package/src/composables/pluginWorkspaceModel.ts +0 -3
- package/src/composables/useAutoGroup.ts +10 -0
- package/src/composables/useBioTemplateComponents.ts +15 -3
- package/src/composables/useBioTemplateControls.ts +5 -1
- package/src/composables/useBioTemplatePackWorkspace.ts +2 -0
- package/src/composables/useBioTemplatePresetWorkspace.ts +5 -1
- package/src/composables/useBioTemplateWorkspace.ts +5 -1
- package/src/composables/useChemicalFormula.ts +39 -13
- package/src/composables/useDropdownState.ts +6 -1
- package/src/composables/useExperimentSave.ts +5 -1
- package/src/composables/useFileBrowser.ts +3 -2
- package/src/composables/useFilePicker.ts +98 -13
- package/src/composables/useFocusTrap.ts +9 -6
- package/src/composables/useGeneratedAnalysis.ts +38 -0
- package/src/composables/useGroupAssignment.ts +5 -1
- package/src/composables/useJobsStatusTray.ts +5 -5
- package/src/composables/useMenuKeyboard.ts +5 -3
- package/src/composables/usePlatformFilePickerAdapter.ts +26 -4
- package/src/composables/usePluginClient.ts +1 -1
- package/src/composables/usePluginWorkspace.ts +0 -1
- package/src/composables/useRackEditor.ts +202 -12
- package/src/composables/useSequenceUtils.ts +20 -2
- package/src/composables/useTemplateCollection.ts +5 -1
- package/src/composables/workspaceRecipes.ts +1 -0
- package/src/index.ts +9 -3
- package/src/instrument.ts +6 -0
- package/src/lcms.ts +11 -0
- package/src/permissions.ts +2 -59
- package/src/styles/components/action-menu.css +9 -38
- package/src/styles/components/adduct-text.css +15 -3
- package/src/styles/components/alert-box.css +19 -70
- package/src/styles/components/app-avatar-menu.css +22 -57
- package/src/styles/components/app-container.css +4 -4
- package/src/styles/components/app-layout.css +18 -18
- package/src/styles/components/app-page-selector.css +50 -105
- package/src/styles/components/app-pill-nav.css +24 -42
- package/src/styles/components/app-sidebar.css +2 -2
- package/src/styles/components/app-top-bar.css +78 -55
- package/src/styles/components/artifact-selector-modal.css +1 -211
- package/src/styles/components/audit-trail.css +45 -38
- package/src/styles/components/avatar.css +1 -1
- package/src/styles/components/batch-progress-list.css +179 -95
- package/src/styles/components/breadcrumb.css +34 -15
- package/src/styles/components/calendar.css +2 -8
- package/src/styles/components/chart-container.css +81 -38
- package/src/styles/components/checkbox.css +8 -6
- package/src/styles/components/chemical-formula.css +8 -6
- package/src/styles/components/collapsible-card.css +6 -46
- package/src/styles/components/concentration-input.css +1 -10
- package/src/styles/components/dataframe.css +48 -67
- package/src/styles/components/date-picker.css +124 -62
- package/src/styles/components/datetime-picker.css +81 -47
- package/src/styles/components/divider.css +2 -4
- package/src/styles/components/dose-calculator.css +9 -135
- package/src/styles/components/empty-state.css +26 -35
- package/src/styles/components/experiment-code-badge.css +1 -1
- package/src/styles/components/experiment-popover.css +16 -83
- package/src/styles/components/experiment-selector-modal.css +9 -226
- package/src/styles/components/experiment-timeline.css +120 -50
- package/src/styles/components/file-picker.css +323 -299
- package/src/styles/components/file-uploader.css +4 -6
- package/src/styles/components/fit-panel.css +108 -22
- package/src/styles/components/form-field.css +6 -4
- package/src/styles/components/formula-input.css +121 -48
- package/src/styles/components/group-assigner.css +1 -3
- package/src/styles/components/icon-button.css +15 -37
- package/src/styles/components/input.css +91 -2
- package/src/styles/components/instrument-monitor.css +37 -447
- package/src/styles/components/jobs-status-tray.css +82 -61
- package/src/styles/components/loading-spinner.css +18 -0
- package/src/styles/components/mobile-support-gate.css +15 -17
- package/src/styles/components/modal.css +44 -33
- package/src/styles/components/molecule-input.css +31 -16
- package/src/styles/components/multi-select.css +33 -29
- package/src/styles/components/number-input.css +1 -1
- package/src/styles/components/plate-editor.css +497 -0
- package/src/styles/components/popover.css +162 -0
- package/src/styles/components/progress-bar.css +1 -70
- package/src/styles/components/protocol-step-editor.css +21 -333
- package/src/styles/components/radio-group.css +9 -18
- package/src/styles/components/reagent-editor.css +3 -7
- package/src/styles/components/reagent-list.css +63 -69
- package/src/styles/components/resource-card.css +4 -6
- package/src/styles/components/resource-picker-list.css +212 -0
- package/src/styles/components/sample-hierarchy-tree.css +83 -65
- package/src/styles/components/sample-legend.css +18 -7
- package/src/styles/components/sample-selector.css +41 -68
- package/src/styles/components/schedule-calendar.css +59 -54
- package/src/styles/components/scientific-number.css +72 -18
- package/src/styles/components/searchable-select.css +17 -26
- package/src/styles/components/secret-input.css +20 -23
- package/src/styles/components/section-card.css +3 -5
- package/src/styles/components/segmented-control.css +14 -1
- package/src/styles/components/select.css +19 -8
- package/src/styles/components/sequence-input.css +85 -37
- package/src/styles/components/sequence-progress-bar.css +18 -37
- package/src/styles/components/settings-modal.css +683 -34
- package/src/styles/components/skeleton.css +24 -23
- package/src/styles/components/slider.css +74 -8
- package/src/styles/components/smart-group.css +27 -39
- package/src/styles/components/status-indicator.css +1 -1
- package/src/styles/components/step-wizard.css +62 -99
- package/src/styles/components/tabs.css +2 -6
- package/src/styles/components/tags-input.css +64 -54
- package/src/styles/components/textarea.css +2 -2
- package/src/styles/components/time-picker.css +67 -38
- package/src/styles/components/time-range-input.css +16 -18
- package/src/styles/components/toast.css +1 -1
- package/src/styles/components/toggle.css +21 -31
- package/src/styles/components/tooltip.css +13 -15
- package/src/styles/components/unit-input.css +86 -36
- package/src/styles/components/well-edit-popup.css +111 -189
- package/src/styles/components/well-plate.css +7 -7
- package/src/styles/index.css +5 -7
- package/src/styles/variables.css +35 -7
- package/src/templates/adapters.ts +4 -0
- package/src/templates/assayMatrixAdapters.ts +8 -1
- package/src/templates/assayMatrixBuilder.ts +1 -0
- package/src/templates/builderPresetControls.ts +1 -0
- package/src/templates/calibrationCurveAdapters.ts +3 -0
- package/src/templates/calibrationCurveBuilder.ts +1 -0
- package/src/templates/catalog.ts +6 -2
- package/src/templates/componentBindingCatalog.ts +1 -1
- package/src/templates/componentBindings.ts +31 -5
- package/src/templates/componentDoseResponseProps.ts +0 -1
- package/src/templates/componentPlateHelpers.ts +22 -1
- package/src/templates/componentPlateMapProps.ts +7 -5
- package/src/templates/componentQpcrPlateProps.ts +0 -1
- package/src/templates/controlSchemas.ts +9 -0
- package/src/templates/defaultBioTemplateBuilder.ts +1 -0
- package/src/templates/doseResponseAdapters.ts +2 -0
- package/src/templates/doseResponseBuilder.ts +1 -0
- package/src/templates/elisaAssayCollectionBuilder.ts +1 -0
- package/src/templates/flowCytometryAssayCollectionBuilder.ts +1 -0
- package/src/templates/flowCytometryPanelBuilder.ts +1 -0
- package/src/templates/flowPanelAdapters.ts +3 -0
- package/src/templates/index.ts +4 -0
- package/src/templates/instrumentRunAdapters.ts +13 -2
- package/src/templates/instrumentRunBuilder.ts +1 -0
- package/src/templates/lcmsBatchCollectionBuilder.ts +1 -0
- package/src/templates/packs.ts +4 -0
- package/src/templates/plateMapAdapters.ts +2 -0
- package/src/templates/plateMapBuilder.ts +1 -0
- package/src/templates/presets.ts +6 -2
- package/src/templates/protocolAdapters.ts +4 -0
- package/src/templates/protocolStepsBuilder.ts +1 -0
- package/src/templates/qpcrAdapters.ts +4 -0
- package/src/templates/qpcrExpressionCollectionBuilder.ts +1 -0
- package/src/templates/qpcrPlateBuilder.ts +1 -0
- package/src/templates/reagentAdapters.ts +4 -0
- package/src/templates/reagentListBuilder.ts +1 -0
- package/src/templates/samplePrepAdapters.ts +3 -0
- package/src/templates/samplePrepBuilder.ts +1 -0
- package/src/templates/sampleSheetAdapters.ts +4 -0
- package/src/templates/sampleSheetBuilder.ts +1 -0
- package/src/templates/targetedMetabolomicsCollectionBuilder.ts +1 -0
- package/src/templates/templateEnvelopes.ts +8 -0
- package/src/templates/templatePackCollectionBuilder.ts +1 -0
- package/src/templates/templatePresetCollectionBuilder.ts +2 -0
- package/src/templates/templateValidators.ts +12 -0
- package/src/templates/timeCourseAdapters.ts +4 -0
- package/src/templates/timeCourseBuilder.ts +1 -0
- package/src/templates/wellPlateScreenCollectionBuilder.ts +1 -0
- package/src/templates/westernBlotAssayCollectionBuilder.ts +1 -0
- package/src/types/auth.ts +0 -37
- package/src/types/componentLabTypes.ts +16 -13
- package/src/types/componentWorkflowTypes.ts +29 -0
- package/src/types/components.ts +43 -20
- package/src/types/fileBrowserTypes.ts +15 -0
- package/src/types/filePicker.ts +19 -1
- package/src/types/generated-ui.ts +15 -0
- package/src/types/index.ts +12 -11
- package/src/types/instrument.ts +47 -15
- package/src/types/platform.ts +2 -0
- package/src/utils/color.ts +16 -1
- package/src/utils/formModelSync.ts +1 -1
- package/src/utils/plotlyTemplate.ts +39 -0
- package/src/utils/rack.ts +16 -0
- package/src/utils/sampleTypeMarker.ts +44 -0
- package/dist/ExperimentPopover-CJdNlCZb.js +0 -451
- package/dist/ExperimentPopover-CJdNlCZb.js.map +0 -1
- package/dist/ExperimentSelectorModal-DHE9k8TP.js +0 -507
- package/dist/ExperimentSelectorModal-DHE9k8TP.js.map +0 -1
- package/dist/SettingsModal-DELMkUFR.js +0 -492
- package/dist/SettingsModal-DELMkUFR.js.map +0 -1
- package/dist/Skeleton-jhF9wUkU.js +0 -485
- package/dist/Skeleton-jhF9wUkU.js.map +0 -1
- package/dist/__tests__/composables/usePluginConfig.test.d.ts +0 -15
- package/dist/chunk-BoAXSpZd.js +0 -33
- package/dist/components/AppPluginSwitcher.vue.d.ts +0 -40
- package/dist/components/ColorSlider.vue.d.ts +0 -34
- package/dist/components/DropdownButton.vue.d.ts +0 -49
- package/dist/components/FileBrowserModal.vue.d.ts +0 -99
- package/dist/components/InstrumentAlertLog.vue.d.ts +0 -22
- package/dist/components/InstrumentStatusCard.vue.d.ts +0 -13
- package/dist/components/LcmsSequenceTable.vue.d.ts +0 -54
- package/dist/components/PlateMapEditor.vue.d.ts +0 -50
- package/dist/components/RackEditor.vue.d.ts +0 -78
- package/dist/components/fileBrowserPresentation.d.ts +0 -10
- package/dist/components/internal/FileBrowserDialogInternal.vue.d.ts +0 -34
- package/dist/components/internal/FileBrowserListingInternal.vue.d.ts +0 -25
- package/dist/components/internal/FileBrowserToolbarInternal.vue.d.ts +0 -26
- package/dist/components/internal/PlateMapEditorToolbarInternal.vue.d.ts +0 -28
- package/dist/components-Bbg_gtzF.js.map +0 -1
- package/dist/composables/useAsync.d.ts +0 -132
- package/dist/composables/useAuth.d.ts +0 -47
- package/dist/composables/useCommandHistory.d.ts +0 -33
- package/dist/composables/useOptimisticMutation.d.ts +0 -32
- package/dist/composables/usePasskey.d.ts +0 -10
- package/dist/composables/usePluginConfig.d.ts +0 -27
- package/dist/composables/useResourceCrud.d.ts +0 -44
- package/dist/composables/useWellPainting.d.ts +0 -39
- package/dist/composables/useWellPlateAdapter.d.ts +0 -40
- package/dist/composables/useWellPlateEditor.d.ts +0 -33
- package/dist/composables/useWellPlateValidation.d.ts +0 -31
- package/dist/composables-BCbYb2lA.js +0 -2356
- package/dist/composables-BCbYb2lA.js.map +0 -1
- package/dist/errors-BLuqMee5.js.map +0 -1
- package/dist/experiment-CVDRAnqp.js +0 -90
- package/dist/experiment-CVDRAnqp.js.map +0 -1
- package/dist/experiment-utils-CV2Wza3z.js.map +0 -1
- package/dist/plotly.min-c2Sez60c.js +0 -180634
- package/dist/plotly.min-c2Sez60c.js.map +0 -1
- package/dist/templates-NuaNHohp.js +0 -5260
- package/dist/templates-NuaNHohp.js.map +0 -1
- package/dist/useControlSchema-vLiRPUmj.js +0 -7301
- package/dist/useControlSchema-vLiRPUmj.js.map +0 -1
- package/dist/useDropdownState-C7hRiVQf.js +0 -63
- package/dist/useDropdownState-C7hRiVQf.js.map +0 -1
- package/dist/useExperimentSelector-G_CAOFTX.js +0 -328
- package/dist/useExperimentSelector-G_CAOFTX.js.map +0 -1
- package/dist/useFormBuilder-D37ajgS8.js +0 -729
- package/dist/useFormBuilder-D37ajgS8.js.map +0 -1
- package/dist/validation-ChMyixAf.js.map +0 -1
- package/src/__tests__/components/AppPluginSwitcher.test.ts +0 -44
- package/src/__tests__/components/DropdownButton.test.ts +0 -628
- package/src/__tests__/components/FileBrowserModal.test.ts +0 -460
- package/src/__tests__/components/InstrumentAlertLog.test.ts +0 -59
- package/src/__tests__/components/LcmsSequenceTable.test.ts +0 -79
- package/src/__tests__/components/PlateMapEditorToolbarInternal.test.ts +0 -54
- package/src/__tests__/components/RackEditor.test.ts +0 -169
- package/src/__tests__/composables/useAuth.test.ts +0 -233
- package/src/__tests__/composables/useCommandHistory.test.ts +0 -43
- package/src/__tests__/composables/useOptimisticMutation.test.ts +0 -40
- package/src/__tests__/composables/usePluginConfig.test.ts +0 -497
- package/src/__tests__/composables/useResourceCrud.test.ts +0 -56
- package/src/__tests__/composables/useWellPainting.test.ts +0 -52
- package/src/__tests__/composables/useWellPlateAdapter.test.ts +0 -50
- package/src/__tests__/composables/useWellPlateValidation.test.ts +0 -42
- package/src/components/AppPluginSwitcher.story.vue +0 -87
- package/src/components/AppPluginSwitcher.vue +0 -134
- package/src/components/ColorSlider.story.vue +0 -120
- package/src/components/ColorSlider.vue +0 -160
- package/src/components/DropdownButton.story.vue +0 -102
- package/src/components/DropdownButton.vue +0 -181
- package/src/components/FileBrowserModal.story.vue +0 -203
- package/src/components/FileBrowserModal.vue +0 -384
- package/src/components/InstrumentAlertLog.vue +0 -187
- package/src/components/InstrumentStatusCard.vue +0 -184
- package/src/components/LcmsSequenceTable.vue +0 -222
- package/src/components/PlateMapEditor.story.vue +0 -92
- package/src/components/PlateMapEditor.vue +0 -423
- package/src/components/RackEditor.story.vue +0 -100
- package/src/components/RackEditor.vue +0 -429
- package/src/components/fileBrowserPresentation.ts +0 -39
- package/src/components/internal/FileBrowserDialogInternal.vue +0 -75
- package/src/components/internal/FileBrowserListingInternal.vue +0 -197
- package/src/components/internal/FileBrowserToolbarInternal.vue +0 -136
- package/src/components/internal/FilePickerTreeInternal.vue +0 -238
- package/src/components/internal/PlateMapEditorToolbarInternal.vue +0 -128
- package/src/composables/useAsync.ts +0 -327
- package/src/composables/useAuth.ts +0 -458
- package/src/composables/useCommandHistory.ts +0 -117
- package/src/composables/useOptimisticMutation.ts +0 -97
- package/src/composables/usePasskey.ts +0 -216
- package/src/composables/usePluginConfig.ts +0 -252
- package/src/composables/useResourceCrud.ts +0 -235
- package/src/composables/useWellPainting.ts +0 -167
- package/src/composables/useWellPlateAdapter.ts +0 -151
- package/src/composables/useWellPlateEditor.ts +0 -415
- package/src/composables/useWellPlateValidation.ts +0 -89
- package/src/plotly-dist.d.ts +0 -3
- package/src/styles/components/app-plugin-switcher.css +0 -196
- package/src/styles/components/color-slider.css +0 -110
- package/src/styles/components/dropdown-button.css +0 -280
- package/src/styles/components/file-browser-modal.css +0 -489
- package/src/styles/components/lcms-sequence-table.css +0 -204
- package/src/styles/components/plate-map-editor.css +0 -464
- package/src/styles/components/rack-editor.css +0 -287
- /package/dist/__tests__/components/{AppPluginSwitcher.test.d.ts → AlertBox.test.d.ts} +0 -0
- /package/dist/__tests__/components/{DropdownButton.test.d.ts → AuditTrail.test.d.ts} +0 -0
- /package/dist/__tests__/components/{FileBrowserModal.test.d.ts → BaseCheckbox.test.d.ts} +0 -0
- /package/dist/__tests__/components/{InstrumentAlertLog.test.d.ts → BaseSlider.test.d.ts} +0 -0
- /package/dist/__tests__/components/{LcmsSequenceTable.test.d.ts → DoseCalculator.test.d.ts} +0 -0
- /package/dist/__tests__/components/{PlateMapEditorToolbarInternal.test.d.ts → FileUploader.test.d.ts} +0 -0
- /package/dist/__tests__/components/{RackEditor.test.d.ts → FitPanel.test.d.ts} +0 -0
- /package/dist/__tests__/{composables/useAuth.test.d.ts → components/FormulaInput.test.d.ts} +0 -0
- /package/dist/__tests__/{composables/useCommandHistory.test.d.ts → components/InstrumentStateBadge.test.d.ts} +0 -0
- /package/dist/__tests__/{composables/useOptimisticMutation.test.d.ts → components/MoleculeInput.test.d.ts} +0 -0
- /package/dist/__tests__/{composables/useResourceCrud.test.d.ts → components/PlateEditor.test.d.ts} +0 -0
- /package/dist/__tests__/{composables/useWellPainting.test.d.ts → components/PlateEditorBindingInternal.test.d.ts} +0 -0
- /package/dist/__tests__/{composables/useWellPlateAdapter.test.d.ts → components/ResourcePickerListInternal.test.d.ts} +0 -0
- /package/dist/__tests__/{composables/useWellPlateValidation.test.d.ts → components/SampleLegend.test.d.ts} +0 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs'
|
|
2
|
+
import { dirname, join, resolve } from 'node:path'
|
|
3
|
+
import { fileURLToPath } from 'node:url'
|
|
4
|
+
import { describe, expect, it } from 'vitest'
|
|
5
|
+
|
|
6
|
+
// SDK control refresh, phase 1 base controls (rounds 1 and 10). One rule per
|
|
7
|
+
// test; a failure lists the offending `file:line`.
|
|
8
|
+
|
|
9
|
+
const here = dirname(fileURLToPath(import.meta.url))
|
|
10
|
+
const componentsDir = resolve(here, '../../styles/components')
|
|
11
|
+
|
|
12
|
+
/** Lines of a component sheet with block comments blanked (line numbers kept). */
|
|
13
|
+
function lines(file: string): string[] {
|
|
14
|
+
const text = readFileSync(join(componentsDir, file), 'utf-8')
|
|
15
|
+
return text.replace(/\/\*[\s\S]*?\*\//g, (c) => c.replace(/[^\n]/g, ' ')).split('\n')
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function offenders(files: string[], test: (line: string) => boolean): string[] {
|
|
19
|
+
return files.flatMap((file) =>
|
|
20
|
+
lines(file).flatMap((line, i) => (test(line) ? [`${file}:${i + 1}: ${line.trim()}`] : [])),
|
|
21
|
+
)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const css = (file: string) => lines(file).join('\n')
|
|
25
|
+
|
|
26
|
+
describe('SDK control refresh base-control rules', () => {
|
|
27
|
+
it('should find no transparent-border focus when scanning select.css (1a)', () => {
|
|
28
|
+
expect(offenders(['select.css'], (l) => /border-color:\s*transparent/.test(l))).toEqual([])
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
it('should find no soft or plain focus ring when scanning pressable controls (1a)', () => {
|
|
32
|
+
const pressables = ['checkbox.css', 'radio-group.css', 'toggle.css', 'icon-button.css', 'multi-select.css']
|
|
33
|
+
expect(offenders(pressables, (l) => /var\(--focus-ring(-soft)?\)/.test(l))).toEqual([])
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
it.each(['input.css', 'select.css', 'textarea.css'])(
|
|
37
|
+
'should use the shared field hover border when scanning %s (1e)',
|
|
38
|
+
(file) => {
|
|
39
|
+
expect(css(file)).toContain('border-color: var(--_field-border-hover)')
|
|
40
|
+
},
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
it('should disable select without opacity when scanning select.css (1e)', () => {
|
|
44
|
+
expect(css('select.css')).not.toContain('--mint-disabled-opacity')
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
it.each(['checkbox.css', 'radio-group.css'])(
|
|
48
|
+
'should draw the unchecked control with the strong border when scanning %s (1b)',
|
|
49
|
+
(file) => {
|
|
50
|
+
expect(css(file)).toContain('border: 1.5px solid var(--_control-border-strong)')
|
|
51
|
+
},
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
it('should paint the off track with the strong border color when scanning toggle.css (1b)', () => {
|
|
55
|
+
expect(css('toggle.css')).toMatch(/\.mint-toggle__track--off \{\s*background-color: var\(--_control-border-strong\);/)
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
it('should move the toggle knob with transform only when scanning toggle.css (1b)', () => {
|
|
59
|
+
expect(offenders(['toggle.css'], (l) => /__knob--on-|transition:\s*left/.test(l))).toEqual([])
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
it('should find no radio input-wrapper size modifiers when scanning radio-group.css (1b)', () => {
|
|
63
|
+
expect(offenders(['radio-group.css'], (l) => /__input-wrapper--|margin-left:\s*-/.test(l))).toEqual([])
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
it('should find no translateY lift when scanning icon-button.css (1d)', () => {
|
|
67
|
+
expect(offenders(['icon-button.css'], (l) => /translateY/.test(l))).toEqual([])
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
it('should ring the slider thumb when the native input has keyboard focus (1f)', () => {
|
|
71
|
+
expect(css('slider.css')).toMatch(
|
|
72
|
+
/\.mint-slider__input:focus-visible ~ \.mint-slider__thumb \{[^}]*box-shadow: var\(--focus-ring-offset\);/,
|
|
73
|
+
)
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
it('should find no semantic title color when scanning alert-box.css (1h)', () => {
|
|
77
|
+
expect(offenders(['alert-box.css'], (l) => /\.mint-alert--\w+ \.mint-alert__title/.test(l))).toEqual([])
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
it('should find no pill radius on the chip when scanning multi-select.css (1i)', () => {
|
|
81
|
+
expect(offenders(['multi-select.css'], (l) => /9999px|999px/.test(l))).toEqual([])
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
it('should find no literal radius or hand-written shadow when scanning modal.css (1i drift)', () => {
|
|
85
|
+
expect(offenders(['modal.css'], (l) => /0\.875rem 0|radius:\s*0\.875rem|rgba\(15, 23, 42, 0\.(4|2|08)\)/.test(l))).toEqual([])
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
it('should find no Fira font literal when scanning drift files (1i drift, 10c)', () => {
|
|
89
|
+
const files = ['modal.css', 'tooltip.css', 'slider.css', 'experiment-code-badge.css']
|
|
90
|
+
expect(offenders(files, (l) => /'Fira/.test(l))).toEqual([])
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
it('should find no literal var() fallback when scanning drift files (1i drift, 10c)', () => {
|
|
94
|
+
const files = ['checkbox.css', 'toggle.css', 'slider.css', 'app-layout.css', 'app-container.css', 'mobile-support-gate.css']
|
|
95
|
+
expect(offenders(files, (l) => /var\(--[\w-]+,\s*[^v\s]/.test(l))).toEqual([])
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
it('should keep the collapsible-card header actions still on hover (10a)', () => {
|
|
99
|
+
expect(offenders(['collapsible-card.css'], (l) => /translateY/.test(l))).toEqual([])
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
it('should keep the resource-card hover shadow at --shadow-sm (10a)', () => {
|
|
103
|
+
expect(css('resource-card.css')).not.toMatch(/\.mint-resource-card:hover \{[^}]*box-shadow/)
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
it('should replace the spinner rotation under reduced motion (10c)', () => {
|
|
107
|
+
expect(css('loading-spinner.css')).toMatch(
|
|
108
|
+
/@media \(prefers-reduced-motion: reduce\) \{\s*\.mint-spinner__svg \{\s*animation: mint-spinner-pulse [^;]*!important;/,
|
|
109
|
+
)
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
it('should size the card segmented control border-box so full-width fits its container (3b)', () => {
|
|
113
|
+
expect(css('segmented-control.css')).toMatch(/\.mint-segmented-control--card \{[^}]*box-sizing: border-box;/)
|
|
114
|
+
})
|
|
115
|
+
})
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { readdirSync, readFileSync, statSync } from 'node:fs'
|
|
2
|
+
import { dirname, join, relative, resolve } from 'node:path'
|
|
3
|
+
import { fileURLToPath } from 'node:url'
|
|
4
|
+
import { describe, expect, it } from 'vitest'
|
|
5
|
+
|
|
6
|
+
// SDK control refresh (decisions/2026-09-25-sdk-control-refresh) style rules.
|
|
7
|
+
// Each failure message lists every offending `file:line`, so it doubles as the
|
|
8
|
+
// migration work-list.
|
|
9
|
+
|
|
10
|
+
const here = dirname(fileURLToPath(import.meta.url))
|
|
11
|
+
const pkgRoot = resolve(here, '../../..')
|
|
12
|
+
const srcRoot = join(pkgRoot, 'src')
|
|
13
|
+
const stylesDir = join(srcRoot, 'styles')
|
|
14
|
+
const componentsDir = join(stylesDir, 'components')
|
|
15
|
+
|
|
16
|
+
const IGNORED_DIRS = new Set(['__tests__', 'generated-ui', 'node_modules'])
|
|
17
|
+
|
|
18
|
+
function walk(dir: string, exts: string[], out: string[] = []): string[] {
|
|
19
|
+
for (const entry of readdirSync(dir)) {
|
|
20
|
+
const full = join(dir, entry)
|
|
21
|
+
if (statSync(full).isDirectory()) {
|
|
22
|
+
if (!IGNORED_DIRS.has(entry)) walk(full, exts, out)
|
|
23
|
+
} else if (exts.some((ext) => entry.endsWith(ext))) {
|
|
24
|
+
out.push(full)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return out
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Block comments blanked out, newlines kept so line numbers stay true. */
|
|
31
|
+
function stripComments(text: string): string {
|
|
32
|
+
return text.replace(/\/\*[\s\S]*?\*\//g, (c) => c.replace(/[^\n]/g, ' '))
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function offenders(files: string[], test: (line: string) => boolean): string[] {
|
|
36
|
+
const hits: string[] = []
|
|
37
|
+
for (const file of files) {
|
|
38
|
+
const lines = stripComments(readFileSync(file, 'utf-8')).split('\n')
|
|
39
|
+
lines.forEach((line, i) => {
|
|
40
|
+
if (test(line)) hits.push(`${relative(pkgRoot, file)}:${i + 1}: ${line.trim()}`)
|
|
41
|
+
})
|
|
42
|
+
}
|
|
43
|
+
return hits
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function expectNone(hits: string[]): void {
|
|
47
|
+
expect(hits, `${hits.length} offenders\n${hits.join('\n')}`).toEqual([])
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const componentCss = walk(componentsDir, ['.css'])
|
|
51
|
+
const allStyleCss = walk(stylesDir, ['.css'])
|
|
52
|
+
const allSrcCssAndVue = walk(srcRoot, ['.css', '.vue'])
|
|
53
|
+
const component = (name: string) => join(componentsDir, name)
|
|
54
|
+
|
|
55
|
+
// 8d: UI text >= 11px (0.6875rem). In-graphic well labels are exempt.
|
|
56
|
+
const MIN_FONT_PX = 11
|
|
57
|
+
const FONT_SIZE_WHITELIST = new Set(['well-plate.css'])
|
|
58
|
+
|
|
59
|
+
function hasTooSmallFont(line: string): boolean {
|
|
60
|
+
// Several declarations can share a line (`font: inherit; font-size: …`).
|
|
61
|
+
for (const decl of line.matchAll(/\bfont(?:-size)?\s*:\s*([^;]*)/g)) {
|
|
62
|
+
// The first length in `font-size:` or the `font:` shorthand is the size.
|
|
63
|
+
const size = decl[1].match(/(\d*\.?\d+)(px|rem)\b/)
|
|
64
|
+
if (!size) continue
|
|
65
|
+
const px = size[2] === 'rem' ? Number(size[1]) * 16 : Number(size[1])
|
|
66
|
+
if (px < MIN_FONT_PX) return true
|
|
67
|
+
}
|
|
68
|
+
return false
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
describe('SDK control refresh style rules', () => {
|
|
72
|
+
it('should find no uppercase text-transform when scanning styles (2a)', () => {
|
|
73
|
+
expectNone(offenders(allStyleCss, (l) => /text-transform\s*:\s*uppercase/i.test(l)))
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
it('should find no font size below 11px when scanning component styles (8d)', () => {
|
|
77
|
+
const files = componentCss.filter((f) => !FONT_SIZE_WHITELIST.has(relative(componentsDir, f)))
|
|
78
|
+
expectNone(offenders(files, hasTooSmallFont))
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
it('should find no var(--token, #hex) fallback when scanning styles (4f)', () => {
|
|
82
|
+
expectNone(offenders(allStyleCss, (l) => /var\(--[\w-]+,\s*#/.test(l)))
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
it('should find no legacy --mint-border/bg-/text- reference when scanning styles (4f)', () => {
|
|
86
|
+
// Usages only: variables.css still declares the aliases, and
|
|
87
|
+
// --mint-border-focus is a real token, not part of the legacy chain.
|
|
88
|
+
expectNone(offenders(allStyleCss, (l) => /var\(--mint-(?:border(?![\w-])|bg-|text-)/.test(l)))
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
it('should find no pre-rebrand blue literal when scanning source CSS and Vue files (6d)', () => {
|
|
92
|
+
// The --mint-info-* token declarations are the genuine info blue (the
|
|
93
|
+
// replacement target for info intent), not a legacy use.
|
|
94
|
+
expectNone(
|
|
95
|
+
offenders(
|
|
96
|
+
allSrcCssAndVue,
|
|
97
|
+
(l) => /rgba\(\s*59\s*,\s*130\s*,\s*246/.test(l) && !/^\s*--mint-info-[\w-]+\s*:/.test(l),
|
|
98
|
+
),
|
|
99
|
+
)
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
it('should find no linear-gradient when scanning flat-surface components (1d, 2f, 2g, 3e)', () => {
|
|
103
|
+
const files = ['icon-button.css', 'empty-state.css', 'jobs-status-tray.css', 'file-picker.css', 'skeleton.css'].map(component)
|
|
104
|
+
expectNone(offenders(files, (l) => /linear-gradient/.test(l)))
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
it('should find no hex color literal when scanning token-only graphics (1g, 2b, 3b, 7a)', () => {
|
|
108
|
+
const files = ['well-plate.css', 'tooltip.css', 'well-edit-popup.css', 'plate-editor.css'].map(component)
|
|
109
|
+
expectNone(offenders(files, (l) => /#[0-9a-fA-F]{3,8}\b/.test(l)))
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
it('should ring the focused editor root when scanning plate-editor.css (7a)', () => {
|
|
113
|
+
const css = stripComments(readFileSync(component('plate-editor.css'), 'utf-8'))
|
|
114
|
+
expect(/\.mint-plate-editor:focus-visible\s*\{[^}]*box-shadow:\s*var\(--focus-ring\)/.test(css)).toBe(true)
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
it('should fill progress with the primary color only when scanning progress-bar.css (6b)', () => {
|
|
118
|
+
// --mint-info is reserved for the "running" status dot.
|
|
119
|
+
expectNone(offenders([component('progress-bar.css')], (l) => /--mint-info/.test(l)))
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
it('should keep sequence progress text off --mint-info when scanning sequence-progress-bar.css (6b)', () => {
|
|
123
|
+
expectNone(offenders([component('sequence-progress-bar.css')], (l) => /--mint-info/.test(l)))
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
it('should fill primary and info progress with --color-primary when scanning progress-bar.css (6b)', () => {
|
|
127
|
+
// The rail bar, for primary and info.
|
|
128
|
+
const fills = stripComments(readFileSync(component('progress-bar.css'), 'utf-8'))
|
|
129
|
+
.split('\n')
|
|
130
|
+
.filter((l) => /\.mint-progress__[\w.-]*--(primary|info)\s*\{/.test(l))
|
|
131
|
+
.map((l) => /background-color:\s*([^;]+);/.exec(l)?.[1])
|
|
132
|
+
expect(fills).toEqual(Array(2).fill('var(--color-primary)'))
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
it('should compose SDK fields instead of private field styles when scanning protocol-step-editor.css and dose-calculator.css (6c)', () => {
|
|
136
|
+
const files = [component('protocol-step-editor.css'), component('dose-calculator.css')]
|
|
137
|
+
expectNone(offenders(files, (l) => /__(input|select|textarea|unit-suffix|template-|mode-badge|btn|apply-btn)/.test(l)))
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
it('should wrap FormField rows so a row error sits on its own line (6c)', () => {
|
|
141
|
+
expect(readFileSync(component('form-field.css'), 'utf-8')).toMatch(/\.mint-form-field--row\s*\{[^}]*flex-wrap:\s*wrap;/)
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
it('should set FormField row labels in 13px text-secondary-strong (3b, 6c)', () => {
|
|
145
|
+
expect(readFileSync(component('form-field.css'), 'utf-8')).toMatch(/\.mint-form-field--row \.mint-form-field__label\s*\{[^}]*font-size:\s*0\.8125rem;[^}]*color:\s*var\(--text-secondary-strong\);/)
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
it('should draw no checkbox glyph as a data URI when scanning sample-selector.css (7c)', () => {
|
|
149
|
+
expectNone(offenders([component('sample-selector.css')], (l) => /data:image/.test(l)))
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
it('should generate no label text in CSS when scanning scientific inputs (4b)', () => {
|
|
153
|
+
// "MW" and "≈" live in templates so they can be translated, selected and read aloud.
|
|
154
|
+
const files = ['formula-input.css', 'concentration-input.css', 'unit-input.css'].map(component)
|
|
155
|
+
expectNone(offenders(files, (l) => /(^|[^-\w])content\s*:/.test(l)))
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
it('should find no italic conversion hint when scanning scientific inputs (4b)', () => {
|
|
159
|
+
const files = ['concentration-input.css', 'unit-input.css'].map(component)
|
|
160
|
+
expectNone(offenders(files, (l) => /font-style\s*:\s*italic/.test(l)))
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
it('should set the unit at the number size when scanning scientific-number.css (4b)', () => {
|
|
164
|
+
const css = stripComments(readFileSync(component('scientific-number.css'), 'utf-8'))
|
|
165
|
+
const rule = /\.mint-sci-number__unit\s*\{([^}]*)\}/.exec(css)?.[1] ?? ''
|
|
166
|
+
expect(rule).not.toMatch(/font-size/)
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
it('should give numeric DataFrame cells tabular figures when scanning dataframe.css (2a)', () => {
|
|
170
|
+
const css = stripComments(readFileSync(component('dataframe.css'), 'utf-8'))
|
|
171
|
+
const rule = /\.mint-dataframe__td--number\s*\{([^}]*)\}/.exec(css)?.[1] ?? ''
|
|
172
|
+
expect(rule).toMatch(/font-variant-numeric:\s*tabular-nums/)
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
it('should center the select-all checkbox over the row checkboxes when .mint-dataframe__th forces left (2a)', () => {
|
|
176
|
+
const css = stripComments(readFileSync(component('dataframe.css'), 'utf-8'))
|
|
177
|
+
const rule = /\.mint-dataframe__th--checkbox\s*\{([^}]*)\}/.exec(css)?.[1] ?? ''
|
|
178
|
+
expect(rule).toMatch(/text-align:\s*center\s*!important/)
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
it('should wrap a row FormField so its hint drops below the control when scanning form-field.css (3b)', () => {
|
|
182
|
+
const css = stripComments(readFileSync(component('form-field.css'), 'utf-8'))
|
|
183
|
+
const rule = /\.mint-form-field--row\s*\{([^}]*)\}/.exec(css)?.[1] ?? ''
|
|
184
|
+
expect(rule).toMatch(/flex-wrap:\s*wrap/)
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
it('should pad resource picker rows to the roomier two-column layout when scanning resource-picker-list.css', () => {
|
|
188
|
+
const css = stripComments(readFileSync(component('resource-picker-list.css'), 'utf-8'))
|
|
189
|
+
const rule = /\.mint-resource-picker__row\s*\{([^}]*)\}/.exec(css)?.[1] ?? ''
|
|
190
|
+
expect(rule).toMatch(/padding:\s*10px 12px/)
|
|
191
|
+
})
|
|
192
|
+
|
|
193
|
+
// Group bars and the list frame were inset by the modal body padding; the list now runs edge to edge.
|
|
194
|
+
it('should drop the modal body padding around the resource picker when scanning resource-picker-list.css', () => {
|
|
195
|
+
const css = stripComments(readFileSync(component('resource-picker-list.css'), 'utf-8'))
|
|
196
|
+
const rule = /\.mint-modal__body:has\(> \.mint-resource-picker\)\s*\{([^}]*)\}/.exec(css)?.[1] ?? ''
|
|
197
|
+
expect(rule).toMatch(/padding:\s*0/)
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
it('should pad resource picker group bars to the modal gutter when scanning resource-picker-list.css', () => {
|
|
201
|
+
const css = stripComments(readFileSync(component('resource-picker-list.css'), 'utf-8'))
|
|
202
|
+
const rule = /\.mint-resource-picker__group\s*\{([^}]*)\}/.exec(css)?.[1] ?? ''
|
|
203
|
+
expect(rule).toMatch(/padding:\s*0 1\.25rem/)
|
|
204
|
+
})
|
|
205
|
+
|
|
206
|
+
// The list sat in a bordered card inside the modal card.
|
|
207
|
+
it('should draw no frame around the resource picker list when scanning resource-picker-list.css', () => {
|
|
208
|
+
const css = stripComments(readFileSync(component('resource-picker-list.css'), 'utf-8'))
|
|
209
|
+
const rule = /\.mint-resource-picker__frame\s*\{([^}]*)\}/.exec(css)?.[1] ?? ''
|
|
210
|
+
expect(rule).not.toMatch(/(^|;)\s*border:/)
|
|
211
|
+
})
|
|
212
|
+
|
|
213
|
+
it('should paint the clear-selection link with primary ink when scanning experiment-selector-modal.css (8b)', () => {
|
|
214
|
+
const css = stripComments(readFileSync(component('experiment-selector-modal.css'), 'utf-8'))
|
|
215
|
+
const rule = /\.mint-experiment-selector__clear-btn\s*\{([^}]*)\}/.exec(css)?.[1] ?? ''
|
|
216
|
+
expect(rule).toMatch(/color:\s*var\(--_ink-primary\)/)
|
|
217
|
+
})
|
|
218
|
+
})
|
|
@@ -14,11 +14,7 @@ const variablesCss = readFileSync(join(stylesDir, 'variables.css'), 'utf-8')
|
|
|
14
14
|
* component-local knobs declared in the same stylesheet that consumes them.
|
|
15
15
|
* Anything else must be a canonical token from variables.css.
|
|
16
16
|
*/
|
|
17
|
-
const RUNTIME_PROPERTY_ALLOWLIST = new Set<string>([
|
|
18
|
-
// Names assembled in JS (`--grp-${i}`) — the literal prefix is what the
|
|
19
|
-
// scanner sees in a template string.
|
|
20
|
-
'--grp-',
|
|
21
|
-
])
|
|
17
|
+
const RUNTIME_PROPERTY_ALLOWLIST = new Set<string>([])
|
|
22
18
|
|
|
23
19
|
const SOURCE_EXTENSIONS = ['.vue', '.css', '.ts']
|
|
24
20
|
const IGNORED_DIRS = new Set(['__tests__', 'generated-ui', 'node_modules'])
|
|
@@ -95,6 +91,12 @@ describe('CSS custom properties', () => {
|
|
|
95
91
|
expect(report).toEqual([])
|
|
96
92
|
})
|
|
97
93
|
|
|
94
|
+
// 9a: PlotlyChart reads it through getComputedStyle('--font-sans'), which the
|
|
95
|
+
// scan above counts as a declaration, so it slipped through as undefined.
|
|
96
|
+
it('should declare --font-sans as Fira Sans when charts read the sans font token (9a)', () => {
|
|
97
|
+
expect(variablesCss).toMatch(/--font-sans:\s*'Fira Sans'/)
|
|
98
|
+
})
|
|
99
|
+
|
|
98
100
|
it('does not use the platform-only --color-bg-*/--color-text-*/--color-border aliases', () => {
|
|
99
101
|
const platformOnly = /^--color-(bg|text)-|^--color-border$/
|
|
100
102
|
const offenders = [
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { readdirSync, readFileSync } from 'node:fs'
|
|
2
|
+
import { dirname, join, resolve } from 'node:path'
|
|
3
|
+
import { fileURLToPath } from 'node:url'
|
|
4
|
+
import { describe, expect, it } from 'vitest'
|
|
5
|
+
|
|
6
|
+
// SDK control refresh phase 1, fix round 1: dark-mode ink, hairlines and sizing.
|
|
7
|
+
const stylesDir = resolve(dirname(fileURLToPath(import.meta.url)), '../../styles')
|
|
8
|
+
const componentsDir = join(stylesDir, 'components')
|
|
9
|
+
const css = (name: string) => readFileSync(join(componentsDir, name), 'utf-8')
|
|
10
|
+
|
|
11
|
+
describe('dark-mode ink and hairline rules', () => {
|
|
12
|
+
it('should find no light-only ink text color when scanning component styles', () => {
|
|
13
|
+
const offenders = readdirSync(componentsDir)
|
|
14
|
+
.filter(f => f.endsWith('.css'))
|
|
15
|
+
.flatMap(f => css(f).split('\n').map((l, i) => ({ l, at: `${f}:${i + 1}` })))
|
|
16
|
+
.filter(({ l }) => /(^|[\s;{])color:\s*var\(--(color-primary-hover|mint-error-hover)\)/.test(l))
|
|
17
|
+
.map(({ at }) => at)
|
|
18
|
+
expect(offenders).toEqual([])
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
it('should lift the ink aliases toward --text-primary when the theme is dark', () => {
|
|
22
|
+
const dark = readFileSync(join(stylesDir, 'variables.css'), 'utf-8').match(/html\.dark \{[^}]*\}/)?.[0] ?? ''
|
|
23
|
+
expect(dark).toMatch(/--_ink-primary: color-mix\(in srgb, var\(--color-primary\) 50%, var\(--text-primary\)\);[\s\S]*--_ink-error: color-mix\(in srgb, var\(--mint-error\) 50%, var\(--text-primary\)\);/)
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it.each([
|
|
27
|
+
['batch-progress-list.css', 'mint-batch-progress'],
|
|
28
|
+
['dataframe.css', 'mint-dataframe'],
|
|
29
|
+
['fit-panel.css', 'mint-fit-panel'],
|
|
30
|
+
['jobs-status-tray.css', 'mint-jobs-tray'],
|
|
31
|
+
['molecule-input.css', 'mint-molecule-input'],
|
|
32
|
+
['reagent-list.css', 'mint-reagent-list'],
|
|
33
|
+
['sample-hierarchy-tree.css', 'mint-sample-tree'],
|
|
34
|
+
['sequence-input.css', 'mint-sequence-input'],
|
|
35
|
+
['step-wizard.css', 'mint-wizard'],
|
|
36
|
+
])('should draw %s hairlines with --border-color when the theme is dark', (file, root) => {
|
|
37
|
+
expect(css(file)).toContain(`:where(html.dark) .${root} {\n --border-light: var(--border-color);\n}`)
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
it('should stripe DataFrame rows with a tint that differs from the --bg-card surface', () => {
|
|
41
|
+
expect(css('dataframe.css')).not.toMatch(/\.mint-dataframe__row--striped[^{]*\{[^}]*--bg-secondary/)
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
it('should size timeline icons border-box so the dashed skipped ring keeps the nominal size', () => {
|
|
45
|
+
expect(css('experiment-timeline.css')).toMatch(/\.mint-timeline__icon \{[^}]*box-sizing: border-box;/)
|
|
46
|
+
})
|
|
47
|
+
})
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs'
|
|
2
|
+
import { dirname, join, resolve } from 'node:path'
|
|
3
|
+
import { fileURLToPath } from 'node:url'
|
|
4
|
+
import { describe, expect, it } from 'vitest'
|
|
5
|
+
|
|
6
|
+
// SDK control refresh phase 1 (2c, 5a, 5d): CSS-only cards, locked by value.
|
|
7
|
+
const componentsDir = resolve(dirname(fileURLToPath(import.meta.url)), '../../styles/components')
|
|
8
|
+
const css = (name: string) => readFileSync(join(componentsDir, name), 'utf-8')
|
|
9
|
+
|
|
10
|
+
describe('menus and app shell styles', () => {
|
|
11
|
+
it('should fill completed StepWizard connectors with the primary hue (2c)', () => {
|
|
12
|
+
expect(css('step-wizard.css')).toMatch(/\.mint-wizard__step-connector--completed\s*\{[^}]*background-color:\s*var\(--color-primary\);/)
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
it('should draw the StepWizard connector 1px tall (2c)', () => {
|
|
16
|
+
expect(css('step-wizard.css')).toMatch(/\.mint-wizard__step-connector\s*\{[^}]*height:\s*1px;/)
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
// Phase 3: the nav renders BaseButton (Finish = primary, see StepWizard.test.ts), so no private button rules remain.
|
|
20
|
+
it('should leave StepWizard nav buttons to BaseButton (2c)', () => {
|
|
21
|
+
expect(css('step-wizard.css')).not.toMatch(/\.mint-wizard__nav-btn/)
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
it('should pad the top bar to the 1.2 height (62px)', () => {
|
|
25
|
+
expect(css('app-top-bar.css')).toMatch(/\.mint-topbar\s*\{[^}]*padding:\s*0\.75rem 1rem;/)
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
// 28px items + 3px track padding + 1px border on each side = the 36px top-bar control height.
|
|
29
|
+
it('should size pill nav items so the track matches the 36px top-bar controls', () => {
|
|
30
|
+
expect(css('app-pill-nav.css')).toMatch(/\.mint-pill-nav__item\s*\{[^}]*height:\s*1\.75rem;/)
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
it('should size the page selector trigger to the 36px identity tile', () => {
|
|
34
|
+
expect(css('app-page-selector.css')).toMatch(/\.mint-page-selector__trigger\s*\{[^}]*height:\s*2\.25rem;/)
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
// Shrinking the tile beside the identity also shrank structured icons inside their solid chip, drawing a ring.
|
|
38
|
+
it('should keep the plugin tile beside the static plugin identity (5a)', () => {
|
|
39
|
+
expect(css('app-top-bar.css')).not.toMatch(/:has\(\+ \.mint-topbar__plugin-identity\)/)
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
// A slotted 36px logo shrank to 32px wide but kept its height, drawing a 32x36 tile.
|
|
43
|
+
it('should fit slotted identity content inside the identity tile (5a)', () => {
|
|
44
|
+
expect(css('app-top-bar.css')).toMatch(/\.mint-topbar__identity > \*\s*\{[^}]*max-width:\s*100%;[^}]*max-height:\s*100%;/)
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
// 15px x 1.15 + 12px x 1.2 = 31.7px, so the title group fits the 32px control row.
|
|
48
|
+
it('should fit the top-bar title and subtitle inside the control row (5a)', () => {
|
|
49
|
+
expect(css('app-top-bar.css')).toMatch(/\.mint-topbar-title\s*\{[^}]*line-height:\s*1\.15;/)
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
it('should size the top-bar experiment trigger to the 32px control height (5a)', () => {
|
|
53
|
+
expect(css('experiment-popover.css')).toMatch(/\.mint-experiment-popover__trigger\s*\{[^}]*height:\s*var\(--form-height-sm\);/)
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
it('should size the top-bar experiment save trigger to the 32px control height (5a)', () => {
|
|
57
|
+
expect(css('experiment-popover.css')).toMatch(/\.mint-experiment-popover__save-trigger\s*\{[^}]*height:\s*var\(--form-height-sm\);/)
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
it('should give settings number rows a 120px control (5d)', () => {
|
|
61
|
+
expect(css('settings-modal.css')).toMatch(/> \.mint-number-input\s*\{\s*width:\s*7\.5rem;/)
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
it('should give settings select rows a 220px control (5d)', () => {
|
|
65
|
+
expect(css('settings-modal.css')).toMatch(/> \.mint-select\s*\{\s*width:\s*13\.75rem;/)
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
it('should keep full-width menu items inside the popover when rendered as <a> or <li> (2d)', () => {
|
|
69
|
+
expect(css('popover.css')).toMatch(/\.mint-menu-item\s*\{[^}]*box-sizing:\s*border-box;/)
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
it('should size the popover border-box so trigger-width panels do not overhang (2d)', () => {
|
|
73
|
+
expect(css('popover.css')).toMatch(/\.mint-popover\s*\{[^}]*box-sizing:\s*border-box;/)
|
|
74
|
+
})
|
|
75
|
+
})
|
|
@@ -66,6 +66,7 @@ import {
|
|
|
66
66
|
toInstrumentRunRows,
|
|
67
67
|
toInstrumentRunScheduleEvents,
|
|
68
68
|
toInstrumentRunSteps,
|
|
69
|
+
racksFromPlateState,
|
|
69
70
|
toPlateMapEditorState,
|
|
70
71
|
toProtocolDataFrame,
|
|
71
72
|
toProtocolSteps,
|
|
@@ -251,6 +252,12 @@ describe('bio data templates', () => {
|
|
|
251
252
|
expect(listBioTemplatePresets()).toEqual(bioTemplatePresetsContract)
|
|
252
253
|
})
|
|
253
254
|
|
|
255
|
+
it('should not recommend AutoGroupModal when it is scheduled for removal', () => {
|
|
256
|
+
const components = listBioTemplateCatalog().flatMap(entry => entry.components)
|
|
257
|
+
|
|
258
|
+
expect(components).not.toContain('AutoGroupModal')
|
|
259
|
+
})
|
|
260
|
+
|
|
254
261
|
it('prefers generic dataframe adapters in catalog entries', () => {
|
|
255
262
|
const dataframeTemplates = listBioTemplateCatalog().filter(entry =>
|
|
256
263
|
entry.components.includes('DataFrame')
|
|
@@ -311,12 +318,12 @@ describe('bio data templates', () => {
|
|
|
311
318
|
const westernBindings = getBioTemplateComponentBindings('western-blot-assay')
|
|
312
319
|
const wellplateImports = toBioTemplateComponentImports('wellplate-screen')
|
|
313
320
|
|
|
314
|
-
expect(bindings['plate-map'].map(binding => binding.component)).toEqual(['
|
|
321
|
+
expect(bindings['plate-map'].map(binding => binding.component)).toEqual(['PlateEditor', 'WellPlate'])
|
|
315
322
|
expect(wellplateBindings.map(binding => binding.component)).toContain('DoseCalculator')
|
|
316
323
|
expect(wellplateBindings.map(binding => binding.component)).toContain('WellPlate')
|
|
317
324
|
expect(qpcrBindings.map(binding => binding.component)).toContain('WellPlate')
|
|
318
325
|
expect(qpcrBindings.map(binding => binding.component)).toContain('DataFrame')
|
|
319
|
-
expect(elisaBindings.map(binding => binding.component)).toContain('
|
|
326
|
+
expect(elisaBindings.map(binding => binding.component)).toContain('PlateEditor')
|
|
320
327
|
expect(elisaBindings.map(binding => binding.component)).toContain('DataFrame')
|
|
321
328
|
expect(lcmsBindings.map(binding => binding.component)).toContain('ScheduleCalendar')
|
|
322
329
|
expect(lcmsBindings.map(binding => binding.component)).toContain('ExperimentTimeline')
|
|
@@ -335,8 +342,8 @@ describe('bio data templates', () => {
|
|
|
335
342
|
expect(wellplateImports).toEqual([
|
|
336
343
|
{
|
|
337
344
|
importPath: '@morscherlab/mint-sdk',
|
|
338
|
-
components: ['
|
|
339
|
-
statement: "import {
|
|
345
|
+
components: ['PlateEditor', 'WellPlate', 'DataFrame', 'SampleSelector', 'DoseCalculator'],
|
|
346
|
+
statement: "import { PlateEditor, WellPlate, DataFrame, SampleSelector, DoseCalculator } from '@morscherlab/mint-sdk'",
|
|
340
347
|
},
|
|
341
348
|
])
|
|
342
349
|
})
|
|
@@ -354,6 +361,12 @@ describe('bio data templates', () => {
|
|
|
354
361
|
expect(state.samples[1].id).toBe('drug-a')
|
|
355
362
|
})
|
|
356
363
|
|
|
364
|
+
it('should convert plate-map state into PlateEditor racks', () => {
|
|
365
|
+
const state = toPlateMapEditorState(createPlateMapTemplate({ samples: ['DMSO'] }))
|
|
366
|
+
|
|
367
|
+
expect(racksFromPlateState(state)[0]).toMatchObject({ id: 'plate-1', format: 96, slot: 'R' })
|
|
368
|
+
})
|
|
369
|
+
|
|
357
370
|
it('loads the shared plate-map fixture', () => {
|
|
358
371
|
const state = toPlateMapEditorState(plateMapFixture as PlateMapTemplate)
|
|
359
372
|
const wells = toWellPlateWells(plateMapFixture as PlateMapTemplate)
|
|
@@ -390,7 +403,7 @@ describe('bio data templates', () => {
|
|
|
390
403
|
})
|
|
391
404
|
|
|
392
405
|
expect(Object.keys(propsById)).toEqual([
|
|
393
|
-
'plate-map:
|
|
406
|
+
'plate-map:PlateEditor',
|
|
394
407
|
'plate-map:WellPlate',
|
|
395
408
|
'sample-sheet:DataFrame',
|
|
396
409
|
'sample-sheet:SampleSelector',
|
|
@@ -446,13 +459,13 @@ describe('bio data templates', () => {
|
|
|
446
459
|
propsVariable: 'bindings',
|
|
447
460
|
})
|
|
448
461
|
|
|
449
|
-
expect(snippets.map(snippet => snippet.component)).toEqual(['
|
|
462
|
+
expect(snippets.map(snippet => snippet.component)).toEqual(['PlateEditor', 'WellPlate'])
|
|
450
463
|
expect(snippets.map(snippet => snippet.propsName)).toEqual([
|
|
451
|
-
'
|
|
464
|
+
'plateMapPlateEditorProps',
|
|
452
465
|
'plateMapWellPlateProps',
|
|
453
466
|
])
|
|
454
467
|
expect(snippets[0].propsExpression).toBe('bindings[0].propsObject')
|
|
455
|
-
expect(snippets[0].template).toBe('<
|
|
468
|
+
expect(snippets[0].template).toBe('<PlateEditor v-bind="bindings[0].propsObject" />')
|
|
456
469
|
expect(snippets[1].template).toBe('<WellPlate v-bind="bindings[1].propsObject" />')
|
|
457
470
|
})
|
|
458
471
|
|
|
@@ -463,20 +476,20 @@ describe('bio data templates', () => {
|
|
|
463
476
|
})
|
|
464
477
|
|
|
465
478
|
expect(usage.imports[0].statement).toBe(
|
|
466
|
-
"import {
|
|
479
|
+
"import { PlateEditor, WellPlate } from '@morscherlab/mint-sdk'"
|
|
467
480
|
)
|
|
468
481
|
expect(usage.componentProps).toHaveLength(2)
|
|
469
482
|
expect(usage.propsDeclarations).toEqual([
|
|
470
|
-
'const
|
|
483
|
+
'const plateMapPlateEditorProps = bindings[0].propsObject',
|
|
471
484
|
'const plateMapWellPlateProps = bindings[1].propsObject',
|
|
472
485
|
])
|
|
473
486
|
expect(usage.scriptSetup).toBe([
|
|
474
487
|
'const bindings = toBioTemplateComponentProps(plateMap)',
|
|
475
|
-
'const
|
|
488
|
+
'const plateMapPlateEditorProps = bindings[0].propsObject',
|
|
476
489
|
'const plateMapWellPlateProps = bindings[1].propsObject',
|
|
477
490
|
].join('\n'))
|
|
478
491
|
expect(usage.template).toBe([
|
|
479
|
-
'<
|
|
492
|
+
'<PlateEditor v-bind="plateMapPlateEditorProps" />',
|
|
480
493
|
'<WellPlate v-bind="plateMapWellPlateProps" />',
|
|
481
494
|
].join('\n'))
|
|
482
495
|
})
|
|
@@ -487,10 +500,10 @@ describe('bio data templates', () => {
|
|
|
487
500
|
expect(usage.scriptSetup).toContain(
|
|
488
501
|
'const props = defineProps<{ templateCollection: BioTemplateEnvelope<unknown> | TemplateCollectionEnvelope }>()'
|
|
489
502
|
)
|
|
490
|
-
expect(usage.sfc).toContain("import {
|
|
503
|
+
expect(usage.sfc).toContain("import { PlateEditor, WellPlate } from '@morscherlab/mint-sdk'")
|
|
491
504
|
expect(usage.sfc).toContain("import { toBioTemplateComponentProps } from '@morscherlab/mint-sdk/templates'")
|
|
492
505
|
expect(usage.sfc).toContain('defineProps<{ templateCollection: BioTemplateEnvelope<unknown> | TemplateCollectionEnvelope }>()')
|
|
493
|
-
expect(usage.sfc).toContain('<
|
|
506
|
+
expect(usage.sfc).toContain('<PlateEditor v-bind="plateMapPlateEditorProps" />')
|
|
494
507
|
expect(usage.sfc).toContain('<WellPlate v-bind="plateMapWellPlateProps" />')
|
|
495
508
|
expect(usage.sfc).toMatch(/^<script setup lang="ts">[\s\S]*<\/template>$/)
|
|
496
509
|
})
|
|
@@ -583,7 +596,7 @@ describe('bio data templates', () => {
|
|
|
583
596
|
expect(wellplate.metadata?.preset).toBe('wellplate-screen')
|
|
584
597
|
expect(toPlateMapEditorState(wellplateTemplates['plate-map'] as PlateMapTemplate).samples[1].id).toBe('treatment')
|
|
585
598
|
expect(toDoseConditions(wellplateTemplates['dose-response'] as DoseResponseTemplate)[0].label).toBe('Drug A')
|
|
586
|
-
expect(wellplateComponentProps.map(binding => binding.component)).toContain('
|
|
599
|
+
expect(wellplateComponentProps.map(binding => binding.component)).toContain('PlateEditor')
|
|
587
600
|
expect(wellplateComponentProps.map(binding => binding.component)).toContain('DoseCalculator')
|
|
588
601
|
expect(Object.keys(qpcrTemplates)).toEqual(['sample-sheet', 'qpcr-plate'])
|
|
589
602
|
expect(toQpcrRows(qpcrTemplates['qpcr-plate'] as QpcrPlateTemplate)[0].sampleId).toBe('S001')
|
|
@@ -1183,3 +1196,40 @@ describe('bio data templates', () => {
|
|
|
1183
1196
|
expect(template.data.measurements[0].featureId).toBe('lactate')
|
|
1184
1197
|
})
|
|
1185
1198
|
})
|
|
1199
|
+
|
|
1200
|
+
describe('plate-map PlateEditor binding (7a)', () => {
|
|
1201
|
+
const editorProps = () =>
|
|
1202
|
+
toBioTemplateComponentProps(plateMapFixture as PlateMapTemplate)
|
|
1203
|
+
.find(binding => binding.component === 'PlateEditor')?.propsObject as Record<string, unknown>
|
|
1204
|
+
|
|
1205
|
+
it('should pass the plates as racks with sequential slots', () => {
|
|
1206
|
+
expect((editorProps().modelValue as Array<{ slot: string }>)[0].slot).toBe('R')
|
|
1207
|
+
})
|
|
1208
|
+
|
|
1209
|
+
it('should move the sample id of a well to its group', () => {
|
|
1210
|
+
const racks = editorProps().modelValue as Array<{ wells: Record<string, { group?: string }> }>
|
|
1211
|
+
|
|
1212
|
+
expect(racks[0].wells.A2.group).toBe('drug-a')
|
|
1213
|
+
})
|
|
1214
|
+
|
|
1215
|
+
it('should make a well with a sample id a sample', () => {
|
|
1216
|
+
const racks = editorProps().modelValue as Array<{ wells: Record<string, { sampleType?: string }> }>
|
|
1217
|
+
|
|
1218
|
+
expect(racks[0].wells.A2.sampleType).toBe('sample')
|
|
1219
|
+
})
|
|
1220
|
+
|
|
1221
|
+
it('should leave the stored plate-map wells unchanged', () => {
|
|
1222
|
+
const template = structuredClone(plateMapFixture) as PlateMapTemplate
|
|
1223
|
+
toBioTemplateComponentProps(template)
|
|
1224
|
+
|
|
1225
|
+
expect(template).toEqual(plateMapFixture)
|
|
1226
|
+
})
|
|
1227
|
+
|
|
1228
|
+
it('should offer the template samples as groups', () => {
|
|
1229
|
+
expect((editorProps().groups as Array<{ id: string }>).map(group => group.id)).toContain('drug-a')
|
|
1230
|
+
})
|
|
1231
|
+
|
|
1232
|
+
it('should pin the format to the plate format', () => {
|
|
1233
|
+
expect(editorProps().formats).toEqual([96])
|
|
1234
|
+
})
|
|
1235
|
+
})
|