@morscherlab/mint-sdk 1.0.0-rc.4 → 1.0.0-rc.6
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/dist/__tests__/components/AppTopBar.navigation.test.d.ts +1 -0
- package/dist/__tests__/components/DoseCalculatorVolumeField.test.d.ts +1 -0
- package/dist/__tests__/components/PlateMapEditorToolbarInternal.test.d.ts +1 -0
- package/dist/__tests__/components/PluginWorkspaceView.controls.test.d.ts +1 -0
- package/dist/__tests__/components/PluginWorkspaceView.navigation.test.d.ts +1 -0
- package/dist/__tests__/components/PluginWorkspaceView.shell.test.d.ts +1 -0
- package/dist/__tests__/components/ProtocolStep.presentation.test.d.ts +1 -0
- package/dist/__tests__/components/ProtocolStepEditor.state.test.d.ts +1 -0
- package/dist/__tests__/components/ProtocolStepParameterField.test.d.ts +1 -0
- package/dist/__tests__/components/ReagentList.presentation.test.d.ts +1 -0
- package/dist/__tests__/components/SampleSelector.colors.test.d.ts +1 -0
- package/dist/__tests__/components/SampleSelector.drag.test.d.ts +1 -0
- package/dist/__tests__/components/SampleSelector.groups.test.d.ts +1 -0
- package/dist/__tests__/components/SampleSelector.selection.test.d.ts +1 -0
- package/dist/__tests__/components/SampleSelectorSampleRow.test.d.ts +1 -0
- package/dist/__tests__/components/ScheduleCalendar.test.d.ts +1 -0
- package/dist/__tests__/components/SettingsModal.schema.test.d.ts +1 -0
- package/dist/__tests__/components/WellPlate.colors.test.d.ts +1 -0
- package/dist/__tests__/components/WellPlate.conditions.test.d.ts +1 -0
- package/dist/__tests__/components/WellPlate.geometry.test.d.ts +1 -0
- package/dist/__tests__/components/WellPlate.interaction.test.d.ts +1 -0
- package/dist/__tests__/components/WellPlate.legend.test.d.ts +1 -0
- package/dist/__tests__/components/WellPlate.rendering.test.d.ts +1 -0
- package/dist/__tests__/components/WellPlate.sampleDrop.test.d.ts +1 -0
- package/dist/__tests__/composables/autoGroup/classify.test.d.ts +1 -0
- package/dist/__tests__/composables/autoGroup/columns.test.d.ts +1 -0
- package/dist/__tests__/composables/autoGroup/compose.test.d.ts +1 -0
- package/dist/__tests__/composables/autoGroup/cooccurrence.test.d.ts +1 -0
- package/dist/__tests__/composables/autoGroup/fingerprint.test.d.ts +1 -0
- package/dist/__tests__/composables/autoGroup/integration.test.d.ts +1 -0
- package/dist/__tests__/composables/autoGroup/template.test.d.ts +1 -0
- package/dist/__tests__/composables/autoGroup/tokenize.test.d.ts +1 -0
- package/dist/__tests__/composables/useAutoGroupInputSources.test.d.ts +1 -0
- package/dist/__tests__/composables/useScheduleCalendarLayout.test.d.ts +1 -0
- package/dist/__tests__/docs/extractDocsComponents.test.d.ts +1 -0
- package/dist/__tests__/docs/extractDocsExports.test.d.ts +1 -0
- package/dist/__tests__/docs/extractDocsParsing.test.d.ts +1 -0
- package/dist/__tests__/docs/extractDocsTemplates.test.d.ts +1 -0
- package/dist/__tests__/docs/extractDocsTheme.test.d.ts +1 -0
- package/dist/components/AppSidebar.vue.d.ts +9 -6
- package/dist/components/AppTopBar.navigation.d.ts +11 -0
- package/dist/components/BaseButton.vue.d.ts +1 -1
- package/dist/components/BaseCheckbox.vue.d.ts +7 -2
- package/dist/components/BaseInput.vue.d.ts +2 -2
- package/dist/components/BasePill.vue.d.ts +2 -2
- package/dist/components/BaseRadioGroup.vue.d.ts +2 -2
- package/dist/components/BaseSelect.vue.d.ts +1 -1
- package/dist/components/BaseSlider.vue.d.ts +2 -2
- package/dist/components/BaseTextarea.vue.d.ts +2 -2
- package/dist/components/BaseToggle.vue.d.ts +7 -2
- package/dist/components/BioTemplateExperimentWorkspaceView.vue.d.ts +2 -2
- package/dist/components/BioTemplatePackWorkspaceView.vue.d.ts +1 -1
- package/dist/components/CollapsibleCard.vue.d.ts +9 -0
- package/dist/components/ColorSlider.vue.d.ts +2 -2
- package/dist/components/ConcentrationInput.vue.d.ts +2 -2
- package/dist/components/ControlWorkspaceView.vue.d.ts +4 -4
- package/dist/components/DatePicker.vue.d.ts +1 -1
- package/dist/components/DateTimePicker.vue.d.ts +2 -2
- package/dist/components/DoseCalculatorVolumeField.vue.d.ts +15 -0
- package/dist/components/DoseDesignWorkspaceView.vue.d.ts +2 -2
- package/dist/components/DropdownButton.vue.d.ts +1 -1
- package/dist/components/FileUploader.vue.d.ts +2 -2
- package/dist/components/FormulaInput.vue.d.ts +2 -2
- package/dist/components/IconButton.vue.d.ts +1 -1
- package/dist/components/LoadingSpinner.vue.d.ts +1 -1
- package/dist/components/MoleculeInput.vue.d.ts +2 -2
- package/dist/components/MultiSelect.vue.d.ts +1 -1
- package/dist/components/NumberInput.vue.d.ts +1 -1
- package/dist/components/PlateMapEditor.vue.d.ts +6 -6
- package/dist/components/PluginWorkspaceView.controls.d.ts +28 -0
- package/dist/components/PluginWorkspaceView.navigation.d.ts +29 -0
- package/dist/components/PluginWorkspaceView.props.d.ts +151 -0
- package/dist/components/PluginWorkspaceView.shell.d.ts +19 -0
- package/dist/components/PluginWorkspaceView.vue.d.ts +51 -196
- package/dist/components/ProgressBar.vue.d.ts +1 -1
- package/dist/components/ProtocolStep.presentation.d.ts +4 -0
- package/dist/components/ProtocolStepEditor.state.d.ts +18 -0
- package/dist/components/ProtocolStepParameterField.vue.d.ts +12 -0
- package/dist/components/ReagentList.presentation.d.ts +16 -0
- package/dist/components/ResourceCard.vue.d.ts +1 -1
- package/dist/components/SampleSelector.colors.d.ts +13 -0
- package/dist/components/SampleSelector.drag.d.ts +24 -0
- package/dist/components/SampleSelector.groups.d.ts +15 -0
- package/dist/components/SampleSelector.selection.d.ts +26 -0
- package/dist/components/SampleSelector.vue.d.ts +4 -1
- package/dist/components/SampleSelectorSampleRow.vue.d.ts +21 -0
- package/dist/components/SegmentedControl.vue.d.ts +1 -1
- package/dist/components/SequenceInput.vue.d.ts +2 -2
- package/dist/components/SequenceProgressBar.vue.d.ts +1 -1
- package/dist/components/SettingsModal.schema.d.ts +9 -0
- package/dist/components/StatusIndicator.vue.d.ts +1 -1
- package/dist/components/TagsInput.vue.d.ts +2 -2
- package/dist/components/TimePicker.vue.d.ts +2 -2
- package/dist/components/TimeRangeInput.vue.d.ts +1 -1
- package/dist/components/UnitInput.vue.d.ts +2 -2
- package/dist/components/WellPlate.colors.d.ts +9 -0
- package/dist/components/WellPlate.conditions.d.ts +26 -0
- package/dist/components/WellPlate.geometry.d.ts +23 -0
- package/dist/components/WellPlate.interaction.d.ts +71 -0
- package/dist/components/WellPlate.legend.d.ts +2 -0
- package/dist/components/WellPlate.rendering.d.ts +24 -0
- package/dist/components/WellPlate.sampleDrop.d.ts +8 -0
- package/dist/components/WellPlate.vue.d.ts +1 -1
- package/dist/components/index.js +2 -2
- package/dist/components/internal/ActionItemInternal.vue.d.ts +1 -1
- package/dist/components/internal/PlateMapEditorToolbarInternal.vue.d.ts +28 -0
- package/dist/{components-DafPc4rM.js → components-Blx4MG--.js} +4073 -4222
- package/dist/components-Blx4MG--.js.map +1 -0
- package/dist/composables/autoGroup/classKey.d.ts +4 -0
- package/dist/composables/autoGroup/classify.d.ts +28 -0
- package/dist/composables/autoGroup/colors.d.ts +2 -0
- package/dist/composables/autoGroup/columns.d.ts +10 -0
- package/dist/composables/autoGroup/compose.d.ts +8 -0
- package/dist/composables/autoGroup/cooccurrence.d.ts +2 -0
- package/dist/composables/autoGroup/csv-shim.d.ts +2 -0
- package/dist/composables/autoGroup/fingerprint.d.ts +3 -0
- package/dist/composables/autoGroup/index.d.ts +16 -0
- package/dist/composables/autoGroup/replicatePreGroup.d.ts +38 -0
- package/dist/composables/autoGroup/template.d.ts +15 -0
- package/dist/composables/autoGroup/tokenize.d.ts +8 -0
- package/dist/composables/autoGroupConstants.d.ts +1 -0
- package/dist/composables/autoGroupGrouping.d.ts +3 -0
- package/dist/composables/controlComponentBindings.d.ts +1 -1
- package/dist/composables/controlSchemaAdapters.d.ts +1 -1
- package/dist/composables/controlSchemaDoseDesign.d.ts +11 -0
- package/dist/composables/controlSchemaLayout.d.ts +1 -1
- package/dist/composables/controlSchemaModel.d.ts +5 -0
- package/dist/composables/controlSchemaNormalize.d.ts +1 -1
- package/dist/composables/controlSchemaTypes.d.ts +311 -0
- package/dist/composables/controlWorkspaceOptions.d.ts +1 -1
- package/dist/composables/formBuilderSchema.d.ts +18 -0
- package/dist/composables/index.js +3 -3
- package/dist/composables/pluginEndpointBuilder.d.ts +13 -0
- package/dist/composables/protocolTemplateCatalog.d.ts +26 -0
- package/dist/composables/useAutoGroup.d.ts +61 -74
- package/dist/composables/useAutoGroupInputSources.d.ts +32 -0
- package/dist/composables/useBioTemplateControls.d.ts +1 -1
- package/dist/composables/useBioTemplatePresetWorkspace.d.ts +1 -1
- package/dist/composables/useBioTemplateWorkspace.d.ts +1 -1
- package/dist/composables/useControlSchema.d.ts +4 -316
- package/dist/composables/useControlWorkspace.d.ts +1 -1
- package/dist/composables/useForm.d.ts +2 -33
- package/dist/composables/useFormBuilder.d.ts +2 -9
- package/dist/composables/useFormValidation.d.ts +34 -0
- package/dist/composables/usePluginClient.d.ts +1 -4
- package/dist/composables/useProtocolTemplates.d.ts +2 -24
- package/dist/composables/useScheduleCalendarLayout.d.ts +49 -0
- package/dist/{composables-BMkPQhVK.js → composables-CHDjDIQT.js} +33 -31
- package/dist/composables-CHDjDIQT.js.map +1 -0
- package/dist/index.js +4 -4
- package/dist/install.js +2 -2
- package/dist/styles.css +1432 -660
- package/dist/templates/controlSchemaTypes.d.ts +1 -1
- package/dist/templates/index.js +1 -1
- package/dist/templates/templateAdapterTypes.d.ts +48 -0
- package/dist/templates/templateCreateOptions.d.ts +165 -0
- package/dist/templates/templateQpcrTypes.d.ts +42 -0
- package/dist/templates/types.d.ts +5 -250
- package/dist/{templates-bUAWMn5L.js → templates-DSbHJC4v.js} +1536 -297
- package/dist/templates-DSbHJC4v.js.map +1 -0
- package/dist/types/auto-group.d.ts +79 -9
- package/dist/types/componentLabTypes.d.ts +161 -0
- package/dist/types/componentWorkflowTypes.d.ts +150 -0
- package/dist/types/components.d.ts +14 -311
- package/dist/types/form-builder.d.ts +3 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/{useProtocolTemplates-QZtHFFH2.js → useProtocolTemplates-BbPOYPzO.js} +1220 -454
- package/dist/useProtocolTemplates-BbPOYPzO.js.map +1 -0
- package/package.json +1 -1
- package/src/__tests__/components/AppSidebar.test.ts +67 -0
- package/src/__tests__/components/AppTopBar.navigation.test.ts +70 -0
- package/src/__tests__/components/CollapsibleCard.test.ts +47 -0
- package/src/__tests__/components/DoseCalculatorVolumeField.test.ts +53 -0
- package/src/__tests__/components/FormBuilder.test.ts +57 -0
- package/src/__tests__/components/PlateMapEditorToolbarInternal.test.ts +54 -0
- package/src/__tests__/components/PluginWorkspaceView.controls.test.ts +156 -0
- package/src/__tests__/components/PluginWorkspaceView.navigation.test.ts +102 -0
- package/src/__tests__/components/PluginWorkspaceView.shell.test.ts +43 -0
- package/src/__tests__/components/ProtocolStep.presentation.test.ts +31 -0
- package/src/__tests__/components/ProtocolStepEditor.state.test.ts +165 -0
- package/src/__tests__/components/ProtocolStepParameterField.test.ts +44 -0
- package/src/__tests__/components/ReagentList.presentation.test.ts +68 -0
- package/src/__tests__/components/SampleSelector.colors.test.ts +49 -0
- package/src/__tests__/components/SampleSelector.drag.test.ts +100 -0
- package/src/__tests__/components/SampleSelector.groups.test.ts +81 -0
- package/src/__tests__/components/SampleSelector.selection.test.ts +70 -0
- package/src/__tests__/components/SampleSelector.test.ts +32 -0
- package/src/__tests__/components/SampleSelectorSampleRow.test.ts +37 -0
- package/src/__tests__/components/ScheduleCalendar.test.ts +44 -0
- package/src/__tests__/components/SettingsModal.schema.test.ts +97 -0
- package/src/__tests__/components/WellPlate.colors.test.ts +28 -0
- package/src/__tests__/components/WellPlate.conditions.test.ts +68 -0
- package/src/__tests__/components/WellPlate.geometry.test.ts +54 -0
- package/src/__tests__/components/WellPlate.interaction.test.ts +171 -0
- package/src/__tests__/components/WellPlate.legend.test.ts +13 -0
- package/src/__tests__/components/WellPlate.rendering.test.ts +122 -0
- package/src/__tests__/components/WellPlate.sampleDrop.test.ts +70 -0
- package/src/__tests__/composables/autoGroup/classify.test.ts +107 -0
- package/src/__tests__/composables/autoGroup/columns.test.ts +135 -0
- package/src/__tests__/composables/autoGroup/compose.test.ts +227 -0
- package/src/__tests__/composables/autoGroup/cooccurrence.test.ts +91 -0
- package/src/__tests__/composables/autoGroup/fingerprint.test.ts +50 -0
- package/src/__tests__/composables/autoGroup/integration.test.ts +79 -0
- package/src/__tests__/composables/autoGroup/template.test.ts +70 -0
- package/src/__tests__/composables/autoGroup/tokenize.test.ts +33 -0
- package/src/__tests__/composables/useAutoGroup.test.ts +129 -625
- package/src/__tests__/composables/useAutoGroupInputSources.test.ts +107 -0
- package/src/__tests__/composables/useControlSchema.test.ts +23 -0
- package/src/__tests__/composables/useScheduleCalendarLayout.test.ts +89 -0
- package/src/__tests__/docs/extractDocsComponents.test.ts +142 -0
- package/src/__tests__/docs/extractDocsExports.test.ts +77 -0
- package/src/__tests__/docs/extractDocsParsing.test.ts +69 -0
- package/src/__tests__/docs/extractDocsTemplates.test.ts +54 -0
- package/src/__tests__/docs/extractDocsTheme.test.ts +89 -0
- package/src/__tests__/docs/frontendDocsCatalog.test.ts +1 -1
- package/src/__tests__/fixtures/auto-group/mixed-lc-ms-batch.txt +187 -0
- package/src/components/AppSidebar.story.vue +79 -6
- package/src/components/AppSidebar.vue +74 -6
- package/src/components/AppTopBar.navigation.ts +62 -0
- package/src/components/AppTopBar.vue +17 -44
- package/src/components/AutoGroupModal.story.vue +50 -0
- package/src/components/AutoGroupModal.vue +441 -158
- package/src/components/BaseCheckbox.story.vue +27 -0
- package/src/components/BaseCheckbox.vue +63 -1
- package/src/components/BaseToggle.story.vue +27 -0
- package/src/components/BaseToggle.vue +66 -1
- package/src/components/CollapsibleCard.vue +123 -45
- package/src/components/ControlWorkspaceView.vue +2 -6
- package/src/components/DoseCalculator.vue +13 -73
- package/src/components/DoseCalculatorVolumeField.vue +61 -0
- package/src/components/ExperimentTimeline.vue +6 -31
- package/src/components/FormBuilder.story.vue +13 -0
- package/src/components/FormBuilder.vue +2 -7
- package/src/components/PlateMapEditor.vue +32 -106
- package/src/components/PluginWorkspaceView.controls.ts +182 -0
- package/src/components/PluginWorkspaceView.navigation.ts +106 -0
- package/src/components/PluginWorkspaceView.props.ts +174 -0
- package/src/components/PluginWorkspaceView.shell.ts +67 -0
- package/src/components/PluginWorkspaceView.vue +88 -404
- package/src/components/ProtocolStep.presentation.ts +31 -0
- package/src/components/ProtocolStepEditor.state.ts +104 -0
- package/src/components/ProtocolStepEditor.vue +48 -179
- package/src/components/ProtocolStepParameterField.vue +134 -0
- package/src/components/ReagentList.presentation.ts +105 -0
- package/src/components/ReagentList.vue +16 -79
- package/src/components/SampleSelector.colors.ts +43 -0
- package/src/components/SampleSelector.drag.ts +164 -0
- package/src/components/SampleSelector.groups.ts +109 -0
- package/src/components/SampleSelector.selection.ts +103 -0
- package/src/components/SampleSelector.vue +82 -349
- package/src/components/SampleSelectorSampleRow.vue +64 -0
- package/src/components/ScheduleCalendar.vue +44 -199
- package/src/components/SettingsModal.schema.ts +71 -0
- package/src/components/SettingsModal.vue +16 -46
- package/src/components/WellPlate.colors.ts +56 -0
- package/src/components/WellPlate.conditions.ts +100 -0
- package/src/components/WellPlate.geometry.ts +91 -0
- package/src/components/WellPlate.interaction.ts +272 -0
- package/src/components/WellPlate.legend.ts +8 -0
- package/src/components/WellPlate.rendering.ts +105 -0
- package/src/components/WellPlate.sampleDrop.ts +73 -0
- package/src/components/WellPlate.vue +102 -550
- package/src/components/internal/FormFieldRendererInternal.vue +23 -5
- package/src/components/internal/PlateMapEditorToolbarInternal.vue +128 -0
- package/src/composables/autoGroup/classKey.ts +5 -0
- package/src/composables/autoGroup/classify.ts +205 -0
- package/src/composables/autoGroup/colors.ts +6 -0
- package/src/composables/autoGroup/columns.ts +226 -0
- package/src/composables/autoGroup/compose.ts +156 -0
- package/src/composables/autoGroup/cooccurrence.ts +46 -0
- package/src/composables/autoGroup/csv-shim.ts +44 -0
- package/src/composables/autoGroup/fingerprint.ts +49 -0
- package/src/composables/autoGroup/index.ts +20 -0
- package/src/composables/autoGroup/replicatePreGroup.ts +90 -0
- package/src/composables/autoGroup/template.ts +126 -0
- package/src/composables/autoGroup/tokenize.ts +41 -0
- package/src/composables/autoGroup/vocab.json +67 -0
- package/src/composables/autoGroupConstants.ts +4 -0
- package/src/composables/autoGroupGrouping.ts +148 -0
- package/src/composables/controlComponentBindings.ts +1 -1
- package/src/composables/controlSchemaAdapters.ts +4 -1
- package/src/composables/controlSchemaDoseDesign.ts +215 -0
- package/src/composables/controlSchemaFormFields.ts +4 -1
- package/src/composables/controlSchemaLayout.ts +1 -1
- package/src/composables/controlSchemaModel.ts +163 -0
- package/src/composables/controlSchemaNormalize.ts +1 -1
- package/src/composables/controlSchemaTypes.ts +372 -0
- package/src/composables/controlWorkspaceOptions.ts +1 -1
- package/src/composables/formBuilderSchema.ts +153 -0
- package/src/composables/pluginEndpointBuilder.ts +203 -0
- package/src/composables/protocolTemplateCatalog.ts +325 -0
- package/src/composables/useAutoGroup.ts +395 -549
- package/src/composables/useAutoGroupInputSources.ts +147 -0
- package/src/composables/useBioTemplateControls.ts +1 -1
- package/src/composables/useBioTemplatePresetWorkspace.ts +1 -1
- package/src/composables/useBioTemplateWorkspace.ts +1 -1
- package/src/composables/useControlSchema.ts +21 -692
- package/src/composables/useControlWorkspace.ts +7 -13
- package/src/composables/useForm.ts +5 -187
- package/src/composables/useFormBuilder.ts +11 -153
- package/src/composables/useFormValidation.ts +154 -0
- package/src/composables/usePluginClient.ts +10 -193
- package/src/composables/useProtocolTemplates.ts +10 -328
- package/src/composables/useScheduleCalendarLayout.ts +287 -0
- package/src/styles/components/app-sidebar.css +134 -6
- package/src/styles/components/auto-group-modal.css +248 -310
- package/src/styles/components/checkbox.css +87 -0
- package/src/styles/components/collapsible-card.css +154 -14
- package/src/styles/components/toggle.css +80 -0
- package/src/templates/controlSchemaTypes.ts +1 -1
- package/src/templates/templateAdapterTypes.ts +58 -0
- package/src/templates/templateCreateOptions.ts +208 -0
- package/src/templates/templateQpcrTypes.ts +48 -0
- package/src/templates/types.ts +79 -275
- package/src/types/auto-group.ts +107 -9
- package/src/types/componentLabTypes.ts +235 -0
- package/src/types/componentWorkflowTypes.ts +190 -0
- package/src/types/components.ts +95 -424
- package/src/types/form-builder.ts +3 -0
- package/src/types/index.ts +2 -0
- package/dist/components-DafPc4rM.js.map +0 -1
- package/dist/composables-BMkPQhVK.js.map +0 -1
- package/dist/templates-bUAWMn5L.js.map +0 -1
- package/dist/useProtocolTemplates-QZtHFFH2.js.map +0 -1
|
@@ -4,6 +4,16 @@ import { ref, computed } from 'vue'
|
|
|
4
4
|
import type { ReagentColumn, Reagent } from '../types'
|
|
5
5
|
import { useSortedItems } from '../composables/useSortedItems'
|
|
6
6
|
import { useTextSearch } from '../composables/useTextSearch'
|
|
7
|
+
import {
|
|
8
|
+
REAGENT_COLUMN_LABELS as columnLabels,
|
|
9
|
+
formatReagentExpiryDate as formatExpiryDate,
|
|
10
|
+
getReagentColumnValue,
|
|
11
|
+
getReagentRowClasses,
|
|
12
|
+
getReagentStockFillClass as getStockFillClass,
|
|
13
|
+
getReagentStockLevel as getStockLevel,
|
|
14
|
+
isReagentExpired as isExpired,
|
|
15
|
+
isReagentExpiringSoon as isExpiringSoon,
|
|
16
|
+
} from './ReagentList.presentation'
|
|
7
17
|
|
|
8
18
|
interface Props {
|
|
9
19
|
modelValue?: Reagent[]
|
|
@@ -40,18 +50,6 @@ const sortDirection = ref<'asc' | 'desc'>('asc')
|
|
|
40
50
|
const draggedId = ref<string | null>(null)
|
|
41
51
|
const dragOverId = ref<string | null>(null)
|
|
42
52
|
|
|
43
|
-
// Column configuration
|
|
44
|
-
const columnLabels: Record<ReagentColumn, string> = {
|
|
45
|
-
name: 'Name',
|
|
46
|
-
catalog: 'Catalog #',
|
|
47
|
-
lot: 'Lot #',
|
|
48
|
-
expiry: 'Expiry',
|
|
49
|
-
storage: 'Storage',
|
|
50
|
-
location: 'Location',
|
|
51
|
-
stock: 'Stock',
|
|
52
|
-
supplier: 'Supplier',
|
|
53
|
-
}
|
|
54
|
-
|
|
55
53
|
const reagentSearch = useTextSearch({
|
|
56
54
|
items: () => props.modelValue || [],
|
|
57
55
|
query: searchQuery,
|
|
@@ -76,77 +74,16 @@ const sortedReagents = useSortedItems<Reagent, ReagentColumn>({
|
|
|
76
74
|
items: reagentSearch.filteredItems,
|
|
77
75
|
sort: reagentSort,
|
|
78
76
|
caseSensitive: false,
|
|
79
|
-
getValue: (reagent, column) =>
|
|
77
|
+
getValue: (reagent, column) => getReagentColumnValue(reagent, column),
|
|
80
78
|
})
|
|
81
79
|
const filteredReagents = sortedReagents.sortedItems
|
|
82
80
|
|
|
83
|
-
function getColumnValue(reagent: Reagent, column: ReagentColumn): unknown {
|
|
84
|
-
switch (column) {
|
|
85
|
-
case 'name':
|
|
86
|
-
return reagent.name
|
|
87
|
-
case 'catalog':
|
|
88
|
-
return reagent.catalogNumber
|
|
89
|
-
case 'lot':
|
|
90
|
-
return reagent.lotNumber
|
|
91
|
-
case 'expiry':
|
|
92
|
-
return reagent.expiryDate ? new Date(reagent.expiryDate).getTime() : null
|
|
93
|
-
case 'storage':
|
|
94
|
-
return reagent.storageCondition
|
|
95
|
-
case 'location':
|
|
96
|
-
return reagent.location
|
|
97
|
-
case 'stock':
|
|
98
|
-
return reagent.stockLevel
|
|
99
|
-
case 'supplier':
|
|
100
|
-
return reagent.supplier
|
|
101
|
-
default:
|
|
102
|
-
return null
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// Helpers
|
|
107
|
-
function isExpired(reagent: Reagent): boolean {
|
|
108
|
-
if (!reagent.expiryDate) return false
|
|
109
|
-
const expiry = new Date(reagent.expiryDate)
|
|
110
|
-
return expiry < new Date()
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
function isExpiringSoon(reagent: Reagent, daysThreshold = 30): boolean {
|
|
114
|
-
if (!reagent.expiryDate) return false
|
|
115
|
-
const expiry = new Date(reagent.expiryDate)
|
|
116
|
-
const now = new Date()
|
|
117
|
-
const daysUntilExpiry = (expiry.getTime() - now.getTime()) / (1000 * 60 * 60 * 24)
|
|
118
|
-
return daysUntilExpiry > 0 && daysUntilExpiry <= daysThreshold
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function isLowStock(reagent: Reagent): boolean {
|
|
122
|
-
if (reagent.stockLevel === undefined) return false
|
|
123
|
-
return reagent.stockLevel <= props.lowStockThreshold
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
function formatExpiryDate(date: Date | string | undefined): string {
|
|
127
|
-
if (!date) return '-'
|
|
128
|
-
const d = new Date(date)
|
|
129
|
-
return d.toLocaleDateString('en-US', { year: 'numeric', month: 'short' })
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
function getStockLevel(reagent: Reagent): number {
|
|
133
|
-
return reagent.stockLevel ?? 0
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
function getStockFillClass(level: number): string {
|
|
137
|
-
if (level >= 50) return 'mint-reagent-list__stock-fill--good'
|
|
138
|
-
if (level >= 20) return 'mint-reagent-list__stock-fill--warning'
|
|
139
|
-
return 'mint-reagent-list__stock-fill--low'
|
|
140
|
-
}
|
|
141
|
-
|
|
142
81
|
function getRowClass(reagent: Reagent): string[] {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
if (dragOverId.value === reagent.id) classes.push('mint-reagent-list__row--drag-over')
|
|
149
|
-
return classes
|
|
82
|
+
return getReagentRowClasses(reagent, {
|
|
83
|
+
lowStockThreshold: props.lowStockThreshold,
|
|
84
|
+
draggedId: draggedId.value,
|
|
85
|
+
dragOverId: dragOverId.value,
|
|
86
|
+
})
|
|
150
87
|
}
|
|
151
88
|
|
|
152
89
|
// Actions
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { DEFAULT_COLORS } from '../composables/useAutoGroup'
|
|
2
|
+
import type { SampleGroup } from '../types'
|
|
3
|
+
|
|
4
|
+
export type ColorEdit =
|
|
5
|
+
| { kind: 'single'; name: string }
|
|
6
|
+
| { kind: 'family'; names: string[] }
|
|
7
|
+
|
|
8
|
+
export const DEFAULT_COLOR_PICKER_SEED = '#3B82F6'
|
|
9
|
+
|
|
10
|
+
export function applySampleGroupColorEdit(
|
|
11
|
+
groups: SampleGroup[],
|
|
12
|
+
edit: ColorEdit,
|
|
13
|
+
color: string,
|
|
14
|
+
): SampleGroup[] {
|
|
15
|
+
const targets = edit.kind === 'family' ? new Set(edit.names) : new Set([edit.name])
|
|
16
|
+
return groups.map(group =>
|
|
17
|
+
targets.has(group.name) ? { ...group, color } : group,
|
|
18
|
+
)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function getSampleGroupColorEditSeed(
|
|
22
|
+
edit: ColorEdit | null,
|
|
23
|
+
getGroupColor: (groupName: string) => string,
|
|
24
|
+
): string {
|
|
25
|
+
if (!edit) return DEFAULT_COLOR_PICKER_SEED
|
|
26
|
+
return getGroupColor(edit.kind === 'family' ? edit.names[0] : edit.name)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function pickUnusedSampleGroupColor(groups: SampleGroup[]): string {
|
|
30
|
+
const usedColors = new Set(groups.map(group => group.color))
|
|
31
|
+
return DEFAULT_COLORS.find(color => !usedColors.has(color)) || DEFAULT_COLORS[0]
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function createSampleGroup(name: string, existingGroups: SampleGroup[]): SampleGroup | null {
|
|
35
|
+
const trimmedName = name.trim()
|
|
36
|
+
if (!trimmedName) return null
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
name: trimmedName,
|
|
40
|
+
color: pickUnusedSampleGroupColor(existingGroups),
|
|
41
|
+
samples: [],
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { ref } from 'vue'
|
|
2
|
+
import type { SampleGroup } from '../types'
|
|
3
|
+
import {
|
|
4
|
+
detectSampleGroupSeparator,
|
|
5
|
+
getSampleGroupMajorPrefix,
|
|
6
|
+
moveSampleToGroup,
|
|
7
|
+
reorderSampleGroup,
|
|
8
|
+
reorderSampleMajorGroup,
|
|
9
|
+
type GroupDragKind,
|
|
10
|
+
type GroupReorderPosition,
|
|
11
|
+
} from './SampleSelector.groups'
|
|
12
|
+
|
|
13
|
+
interface MutableSampleGroups {
|
|
14
|
+
value: SampleGroup[]
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function useSampleSelectorDrag(groups: MutableSampleGroups) {
|
|
18
|
+
const draggingSample = ref<string | null>(null)
|
|
19
|
+
const dragSourceGroup = ref<string | null>(null)
|
|
20
|
+
const dragOverGroup = ref<string | null>(null)
|
|
21
|
+
|
|
22
|
+
const draggingGroup = ref<string | null>(null)
|
|
23
|
+
const draggingGroupKind = ref<GroupDragKind | null>(null)
|
|
24
|
+
const reorderTarget = ref<string | null>(null)
|
|
25
|
+
const reorderPosition = ref<GroupReorderPosition | null>(null)
|
|
26
|
+
|
|
27
|
+
function handleDragStart(sample: string, sourceGroup: string | null, event: DragEvent) {
|
|
28
|
+
draggingSample.value = sample
|
|
29
|
+
dragSourceGroup.value = sourceGroup
|
|
30
|
+
if (event.dataTransfer) {
|
|
31
|
+
event.dataTransfer.effectAllowed = 'move'
|
|
32
|
+
event.dataTransfer.setData('text/plain', sample)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function resetDragState() {
|
|
37
|
+
draggingSample.value = null
|
|
38
|
+
dragSourceGroup.value = null
|
|
39
|
+
dragOverGroup.value = null
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function handleDragEnd() {
|
|
43
|
+
resetDragState()
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function handleDragOver(groupName: string, event: DragEvent) {
|
|
47
|
+
// Only accept this drop target when a sample is being dragged; group drags are handled separately.
|
|
48
|
+
if (!draggingSample.value) return
|
|
49
|
+
event.preventDefault()
|
|
50
|
+
if (event.dataTransfer) {
|
|
51
|
+
event.dataTransfer.dropEffect = 'move'
|
|
52
|
+
}
|
|
53
|
+
dragOverGroup.value = groupName
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function handleDragLeave() {
|
|
57
|
+
dragOverGroup.value = null
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function handleDrop(targetGroupName: string, event: DragEvent) {
|
|
61
|
+
if (!draggingSample.value) return
|
|
62
|
+
event.preventDefault()
|
|
63
|
+
|
|
64
|
+
const sample = draggingSample.value
|
|
65
|
+
const sourceGroup = dragSourceGroup.value
|
|
66
|
+
|
|
67
|
+
if (sourceGroup === targetGroupName) {
|
|
68
|
+
resetDragState()
|
|
69
|
+
return
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
groups.value = moveSampleToGroup(groups.value, sample, sourceGroup, targetGroupName)
|
|
73
|
+
resetDragState()
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function handleGroupDragStart(name: string, kind: GroupDragKind, event: DragEvent) {
|
|
77
|
+
draggingGroup.value = name
|
|
78
|
+
draggingGroupKind.value = kind
|
|
79
|
+
if (event.dataTransfer) {
|
|
80
|
+
event.dataTransfer.effectAllowed = 'move'
|
|
81
|
+
event.dataTransfer.setData('text/plain', `mint-group:${name}`)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function handleGroupDragEnd() {
|
|
86
|
+
draggingGroup.value = null
|
|
87
|
+
draggingGroupKind.value = null
|
|
88
|
+
reorderTarget.value = null
|
|
89
|
+
reorderPosition.value = null
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function handleGroupDragOver(name: string, kind: GroupDragKind, event: DragEvent) {
|
|
93
|
+
if (!draggingGroup.value || draggingGroupKind.value !== kind) return
|
|
94
|
+
if (draggingGroup.value === name) return
|
|
95
|
+
|
|
96
|
+
// Sub-group reorder is restricted to siblings under the same major prefix;
|
|
97
|
+
// crossing majors would silently rename the group, which is too magical.
|
|
98
|
+
if (kind === 'sub') {
|
|
99
|
+
const separator = detectSampleGroupSeparator(groups.value)
|
|
100
|
+
if (
|
|
101
|
+
getSampleGroupMajorPrefix(draggingGroup.value, separator) !==
|
|
102
|
+
getSampleGroupMajorPrefix(name, separator)
|
|
103
|
+
) return
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
event.preventDefault()
|
|
107
|
+
if (event.dataTransfer) event.dataTransfer.dropEffect = 'move'
|
|
108
|
+
|
|
109
|
+
const rect = (event.currentTarget as HTMLElement).getBoundingClientRect()
|
|
110
|
+
reorderTarget.value = name
|
|
111
|
+
reorderPosition.value = event.clientY < rect.top + rect.height / 2 ? 'before' : 'after'
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function handleGroupDragLeave(event: DragEvent) {
|
|
115
|
+
const cur = event.currentTarget as HTMLElement
|
|
116
|
+
const rel = event.relatedTarget as Node | null
|
|
117
|
+
if (rel && cur.contains(rel)) return
|
|
118
|
+
reorderTarget.value = null
|
|
119
|
+
reorderPosition.value = null
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function handleGroupDrop(name: string, kind: GroupDragKind, event: DragEvent) {
|
|
123
|
+
if (!draggingGroup.value || draggingGroupKind.value !== kind) {
|
|
124
|
+
handleGroupDragEnd()
|
|
125
|
+
return
|
|
126
|
+
}
|
|
127
|
+
const position = reorderPosition.value
|
|
128
|
+
if (!position || draggingGroup.value === name) {
|
|
129
|
+
handleGroupDragEnd()
|
|
130
|
+
return
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
event.preventDefault()
|
|
134
|
+
|
|
135
|
+
if (kind === 'major') {
|
|
136
|
+
const nextGroups = reorderSampleMajorGroup(groups.value, draggingGroup.value, name, position)
|
|
137
|
+
if (nextGroups !== groups.value) groups.value = nextGroups
|
|
138
|
+
} else {
|
|
139
|
+
const nextGroups = reorderSampleGroup(groups.value, draggingGroup.value, name, position)
|
|
140
|
+
if (nextGroups !== groups.value) groups.value = nextGroups
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
handleGroupDragEnd()
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return {
|
|
147
|
+
draggingSample,
|
|
148
|
+
dragOverGroup,
|
|
149
|
+
draggingGroup,
|
|
150
|
+
draggingGroupKind,
|
|
151
|
+
reorderTarget,
|
|
152
|
+
reorderPosition,
|
|
153
|
+
handleDragStart,
|
|
154
|
+
handleDragEnd,
|
|
155
|
+
handleDragOver,
|
|
156
|
+
handleDragLeave,
|
|
157
|
+
handleDrop,
|
|
158
|
+
handleGroupDragStart,
|
|
159
|
+
handleGroupDragEnd,
|
|
160
|
+
handleGroupDragOver,
|
|
161
|
+
handleGroupDragLeave,
|
|
162
|
+
handleGroupDrop,
|
|
163
|
+
}
|
|
164
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import type { SampleGroup } from '../types'
|
|
2
|
+
|
|
3
|
+
export type GroupDragKind = 'major' | 'sub' | 'flat'
|
|
4
|
+
export type GroupReorderPosition = 'before' | 'after'
|
|
5
|
+
|
|
6
|
+
export function detectSampleGroupSeparator(groups: SampleGroup[]): string {
|
|
7
|
+
return groups.some(group => group.name.includes('/')) ? '/' : '_'
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function getSampleGroupMajorPrefix(groupName: string, separator: string): string {
|
|
11
|
+
const parts = groupName.split(separator)
|
|
12
|
+
return parts.length > 1 ? parts[0] : groupName
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function moveSampleToGroup(
|
|
16
|
+
groups: SampleGroup[],
|
|
17
|
+
sample: string,
|
|
18
|
+
sourceGroup: string | null,
|
|
19
|
+
targetGroup: string,
|
|
20
|
+
): SampleGroup[] {
|
|
21
|
+
if (sourceGroup === targetGroup) return groups
|
|
22
|
+
|
|
23
|
+
return groups.map(group => {
|
|
24
|
+
if (sourceGroup && group.name === sourceGroup) {
|
|
25
|
+
return { ...group, samples: group.samples.filter(item => item !== sample) }
|
|
26
|
+
}
|
|
27
|
+
if (group.name === targetGroup && !group.samples.includes(sample)) {
|
|
28
|
+
return { ...group, samples: [...group.samples, sample] }
|
|
29
|
+
}
|
|
30
|
+
return group
|
|
31
|
+
})
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function removeSampleGroup(groups: SampleGroup[], groupName: string): SampleGroup[] {
|
|
35
|
+
return groups.filter(group => group.name !== groupName)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function removeSampleMajorGroup(
|
|
39
|
+
groups: SampleGroup[],
|
|
40
|
+
majorGroup: { subGroups: Array<{ name: string }> },
|
|
41
|
+
): SampleGroup[] {
|
|
42
|
+
const groupNames = new Set(majorGroup.subGroups.map(group => group.name))
|
|
43
|
+
return groups.filter(group => !groupNames.has(group.name))
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function removeSampleFromGroup(
|
|
47
|
+
groups: SampleGroup[],
|
|
48
|
+
sample: string,
|
|
49
|
+
groupName: string,
|
|
50
|
+
): SampleGroup[] {
|
|
51
|
+
return groups.map(group =>
|
|
52
|
+
group.name === groupName
|
|
53
|
+
? { ...group, samples: group.samples.filter(item => item !== sample) }
|
|
54
|
+
: group,
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function reorderSampleGroup(
|
|
59
|
+
groups: SampleGroup[],
|
|
60
|
+
source: string,
|
|
61
|
+
target: string,
|
|
62
|
+
position: GroupReorderPosition,
|
|
63
|
+
): SampleGroup[] {
|
|
64
|
+
if (source === target) return groups
|
|
65
|
+
|
|
66
|
+
const nextGroups = [...groups]
|
|
67
|
+
const sourceIndex = nextGroups.findIndex(group => group.name === source)
|
|
68
|
+
if (sourceIndex === -1) return groups
|
|
69
|
+
|
|
70
|
+
const [item] = nextGroups.splice(sourceIndex, 1)
|
|
71
|
+
const targetIndex = nextGroups.findIndex(group => group.name === target)
|
|
72
|
+
if (targetIndex === -1) return groups
|
|
73
|
+
|
|
74
|
+
nextGroups.splice(position === 'before' ? targetIndex : targetIndex + 1, 0, item)
|
|
75
|
+
return nextGroups
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function reorderSampleMajorGroup(
|
|
79
|
+
groups: SampleGroup[],
|
|
80
|
+
source: string,
|
|
81
|
+
target: string,
|
|
82
|
+
position: GroupReorderPosition,
|
|
83
|
+
): SampleGroup[] {
|
|
84
|
+
if (source === target) return groups
|
|
85
|
+
|
|
86
|
+
const separator = detectSampleGroupSeparator(groups)
|
|
87
|
+
const isSource = (group: SampleGroup) => getSampleGroupMajorPrefix(group.name, separator) === source
|
|
88
|
+
const isTarget = (group: SampleGroup) => getSampleGroupMajorPrefix(group.name, separator) === target
|
|
89
|
+
|
|
90
|
+
const sourceGroups = groups.filter(isSource)
|
|
91
|
+
if (sourceGroups.length === 0) return groups
|
|
92
|
+
|
|
93
|
+
const remainingGroups = groups.filter(group => !isSource(group))
|
|
94
|
+
let firstTargetIndex = -1
|
|
95
|
+
let lastTargetIndex = -1
|
|
96
|
+
|
|
97
|
+
remainingGroups.forEach((group, index) => {
|
|
98
|
+
if (isTarget(group)) {
|
|
99
|
+
if (firstTargetIndex === -1) firstTargetIndex = index
|
|
100
|
+
lastTargetIndex = index
|
|
101
|
+
}
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
if (firstTargetIndex === -1) return groups
|
|
105
|
+
|
|
106
|
+
const insertIndex = position === 'before' ? firstTargetIndex : lastTargetIndex + 1
|
|
107
|
+
remainingGroups.splice(insertIndex, 0, ...sourceGroups)
|
|
108
|
+
return remainingGroups
|
|
109
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import type { ComputedRef } from 'vue'
|
|
2
|
+
import { useListSelection } from '../composables/useListSelection'
|
|
3
|
+
import type { SampleMajorGroup } from '../composables/useSampleGroups'
|
|
4
|
+
|
|
5
|
+
interface SampleGroupSelectionSource {
|
|
6
|
+
samples: string[]
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface UseSampleSelectorSelectionOptions {
|
|
10
|
+
selected: () => string[]
|
|
11
|
+
samples: () => string[]
|
|
12
|
+
findGroup: (groupName: string) => SampleGroupSelectionSource | undefined
|
|
13
|
+
emitSelected: (samples: string[]) => void
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface UseSampleSelectorSelectionReturn {
|
|
17
|
+
isAllSelected: ComputedRef<boolean>
|
|
18
|
+
toggleSelectAll: () => void
|
|
19
|
+
toggleSample: (sample: string) => void
|
|
20
|
+
toggleGroupSamples: (groupName: string) => void
|
|
21
|
+
toggleMajorGroupSamples: (majorGroup: SampleMajorGroup) => void
|
|
22
|
+
isFullySelected: (samples: string[]) => boolean
|
|
23
|
+
isPartiallySelected: (samples: string[]) => boolean
|
|
24
|
+
isGroupFullySelected: (groupName: string) => boolean
|
|
25
|
+
isGroupPartiallySelected: (groupName: string) => boolean
|
|
26
|
+
isMajorGroupFullySelected: (majorGroup: SampleMajorGroup) => boolean
|
|
27
|
+
isMajorGroupPartiallySelected: (majorGroup: SampleMajorGroup) => boolean
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function useSampleSelectorSelection(
|
|
31
|
+
options: UseSampleSelectorSelectionOptions,
|
|
32
|
+
): UseSampleSelectorSelectionReturn {
|
|
33
|
+
const sampleSelection = useListSelection({
|
|
34
|
+
selected: options.selected,
|
|
35
|
+
items: options.samples,
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
function emitSelection(samples: string[]) {
|
|
39
|
+
options.emitSelected(samples)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function toggleSelectAll() {
|
|
43
|
+
emitSelection(sampleSelection.toggleAll())
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function toggleSample(sample: string) {
|
|
47
|
+
emitSelection(sampleSelection.toggleValue(sample))
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function toggleSamplesSelection(samples: string[]) {
|
|
51
|
+
emitSelection(sampleSelection.toggleValues(samples))
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function toggleGroupSamples(groupName: string) {
|
|
55
|
+
const group = options.findGroup(groupName)
|
|
56
|
+
if (!group) return
|
|
57
|
+
toggleSamplesSelection(group.samples)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function toggleMajorGroupSamples(majorGroup: SampleMajorGroup) {
|
|
61
|
+
toggleSamplesSelection(majorGroup.allSamples)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function isFullySelected(samples: string[]): boolean {
|
|
65
|
+
return sampleSelection.isFullySelected(samples)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function isPartiallySelected(samples: string[]): boolean {
|
|
69
|
+
return sampleSelection.isPartiallySelected(samples)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function isGroupFullySelected(groupName: string): boolean {
|
|
73
|
+
const group = options.findGroup(groupName)
|
|
74
|
+
return group ? isFullySelected(group.samples) : false
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function isGroupPartiallySelected(groupName: string): boolean {
|
|
78
|
+
const group = options.findGroup(groupName)
|
|
79
|
+
return group ? isPartiallySelected(group.samples) : false
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function isMajorGroupFullySelected(majorGroup: SampleMajorGroup): boolean {
|
|
83
|
+
return isFullySelected(majorGroup.allSamples)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function isMajorGroupPartiallySelected(majorGroup: SampleMajorGroup): boolean {
|
|
87
|
+
return isPartiallySelected(majorGroup.allSamples)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return {
|
|
91
|
+
isAllSelected: sampleSelection.isAllSelected,
|
|
92
|
+
toggleSelectAll,
|
|
93
|
+
toggleSample,
|
|
94
|
+
toggleGroupSamples,
|
|
95
|
+
toggleMajorGroupSamples,
|
|
96
|
+
isFullySelected,
|
|
97
|
+
isPartiallySelected,
|
|
98
|
+
isGroupFullySelected,
|
|
99
|
+
isGroupPartiallySelected,
|
|
100
|
+
isMajorGroupFullySelected,
|
|
101
|
+
isMajorGroupPartiallySelected,
|
|
102
|
+
}
|
|
103
|
+
}
|