@morscherlab/mint-sdk 1.4.0-beta.7 → 1.4.0-beta.9
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/{ActionMenu-CScINahU.js → AlertBox-B2Bgr3ei.js} +40 -209
- package/dist/AlertBox-B2Bgr3ei.js.map +1 -0
- package/dist/{AppSidebar-BmiiPfz9.js → AppSidebar-Dq9W1jE2.js} +160 -109
- package/dist/AppSidebar-Dq9W1jE2.js.map +1 -0
- package/dist/{ConfirmDialog-CJ7hqYUP.js → ConfirmDialog-nbJj51is.js} +2 -2
- package/dist/{ConfirmDialog-CJ7hqYUP.js.map → ConfirmDialog-nbJj51is.js.map} +1 -1
- package/dist/ExperimentPopover-5T1fAq2L.js +337 -0
- package/dist/ExperimentPopover-5T1fAq2L.js.map +1 -0
- package/dist/{ExperimentSelectorModal-D-9z7cNx.js → ExperimentSelectorModal-65peG4Up.js} +198 -181
- package/dist/ExperimentSelectorModal-65peG4Up.js.map +1 -0
- package/dist/{SegmentedControl-DERBN-Xd.js → SegmentedControl-BtnnjWzs.js} +2 -2
- package/dist/{SegmentedControl-DERBN-Xd.js.map → SegmentedControl-BtnnjWzs.js.map} +1 -1
- package/dist/{SettingsModal-CSLE31yg.js → SettingsModal-483nyI6b.js} +9 -9
- package/dist/SettingsModal-483nyI6b.js.map +1 -0
- package/dist/components/AppSidebar.vue.d.ts +1 -1
- package/dist/components/ArtifactSaveDialog.vue.d.ts +9 -1
- package/dist/components/AuditTrail.vue.d.ts +1 -1
- package/dist/components/BaseSelect.vue.d.ts +2 -2
- package/dist/components/ChartContainer.vue.d.ts +2 -0
- package/dist/components/DatePicker.vue.d.ts +1 -1
- package/dist/components/ExperimentPopover.vue.d.ts +18 -0
- package/dist/components/ExperimentSelectorModal.vue.d.ts +0 -4
- package/dist/components/FilePicker.vue.d.ts +1 -1
- package/dist/components/FileUploader.vue.d.ts +2 -2
- package/dist/components/PluginIcon.vue.d.ts +2 -2
- package/dist/components/SampleSelector.vue.d.ts +6 -6
- package/dist/components/SequenceProgressBar.vue.d.ts +3 -0
- package/dist/components/StepWizard.vue.d.ts +3 -0
- package/dist/components/internal/AutoGroupModalInternal.vue.d.ts +1 -1
- package/dist/components/internal/DatePickerTimeInternal.vue.d.ts +1 -1
- package/dist/components/internal/ResourcePickerListInternal.vue.d.ts +2 -7
- package/dist/components/internal/SelectMultipleInternal.vue.d.ts +4 -0
- package/dist/composables/createClient.d.ts +2 -0
- package/dist/composables/index.d.ts +1 -0
- package/dist/composables/pluginIdentity.d.ts +24 -0
- package/dist/composables/useAppExperiment.d.ts +8 -0
- package/dist/composables/useCalendarGrid.d.ts +1 -1
- package/dist/composables/useExperimentSelector.d.ts +6 -2
- package/dist/composables/usePlatform.d.ts +1 -0
- package/dist/{controlSchemaModel-CP5-_nAj.js → controlSchemaModel-B8CTXagP.js} +2 -2
- package/dist/{controlSchemaModel-CP5-_nAj.js.map → controlSchemaModel-B8CTXagP.js.map} +1 -1
- package/dist/{data-C2PwI_dn.js → data-CgILxDLW.js} +178 -124
- package/dist/data-CgILxDLW.js.map +1 -0
- package/dist/data.js +8 -8
- package/dist/{experimentStatus-BZmU4czV.js → experimentStatus-Cqp6qNrR.js} +3 -3
- package/dist/{experimentStatus-BZmU4czV.js.map → experimentStatus-Cqp6qNrR.js.map} +1 -1
- package/dist/index.js +19 -19
- package/dist/{install-DAID6c2-.js → install-BtLWTk6H.js} +15 -14
- package/dist/{install-DAID6c2-.js.map → install-BtLWTk6H.js.map} +1 -1
- package/dist/install.js +1 -1
- package/dist/{lab-DLwRl_Ql.js → lab-MHzp-_J8.js} +128 -147
- package/dist/lab-MHzp-_J8.js.map +1 -0
- package/dist/lab.js +4 -3
- package/dist/{records-BzTcxekG.js → records-B6gpM_3e.js} +472 -274
- package/dist/records-B6gpM_3e.js.map +1 -0
- package/dist/{runtime-D6gVat6r.js → runtime-7vfl_bI3.js} +27 -31
- package/dist/runtime-7vfl_bI3.js.map +1 -0
- package/dist/runtime.js +6 -6
- package/dist/{shell-5ju97nOS.js → shell-Cs9OJMnm.js} +5 -5
- package/dist/{shell-5ju97nOS.js.map → shell-Cs9OJMnm.js.map} +1 -1
- package/dist/shell.js +5 -5
- package/dist/styles.css +1606 -1666
- package/dist/types/componentWorkflowTypes.d.ts +2 -0
- package/dist/types/generated/platformContext.d.ts +1 -0
- package/dist/types/generated-ui.d.ts +4 -0
- package/dist/{BaseModal-DfRIuVoj.js → useDropdownState-8yWMu-7_.js} +60 -2
- package/dist/useDropdownState-8yWMu-7_.js.map +1 -0
- package/dist/{useExperimentSamples-CxcnxZ8h.js → useExperimentSamples-DHnxKFAF.js} +3 -3
- package/dist/{useExperimentSamples-CxcnxZ8h.js.map → useExperimentSamples-DHnxKFAF.js.map} +1 -1
- package/dist/{useListReorder-CcbEYxX-.js → useListReorder-BitdUhxn.js} +109 -277
- package/dist/useListReorder-BitdUhxn.js.map +1 -0
- package/dist/{useRackEditor-BD5NIo5s.js → useRackEditor-DiwCt77M.js} +71 -57
- package/dist/useRackEditor-DiwCt77M.js.map +1 -0
- package/dist/{useRealtime-PalKue84.js → useRealtime-C3iy9QkU.js} +7 -4
- package/dist/useRealtime-C3iy9QkU.js.map +1 -0
- package/dist/useRequest-D506eHi8.js +244 -0
- package/dist/useRequest-D506eHi8.js.map +1 -0
- package/dist/utils/time.d.ts +7 -0
- package/package.json +1 -1
- package/src/__tests__/components/AppTopBar.test.ts +51 -2
- package/src/__tests__/components/AppTopBarPillNav.test.ts +35 -0
- package/src/__tests__/components/ArtifactSaveDialog.test.ts +78 -0
- package/src/__tests__/components/BaseSelect.multiple.test.ts +87 -32
- package/src/__tests__/components/BaseSelect.test.ts +2 -1
- package/src/__tests__/components/BatchProgressList.test.ts +16 -0
- package/src/__tests__/components/CalendarGridPanel.test.ts +2 -2
- package/src/__tests__/components/ChartContainer.test.ts +11 -0
- package/src/__tests__/components/ChemicalFormula.test.ts +6 -3
- package/src/__tests__/components/DatePicker.datetime.test.ts +6 -0
- package/src/__tests__/components/DatePicker.test.ts +21 -0
- package/src/__tests__/components/DatePicker.time.test.ts +2 -2
- package/src/__tests__/components/EmptyState.test.ts +1 -1
- package/src/__tests__/components/ExperimentPopover.test.ts +125 -16
- package/src/__tests__/components/ExperimentSelectorModal.test.ts +119 -13
- package/src/__tests__/components/GeneratedPluginView.test.ts +22 -1
- package/src/__tests__/components/InstrumentStateBadge.test.ts +4 -4
- package/src/__tests__/components/ResourcePickerListInternal.test.ts +0 -20
- package/src/__tests__/components/SampleSelector.test.ts +13 -8
- package/src/__tests__/components/SequenceProgressBar.test.ts +12 -0
- package/src/__tests__/components/StepWizard.test.ts +11 -0
- package/src/__tests__/components/WellPlate.decoration.test.ts +11 -4
- package/src/__tests__/components/deprecationTags.test.ts +1 -1
- package/src/__tests__/composables/useAppExperiment.test.ts +27 -1
- package/src/__tests__/composables/useCalendarGrid.test.ts +4 -2
- package/src/__tests__/composables/useExperimentSelector.test.ts +111 -0
- package/src/__tests__/styles/baseControlsRules.test.ts +6 -2
- package/src/__tests__/styles/controlRefreshRules.test.ts +0 -6
- package/src/__tests__/styles/cssTokens.test.ts +2 -2
- package/src/__tests__/styles/menusShellRefresh.test.ts +14 -10
- package/src/__tests__/utils/plotlyTemplate.test.ts +4 -4
- package/src/__tests__/utils/time.test.ts +18 -1
- package/src/components/AdductText.story.vue +7 -0
- package/src/components/AdductText.vue +1 -1
- package/src/components/AlertBox.story.vue +2 -2
- package/src/components/AlertBox.vue +18 -16
- package/src/components/AppSidebar.story.vue +0 -28
- package/src/components/AppTopBar.story.vue +47 -12
- package/src/components/AppTopBar.vue +118 -114
- package/src/components/ArtifactSaveDialog.story.vue +23 -0
- package/src/components/ArtifactSaveDialog.vue +102 -12
- package/src/components/AuditTrail.story.vue +2 -1
- package/src/components/AuditTrail.vue +2 -21
- package/src/components/Avatar.vue +10 -14
- package/src/components/BaseSelect.multiple.story.vue +13 -2
- package/src/components/BaseSelect.vue +4 -3
- package/src/components/BatchProgressList.vue +35 -25
- package/src/components/ChartContainer.story.vue +2 -1
- package/src/components/ChartContainer.vue +8 -6
- package/src/components/ConfirmDialog.story.vue +1 -1
- package/src/components/EmptyState.vue +1 -1
- package/src/components/ExperimentPopover.story.vue +165 -53
- package/src/components/ExperimentPopover.vue +169 -187
- package/src/components/ExperimentSelectorModal.story.vue +40 -36
- package/src/components/ExperimentSelectorModal.vue +124 -110
- package/src/components/FormField.story.vue +8 -48
- package/src/components/GeneratedPluginView.vue +7 -1
- package/src/components/InstrumentStateBadge.vue +1 -1
- package/src/components/JobsStatusTray.vue +1 -1
- package/src/components/LoadingSpinner.vue +1 -1
- package/src/components/NumberInput.vue +3 -6
- package/src/components/PluginIcon.story.vue +2 -10
- package/src/components/PluginIcon.vue +2 -2
- package/src/components/PluginWorkspaceView.story.vue +1 -1
- package/src/components/RuntimeUpdateNotice.vue +1 -1
- package/src/components/SampleSelector.story.vue +1 -1
- package/src/components/SampleSelector.vue +27 -37
- package/src/components/SampleSelectorGroupNode.vue +1 -1
- package/src/components/SectionCard.story.vue +2 -2
- package/src/components/SequenceProgressBar.story.vue +9 -0
- package/src/components/SequenceProgressBar.vue +6 -1
- package/src/components/SettingsModal.schema.ts +1 -1
- package/src/components/SettingsModal.vue +2 -2
- package/src/components/SmartGroupFieldRecipe.story.vue +1 -1
- package/src/components/SmartGroupManual.story.vue +1 -1
- package/src/components/StepWizard.story.vue +33 -0
- package/src/components/StepWizard.vue +8 -1
- package/src/components/WellPlate.story.vue +3 -1
- package/src/components/WellPlate.vue +7 -0
- package/src/components/internal/AppTopBarPillNavInternal.vue +33 -2
- package/src/components/internal/DatePickerDateInternal.vue +16 -40
- package/src/components/internal/DatePickerDateTimeInternal.vue +3 -13
- package/src/components/internal/DatePickerTimeInternal.vue +5 -8
- package/src/components/internal/ResourcePickerListInternal.vue +45 -85
- package/src/components/internal/SelectMultipleInternal.vue +182 -65
- package/src/components/internal/SelectSearchableInternal.vue +2 -3
- package/src/composables/createClient.ts +2 -0
- package/src/composables/index.ts +1 -0
- package/src/composables/pluginIdentity.ts +31 -0
- package/src/composables/useAppExperiment.ts +20 -0
- package/src/composables/useCalendarGrid.ts +4 -3
- package/src/composables/useExperimentSelector.ts +77 -31
- package/src/styles/components/adduct-text.css +13 -5
- package/src/styles/components/alert-box.css +39 -58
- package/src/styles/components/app-layout.css +6 -5
- package/src/styles/components/app-page-selector.css +3 -1
- package/src/styles/components/app-pill-nav.css +11 -12
- package/src/styles/components/app-sidebar.css +9 -18
- package/src/styles/components/app-top-bar.css +57 -55
- package/src/styles/components/artifact-save-dialog.css +153 -2
- package/src/styles/components/audit-trail.css +16 -19
- package/src/styles/components/avatar.css +6 -4
- package/src/styles/components/batch-progress-list.css +38 -36
- package/src/styles/components/button.css +28 -59
- package/src/styles/components/calendar.css +12 -12
- package/src/styles/components/chart-container.css +34 -23
- package/src/styles/components/checkbox.css +2 -12
- package/src/styles/components/collapsible-card.css +27 -29
- package/src/styles/components/confirm-dialog.css +13 -14
- package/src/styles/components/dataframe.css +12 -4
- package/src/styles/components/date-picker.css +80 -92
- package/src/styles/components/datetime-picker.css +31 -43
- package/src/styles/components/divider.css +20 -20
- package/src/styles/components/dose-calculator.css +3 -3
- package/src/styles/components/empty-state.css +20 -17
- package/src/styles/components/experiment-code-badge.css +2 -0
- package/src/styles/components/experiment-popover.css +174 -329
- package/src/styles/components/experiment-selector-modal.css +75 -56
- package/src/styles/components/file-picker.css +3 -3
- package/src/styles/components/file-uploader.css +38 -49
- package/src/styles/components/form-builder.css +3 -3
- package/src/styles/components/formula-input.css +1 -1
- package/src/styles/components/icon-button.css +18 -24
- package/src/styles/components/input.css +5 -4
- package/src/styles/components/instrument-monitor.css +13 -15
- package/src/styles/components/jobs-status-tray.css +31 -25
- package/src/styles/components/modal.css +2 -4
- package/src/styles/components/molecule-input.css +2 -2
- package/src/styles/components/multi-select.css +65 -117
- package/src/styles/components/number-input.css +26 -19
- package/src/styles/components/pill.css +3 -2
- package/src/styles/components/plate-editor.css +0 -1
- package/src/styles/components/plugin-icon.css +26 -23
- package/src/styles/components/popover.css +2 -2
- package/src/styles/components/presence-avatars.css +1 -1
- package/src/styles/components/protocol-step-editor.css +1 -3
- package/src/styles/components/resource-card.css +2 -2
- package/src/styles/components/resource-picker-list.css +6 -57
- package/src/styles/components/sample-hierarchy-tree.css +4 -4
- package/src/styles/components/sample-selector.css +95 -79
- package/src/styles/components/schedule-calendar.css +8 -8
- package/src/styles/components/searchable-select.css +12 -12
- package/src/styles/components/section-card.css +28 -47
- package/src/styles/components/segmented-control.css +18 -15
- package/src/styles/components/select.css +3 -3
- package/src/styles/components/sequence-input.css +2 -2
- package/src/styles/components/sequence-progress-bar.css +17 -8
- package/src/styles/components/smart-group.css +18 -18
- package/src/styles/components/step-wizard.css +52 -16
- package/src/styles/components/tabs.css +2 -2
- package/src/styles/components/textarea.css +3 -3
- package/src/styles/components/time-picker.css +36 -21
- package/src/styles/components/toast.css +12 -10
- package/src/styles/components/toggle.css +1 -11
- package/src/styles/components/tooltip.css +10 -9
- package/src/styles/components/unit-input.css +8 -7
- package/src/styles/components/well-plate.css +9 -2
- package/src/styles/variables.css +106 -75
- package/src/types/componentWorkflowTypes.ts +2 -0
- package/src/types/generated/platformContext.ts +1 -0
- package/src/types/generated-ui.ts +4 -0
- package/src/utils/time.ts +21 -0
- package/dist/ActionMenu-CScINahU.js.map +0 -1
- package/dist/AppSidebar-BmiiPfz9.js.map +0 -1
- package/dist/BaseModal-DfRIuVoj.js.map +0 -1
- package/dist/ExperimentPopover-C4sGw-is.js +0 -359
- package/dist/ExperimentPopover-C4sGw-is.js.map +0 -1
- package/dist/ExperimentSelectorModal-D-9z7cNx.js.map +0 -1
- package/dist/SettingsModal-CSLE31yg.js.map +0 -1
- package/dist/data-C2PwI_dn.js.map +0 -1
- package/dist/lab-DLwRl_Ql.js.map +0 -1
- package/dist/records-BzTcxekG.js.map +0 -1
- package/dist/runtime-D6gVat6r.js.map +0 -1
- package/dist/useListReorder-CcbEYxX-.js.map +0 -1
- package/dist/useRackEditor-BD5NIo5s.js.map +0 -1
- package/dist/useRealtime-PalKue84.js.map +0 -1
- package/dist/useRequest-D5JDfsgZ.js +0 -76
- package/dist/useRequest-D5JDfsgZ.js.map +0 -1
|
@@ -7,18 +7,15 @@
|
|
|
7
7
|
* <ExperimentSelectorModal v-model:open="open" :allowed-experiment-types="['mass-spectrometry']" />
|
|
8
8
|
* ```
|
|
9
9
|
*/
|
|
10
|
-
import { ref, computed, watch } from 'vue'
|
|
11
|
-
import
|
|
10
|
+
import { ref, computed, watch, type Component } from 'vue'
|
|
11
|
+
import { ChevronDown, CircleDot, Folder, Shapes, User } from 'lucide-vue-next'
|
|
12
|
+
import type { ModalSize, ExperimentSummary, ExperimentFilters, ActionMenuItem, Tone } from '../types'
|
|
12
13
|
import { useExperimentSelector } from '../composables/useExperimentSelector'
|
|
13
14
|
import { useExperimentStore } from '../stores/experiment'
|
|
14
|
-
import {
|
|
15
|
-
formatExperimentDate,
|
|
16
|
-
DATE_PRESET_OPTIONS,
|
|
17
|
-
SORT_OPTIONS,
|
|
18
|
-
} from '../composables/experiment-utils'
|
|
15
|
+
import { formatExperimentDate } from '../composables/experiment-utils'
|
|
19
16
|
import * as experimentStatus from '../utils/experimentStatus'
|
|
20
17
|
import BaseModal from './BaseModal.vue'
|
|
21
|
-
import
|
|
18
|
+
import ActionMenu from './ActionMenu.vue'
|
|
22
19
|
import ResourcePickerListInternal from './internal/ResourcePickerListInternal.vue'
|
|
23
20
|
|
|
24
21
|
interface Props {
|
|
@@ -28,16 +25,12 @@ interface Props {
|
|
|
28
25
|
currentExperimentId?: number | null
|
|
29
26
|
title?: string
|
|
30
27
|
size?: ModalSize
|
|
31
|
-
groupByProject?: boolean
|
|
32
|
-
showFilters?: boolean
|
|
33
28
|
}
|
|
34
29
|
|
|
35
30
|
const props = withDefaults(defineProps<Props>(), {
|
|
36
31
|
currentExperimentId: null,
|
|
37
32
|
title: 'Select Experiment',
|
|
38
|
-
size: '
|
|
39
|
-
groupByProject: false,
|
|
40
|
-
showFilters: false,
|
|
33
|
+
size: 'lg',
|
|
41
34
|
})
|
|
42
35
|
|
|
43
36
|
// Selection is committed to the shared experiment store rather than emitted.
|
|
@@ -54,55 +47,102 @@ const {
|
|
|
54
47
|
filters,
|
|
55
48
|
isLoading,
|
|
56
49
|
error,
|
|
57
|
-
sortKey,
|
|
58
50
|
experimentTypes,
|
|
59
51
|
projects,
|
|
60
|
-
|
|
52
|
+
statusCounts,
|
|
61
53
|
fetch: fetchExperiments,
|
|
62
54
|
fetchFilterOptions,
|
|
55
|
+
fetchStatusCounts,
|
|
63
56
|
} = useExperimentSelector({
|
|
64
57
|
experimentType: props.experimentType,
|
|
65
58
|
allowedExperimentTypes: props.allowedExperimentTypes,
|
|
59
|
+
withStatusCounts: true,
|
|
66
60
|
})
|
|
67
61
|
|
|
68
|
-
|
|
69
|
-
const groupToggle = ref(props.groupByProject)
|
|
70
|
-
// Re-mounting the list on open clears its collapsed groups and keyboard highlight.
|
|
62
|
+
// Re-mounting the list on open clears its keyboard highlight.
|
|
71
63
|
const openCount = ref(0)
|
|
72
64
|
|
|
73
|
-
|
|
74
|
-
const hasActiveAdvancedFilters = computed(() =>
|
|
75
|
-
!!(filters.project || filters.experimentType || filters.datePreset || sortKey.value !== 'created_at:desc'),
|
|
76
|
-
)
|
|
65
|
+
const STATUS_ORDER = ['ongoing', 'planned', 'completed', 'cancelled'] as const
|
|
77
66
|
|
|
78
|
-
// Build type filter options from fetched experiment types
|
|
79
|
-
const typeFilterOptions = computed(() => [
|
|
80
|
-
{ value: '', label: 'All types' },
|
|
81
|
-
...experimentTypes.value.map(t => ({ value: t.value, label: t.label })),
|
|
82
|
-
])
|
|
83
67
|
const canChooseExperimentType = computed(() =>
|
|
84
|
-
!props.experimentType &&
|
|
68
|
+
!props.experimentType && experimentTypes.value.length > 1,
|
|
85
69
|
)
|
|
86
70
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
71
|
+
type FilterKey = 'status' | 'project' | 'experimentType'
|
|
72
|
+
|
|
73
|
+
interface FilterMenu {
|
|
74
|
+
key: FilterKey
|
|
75
|
+
label: string
|
|
76
|
+
icon: Component
|
|
77
|
+
items: ActionMenuItem[]
|
|
78
|
+
/** Trigger text while the filter is set. */
|
|
79
|
+
activeLabel?: string
|
|
80
|
+
dotTone?: Tone
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** Every item carries `checked`, so ActionMenu renders a single-choice menu. */
|
|
84
|
+
function choiceItems(key: FilterKey, anyLabel: string, options: { value: string; label: string }[]): ActionMenuItem[] {
|
|
85
|
+
const current = filters[key] ?? ''
|
|
86
|
+
return [{ value: '', label: anyLabel }, ...options].map(option => ({
|
|
87
|
+
id: option.value,
|
|
88
|
+
label: option.label,
|
|
89
|
+
checked: option.value === current,
|
|
90
|
+
}))
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const filterMenus = computed<FilterMenu[]>(() => {
|
|
94
|
+
const menus: FilterMenu[] = [{
|
|
95
|
+
key: 'status',
|
|
96
|
+
label: 'Status',
|
|
97
|
+
icon: CircleDot,
|
|
98
|
+
items: choiceItems('status', 'Any status', STATUS_ORDER.map(status => {
|
|
99
|
+
const count = statusCounts.value[status]
|
|
100
|
+
const label = experimentStatus.format(status)
|
|
101
|
+
return { value: status, label: count === undefined ? label : `${label} · ${count}` }
|
|
102
|
+
})),
|
|
103
|
+
activeLabel: filters.status ? experimentStatus.format(filters.status) : undefined,
|
|
104
|
+
dotTone: filters.status ? experimentStatus.tone(filters.status) : undefined,
|
|
105
|
+
}]
|
|
106
|
+
if (projects.value.length) {
|
|
107
|
+
menus.push({
|
|
108
|
+
key: 'project',
|
|
109
|
+
label: 'Project',
|
|
110
|
+
icon: Folder,
|
|
111
|
+
items: choiceItems('project', 'Any project', projects.value),
|
|
112
|
+
activeLabel: filters.project ?? undefined,
|
|
113
|
+
})
|
|
114
|
+
}
|
|
115
|
+
if (canChooseExperimentType.value) {
|
|
116
|
+
menus.push({
|
|
117
|
+
key: 'experimentType',
|
|
118
|
+
label: 'Type',
|
|
119
|
+
icon: Shapes,
|
|
120
|
+
items: choiceItems('experimentType', 'Any type', experimentTypes.value),
|
|
121
|
+
activeLabel: experimentTypes.value.find(t => t.value === filters.experimentType)?.label
|
|
122
|
+
?? filters.experimentType ?? undefined,
|
|
123
|
+
})
|
|
124
|
+
}
|
|
125
|
+
return menus
|
|
126
|
+
})
|
|
92
127
|
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
? groupedByProject.value.map(([label, items]) => ({ label, items }))
|
|
96
|
-
: null,
|
|
128
|
+
const activeFilterCount = computed(() =>
|
|
129
|
+
[filters.status, filters.project, filters.experimentType, filters.mine].filter(Boolean).length,
|
|
97
130
|
)
|
|
98
131
|
|
|
132
|
+
function clearFilters() {
|
|
133
|
+
filters.status = undefined
|
|
134
|
+
filters.project = undefined
|
|
135
|
+
filters.experimentType = undefined
|
|
136
|
+
filters.mine = undefined
|
|
137
|
+
}
|
|
138
|
+
|
|
99
139
|
function describe(experiment: ExperimentSummary) {
|
|
100
140
|
const owner = experiment.created_by_user
|
|
101
141
|
return {
|
|
102
142
|
code: experiment.experiment_code,
|
|
103
143
|
title: experiment.name,
|
|
104
144
|
meta: [
|
|
105
|
-
|
|
145
|
+
experiment.project_name || experiment.project || '',
|
|
106
146
|
owner ? [owner.first_name, owner.last_name].filter(Boolean).join(' ') || owner.username : '',
|
|
107
147
|
].filter(Boolean),
|
|
108
148
|
status: experiment.status
|
|
@@ -116,10 +156,6 @@ function setFilter<K extends keyof ExperimentFilters>(key: K, value: string | nu
|
|
|
116
156
|
;(filters as Record<string, unknown>)[key] = String(value) || undefined
|
|
117
157
|
}
|
|
118
158
|
|
|
119
|
-
function handleSortChange(value: string | number) {
|
|
120
|
-
sortKey.value = String(value) || 'created_at:desc'
|
|
121
|
-
}
|
|
122
|
-
|
|
123
159
|
function handleSelect(experiment: ExperimentSummary) {
|
|
124
160
|
experimentStore.select(experiment)
|
|
125
161
|
emit('update:open', false)
|
|
@@ -138,6 +174,7 @@ watch(
|
|
|
138
174
|
openCount.value++
|
|
139
175
|
fetchFilterOptions()
|
|
140
176
|
fetchExperiments()
|
|
177
|
+
fetchStatusCounts()
|
|
141
178
|
}
|
|
142
179
|
},
|
|
143
180
|
{ immediate: true },
|
|
@@ -155,10 +192,10 @@ watch(
|
|
|
155
192
|
:key="openCount"
|
|
156
193
|
:search="filters.search ?? ''"
|
|
157
194
|
class="mint-experiment-selector"
|
|
195
|
+
autofocus-search
|
|
158
196
|
label="Experiments"
|
|
159
197
|
placeholder="Search experiments…"
|
|
160
198
|
:items="experiments"
|
|
161
|
-
:groups="groups"
|
|
162
199
|
:item-key="(experiment) => experiment.id"
|
|
163
200
|
:describe="describe"
|
|
164
201
|
:selected-key="currentExperimentId"
|
|
@@ -169,77 +206,54 @@ watch(
|
|
|
169
206
|
@select="handleSelect"
|
|
170
207
|
>
|
|
171
208
|
<template #filters>
|
|
172
|
-
<
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
209
|
+
<ActionMenu
|
|
210
|
+
v-for="menu in filterMenus"
|
|
211
|
+
:key="menu.key"
|
|
212
|
+
:label="menu.label"
|
|
213
|
+
:items="menu.items"
|
|
214
|
+
@select="item => setFilter(menu.key, item.id)"
|
|
215
|
+
>
|
|
216
|
+
<template #trigger="{ open: menuOpen, toggle, keydown }">
|
|
217
|
+
<button
|
|
218
|
+
type="button"
|
|
219
|
+
class="mint-experiment-selector__toggle"
|
|
220
|
+
:class="{ 'mint-experiment-selector__toggle--active': menu.activeLabel }"
|
|
221
|
+
:aria-label="`${menu.label}: ${menu.activeLabel ?? menu.items[0].label}`"
|
|
222
|
+
aria-haspopup="menu"
|
|
223
|
+
:aria-expanded="menuOpen"
|
|
224
|
+
@click="toggle"
|
|
225
|
+
@keydown="keydown"
|
|
226
|
+
>
|
|
227
|
+
<span
|
|
228
|
+
v-if="menu.dotTone"
|
|
229
|
+
class="mint-experiment-selector__dot"
|
|
230
|
+
:class="`mint-experiment-selector__dot--${menu.dotTone}`"
|
|
231
|
+
aria-hidden="true"
|
|
232
|
+
/>
|
|
233
|
+
<component :is="menu.icon" v-else :size="13" aria-hidden="true" />
|
|
234
|
+
<span class="mint-experiment-selector__toggle-label">{{ menu.activeLabel ?? menu.label }}</span>
|
|
235
|
+
<ChevronDown :size="12" aria-hidden="true" />
|
|
236
|
+
</button>
|
|
237
|
+
</template>
|
|
238
|
+
</ActionMenu>
|
|
190
239
|
<button
|
|
191
|
-
class="mint-experiment-selector__filters-toggle"
|
|
192
|
-
:class="{ 'mint-experiment-selector__filters-toggle--active': hasActiveAdvancedFilters }"
|
|
193
240
|
type="button"
|
|
194
|
-
|
|
195
|
-
|
|
241
|
+
class="mint-experiment-selector__toggle"
|
|
242
|
+
:class="{ 'mint-experiment-selector__toggle--active': filters.mine }"
|
|
243
|
+
:aria-pressed="!!filters.mine"
|
|
244
|
+
@click="filters.mine = filters.mine ? undefined : true"
|
|
196
245
|
>
|
|
197
|
-
<
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
246
|
+
<User :size="13" aria-hidden="true" />
|
|
247
|
+
Mine
|
|
248
|
+
</button>
|
|
249
|
+
<button
|
|
250
|
+
v-if="activeFilterCount"
|
|
251
|
+
type="button"
|
|
252
|
+
class="mint-experiment-selector__clear-filters"
|
|
253
|
+
@click="clearFilters"
|
|
254
|
+
>
|
|
255
|
+
Clear {{ activeFilterCount }}
|
|
203
256
|
</button>
|
|
204
|
-
</template>
|
|
205
|
-
<template #advanced>
|
|
206
|
-
<div v-if="showAdvanced" class="mint-experiment-selector__filters-advanced">
|
|
207
|
-
<div v-if="projectFilterOptions.length > 1" class="mint-experiment-selector__filter-select">
|
|
208
|
-
<BaseSelect
|
|
209
|
-
:model-value="filters.project ?? ''"
|
|
210
|
-
:options="projectFilterOptions"
|
|
211
|
-
size="sm"
|
|
212
|
-
aria-label="Filter by project"
|
|
213
|
-
@update:model-value="v => setFilter('project', v)"
|
|
214
|
-
/>
|
|
215
|
-
</div>
|
|
216
|
-
<div class="mint-experiment-selector__filter-select">
|
|
217
|
-
<BaseSelect
|
|
218
|
-
:model-value="filters.datePreset ?? ''"
|
|
219
|
-
:options="DATE_PRESET_OPTIONS"
|
|
220
|
-
size="sm"
|
|
221
|
-
aria-label="Filter by date"
|
|
222
|
-
@update:model-value="v => setFilter('datePreset', v)"
|
|
223
|
-
/>
|
|
224
|
-
</div>
|
|
225
|
-
<div class="mint-experiment-selector__filter-select">
|
|
226
|
-
<BaseSelect
|
|
227
|
-
:model-value="sortKey"
|
|
228
|
-
:options="SORT_OPTIONS"
|
|
229
|
-
size="sm"
|
|
230
|
-
aria-label="Sort"
|
|
231
|
-
@update:model-value="handleSortChange"
|
|
232
|
-
/>
|
|
233
|
-
</div>
|
|
234
|
-
<label class="mint-experiment-selector__group-toggle">
|
|
235
|
-
<input
|
|
236
|
-
v-model="groupToggle"
|
|
237
|
-
type="checkbox"
|
|
238
|
-
class="mint-experiment-selector__group-checkbox"
|
|
239
|
-
/>
|
|
240
|
-
Group by project
|
|
241
|
-
</label>
|
|
242
|
-
</div>
|
|
243
257
|
</template>
|
|
244
258
|
</ResourcePickerListInternal>
|
|
245
259
|
|
|
@@ -15,12 +15,7 @@ import BaseInput from './BaseInput.vue'
|
|
|
15
15
|
:required="state.required"
|
|
16
16
|
:html-for="state.htmlFor"
|
|
17
17
|
>
|
|
18
|
-
<
|
|
19
|
-
:id="state.htmlFor"
|
|
20
|
-
type="text"
|
|
21
|
-
placeholder="Enter value..."
|
|
22
|
-
style="width: 100%; padding: 0.5rem 0.75rem; border: 1px solid var(--border-color, #e2e8f0); border-radius: 0.375rem; font-size: 0.875rem; background: var(--bg-primary, #fff); color: var(--text-primary, #1e293b); box-sizing: border-box;"
|
|
23
|
-
/>
|
|
18
|
+
<BaseInput :id="state.htmlFor" placeholder="Enter value..." />
|
|
24
19
|
</FormField>
|
|
25
20
|
</div>
|
|
26
21
|
</template>
|
|
@@ -39,12 +34,7 @@ import BaseInput from './BaseInput.vue'
|
|
|
39
34
|
<Variant title="With Label">
|
|
40
35
|
<div style="padding: 2rem; max-width: 400px; margin: 0 auto;">
|
|
41
36
|
<FormField label="Sample Name" html-for="sample-name">
|
|
42
|
-
<
|
|
43
|
-
id="sample-name"
|
|
44
|
-
type="text"
|
|
45
|
-
placeholder="e.g., SAMPLE-001"
|
|
46
|
-
style="width: 100%; padding: 0.5rem 0.75rem; border: 1px solid var(--border-color, #e2e8f0); border-radius: 0.375rem; font-size: 0.875rem; background: var(--bg-primary, #fff); color: var(--text-primary, #1e293b); box-sizing: border-box;"
|
|
47
|
-
/>
|
|
37
|
+
<BaseInput id="sample-name" placeholder="e.g., SAMPLE-001" />
|
|
48
38
|
</FormField>
|
|
49
39
|
</div>
|
|
50
40
|
</Variant>
|
|
@@ -52,12 +42,7 @@ import BaseInput from './BaseInput.vue'
|
|
|
52
42
|
<Variant title="Required Field">
|
|
53
43
|
<div style="padding: 2rem; max-width: 400px; margin: 0 auto;">
|
|
54
44
|
<FormField label="Experiment ID" :required="true" html-for="exp-id">
|
|
55
|
-
<
|
|
56
|
-
id="exp-id"
|
|
57
|
-
type="text"
|
|
58
|
-
placeholder="Required field"
|
|
59
|
-
style="width: 100%; padding: 0.5rem 0.75rem; border: 1px solid var(--border-color, #e2e8f0); border-radius: 0.375rem; font-size: 0.875rem; background: var(--bg-primary, #fff); color: var(--text-primary, #1e293b); box-sizing: border-box;"
|
|
60
|
-
/>
|
|
45
|
+
<BaseInput id="exp-id" placeholder="Required field" />
|
|
61
46
|
</FormField>
|
|
62
47
|
</div>
|
|
63
48
|
</Variant>
|
|
@@ -65,12 +50,7 @@ import BaseInput from './BaseInput.vue'
|
|
|
65
50
|
<Variant title="With Hint">
|
|
66
51
|
<div style="padding: 2rem; max-width: 400px; margin: 0 auto;">
|
|
67
52
|
<FormField label="Concentration" hint="Enter value in micromolar (uM)" html-for="conc">
|
|
68
|
-
<
|
|
69
|
-
id="conc"
|
|
70
|
-
type="number"
|
|
71
|
-
placeholder="0.00"
|
|
72
|
-
style="width: 100%; padding: 0.5rem 0.75rem; border: 1px solid var(--border-color, #e2e8f0); border-radius: 0.375rem; font-size: 0.875rem; background: var(--bg-primary, #fff); color: var(--text-primary, #1e293b); box-sizing: border-box;"
|
|
73
|
-
/>
|
|
53
|
+
<BaseInput id="conc" inputmode="decimal" placeholder="0.00" />
|
|
74
54
|
</FormField>
|
|
75
55
|
</div>
|
|
76
56
|
</Variant>
|
|
@@ -78,12 +58,7 @@ import BaseInput from './BaseInput.vue'
|
|
|
78
58
|
<Variant title="With Error">
|
|
79
59
|
<div style="padding: 2rem; max-width: 400px; margin: 0 auto;">
|
|
80
60
|
<FormField label="Plate Barcode" error="Barcode format is invalid. Expected: PLT-XXXX-XXXX" html-for="barcode">
|
|
81
|
-
<
|
|
82
|
-
id="barcode"
|
|
83
|
-
type="text"
|
|
84
|
-
value="invalid"
|
|
85
|
-
style="width: 100%; padding: 0.5rem 0.75rem; border: 1px solid #ef4444; border-radius: 0.375rem; font-size: 0.875rem; background: var(--bg-primary, #fff); color: var(--text-primary, #1e293b); box-sizing: border-box;"
|
|
86
|
-
/>
|
|
61
|
+
<BaseInput id="barcode" model-value="invalid" invalid />
|
|
87
62
|
</FormField>
|
|
88
63
|
</div>
|
|
89
64
|
</Variant>
|
|
@@ -91,28 +66,13 @@ import BaseInput from './BaseInput.vue'
|
|
|
91
66
|
<Variant title="Form Example">
|
|
92
67
|
<div style="padding: 2rem; max-width: 400px; margin: 0 auto; display: flex; flex-direction: column; gap: 1rem;">
|
|
93
68
|
<FormField label="Experiment Name" :required="true" html-for="form-name">
|
|
94
|
-
<
|
|
95
|
-
id="form-name"
|
|
96
|
-
type="text"
|
|
97
|
-
placeholder="Enter experiment name"
|
|
98
|
-
style="width: 100%; padding: 0.5rem 0.75rem; border: 1px solid var(--border-color, #e2e8f0); border-radius: 0.375rem; font-size: 0.875rem; background: var(--bg-primary, #fff); color: var(--text-primary, #1e293b); box-sizing: border-box;"
|
|
99
|
-
/>
|
|
69
|
+
<BaseInput id="form-name" placeholder="Enter experiment name" />
|
|
100
70
|
</FormField>
|
|
101
71
|
<FormField label="Description" hint="Optional description for this experiment" html-for="form-desc">
|
|
102
|
-
<textarea
|
|
103
|
-
id="form-desc"
|
|
104
|
-
placeholder="Describe the experiment..."
|
|
105
|
-
rows="3"
|
|
106
|
-
style="width: 100%; padding: 0.5rem 0.75rem; border: 1px solid var(--border-color, #e2e8f0); border-radius: 0.375rem; font-size: 0.875rem; background: var(--bg-primary, #fff); color: var(--text-primary, #1e293b); resize: vertical; box-sizing: border-box;"
|
|
107
|
-
/>
|
|
72
|
+
<BaseInput id="form-desc" type="textarea" placeholder="Describe the experiment..." :rows="3" />
|
|
108
73
|
</FormField>
|
|
109
74
|
<FormField label="Plate Count" :required="true" error="Must be between 1 and 50" html-for="form-count">
|
|
110
|
-
<
|
|
111
|
-
id="form-count"
|
|
112
|
-
type="number"
|
|
113
|
-
value="100"
|
|
114
|
-
style="width: 100%; padding: 0.5rem 0.75rem; border: 1px solid #ef4444; border-radius: 0.375rem; font-size: 0.875rem; background: var(--bg-primary, #fff); color: var(--text-primary, #1e293b); box-sizing: border-box;"
|
|
115
|
-
/>
|
|
75
|
+
<BaseInput id="form-count" inputmode="numeric" model-value="100" invalid />
|
|
116
76
|
</FormField>
|
|
117
77
|
</div>
|
|
118
78
|
</Variant>
|
|
@@ -29,6 +29,7 @@ import LoadingSpinner from './LoadingSpinner.vue'
|
|
|
29
29
|
import PluginWorkspaceView from './PluginWorkspaceView.vue'
|
|
30
30
|
import { GENERATED_JOBS_API_KEY } from './internal/generatedJobsApi'
|
|
31
31
|
import { definePluginWorkspaceView } from '../composables/componentSpecs'
|
|
32
|
+
import { providePluginIdentity } from '../composables/pluginIdentity'
|
|
32
33
|
|
|
33
34
|
interface Props {
|
|
34
35
|
baseUrl: string
|
|
@@ -74,7 +75,7 @@ const forms = computed<Record<string, FormSchema>>(() => Object.fromEntries(
|
|
|
74
75
|
|
|
75
76
|
const workspace = computed(() => definePluginWorkspaceView({
|
|
76
77
|
title: generated.manifest.value?.ui.title ?? 'Analysis',
|
|
77
|
-
subtitle: generated.manifest.value?.ui.description,
|
|
78
|
+
subtitle: generated.manifest.value?.ui.subtitle || generated.manifest.value?.ui.description,
|
|
78
79
|
// The platform shell renders the toasts around this view.
|
|
79
80
|
toasts: false,
|
|
80
81
|
topBar: {
|
|
@@ -85,6 +86,11 @@ const workspace = computed(() => definePluginWorkspaceView({
|
|
|
85
86
|
sidebar: { title: 'Parameters', panels: panels.value, forms: forms.value },
|
|
86
87
|
}))
|
|
87
88
|
|
|
89
|
+
// Seeds the standalone top bar icon; the title and subtitle above win over the seeded text.
|
|
90
|
+
watch(() => generated.manifest.value?.ui, (ui) => {
|
|
91
|
+
if (ui) providePluginIdentity({ plugin: { name: ui.title, subtitle: ui.subtitle, description: ui.description, icon: ui.icon } })
|
|
92
|
+
}, { immediate: true })
|
|
93
|
+
|
|
88
94
|
const currentValues = computed(() => valuesByDefinition[activeDefinitionId.value] ?? {})
|
|
89
95
|
const currentJob = computed(() => {
|
|
90
96
|
const currentSessionId = generated.session.value?.id
|
|
@@ -15,7 +15,7 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
15
15
|
})
|
|
16
16
|
|
|
17
17
|
const stateConfig: Record<InstrumentBadgeState, { label: string; tone: string }> = {
|
|
18
|
-
running: { label: 'Running', tone: '
|
|
18
|
+
running: { label: 'Running', tone: 'success' },
|
|
19
19
|
standby: { label: 'Standby', tone: 'warning' },
|
|
20
20
|
idle: { label: 'Idle', tone: 'muted' },
|
|
21
21
|
error: { label: 'Error', tone: 'error' },
|
|
@@ -218,7 +218,7 @@ async function clearFinished(): Promise<void> {
|
|
|
218
218
|
<header class="mint-jobs-tray__header">
|
|
219
219
|
<div>
|
|
220
220
|
<h2 :id="titleId" class="mint-jobs-tray__title">{{ title }}</h2>
|
|
221
|
-
<p class="mint-jobs-tray__subtitle">{{ subtitle }}</p>
|
|
221
|
+
<p class="mint-jobs-tray__subtitle" :title="subtitle">{{ subtitle }}</p>
|
|
222
222
|
</div>
|
|
223
223
|
<div class="mint-jobs-tray__header-actions">
|
|
224
224
|
<button
|
|
@@ -40,7 +40,7 @@ withDefaults(defineProps<Props>(), {
|
|
|
40
40
|
<path
|
|
41
41
|
style="opacity: 0.75"
|
|
42
42
|
fill="currentColor"
|
|
43
|
-
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0
|
|
43
|
+
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
|
|
44
44
|
/>
|
|
45
45
|
</svg>
|
|
46
46
|
<span class="mint-spinner__label">{{ label }}</span>
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
* ```
|
|
11
11
|
*/
|
|
12
12
|
import { computed, onBeforeUnmount, useAttrs, type StyleValue } from 'vue'
|
|
13
|
+
import { ChevronDown, ChevronUp } from 'lucide-vue-next'
|
|
13
14
|
import type { UnitOption } from '../types'
|
|
14
15
|
import NumberUnitInputInternal from './internal/NumberUnitInputInternal.vue'
|
|
15
16
|
|
|
@@ -287,9 +288,7 @@ function handleScrubStart(event: PointerEvent) {
|
|
|
287
288
|
class="mint-number-input__stepper mint-number-input__stepper--down"
|
|
288
289
|
@click="decrement"
|
|
289
290
|
>
|
|
290
|
-
<
|
|
291
|
-
<path d="M2 5h6" />
|
|
292
|
-
</svg>
|
|
291
|
+
<ChevronDown :size="12" :stroke-width="2.25" />
|
|
293
292
|
</button>
|
|
294
293
|
<button
|
|
295
294
|
type="button"
|
|
@@ -299,9 +298,7 @@ function handleScrubStart(event: PointerEvent) {
|
|
|
299
298
|
class="mint-number-input__stepper mint-number-input__stepper--up"
|
|
300
299
|
@click="increment"
|
|
301
300
|
>
|
|
302
|
-
<
|
|
303
|
-
<path d="M5 2v6" /><path d="M2 5h6" />
|
|
304
|
-
</svg>
|
|
301
|
+
<ChevronUp :size="12" :stroke-width="2.25" />
|
|
305
302
|
</button>
|
|
306
303
|
</div>
|
|
307
304
|
</div>
|
|
@@ -52,8 +52,8 @@ function initState() {
|
|
|
52
52
|
<HstText v-model="state.icon" title="icon" />
|
|
53
53
|
<HstSelect v-model="state.size" title="size" :options="['sm', 'md', 'topbar', 'lg']" />
|
|
54
54
|
<HstSelect v-model="state.variant" title="variant" :options="['solid', 'tinted']" />
|
|
55
|
-
<HstSelect v-model="state.tone" title="tone" :options="['', 'neutral', 'primary', 'cta', 'success', 'warning', 'error', 'info']" />
|
|
56
|
-
<HstText v-model="state.color" title="color (
|
|
55
|
+
<HstSelect v-model="state.tone" title="tone (deprecated, no effect; removed in 1.5)" :options="['', 'neutral', 'primary', 'cta', 'success', 'warning', 'error', 'info']" />
|
|
56
|
+
<HstText v-model="state.color" title="color (deprecated, no effect; removed in 1.5)" />
|
|
57
57
|
</template>
|
|
58
58
|
</Variant>
|
|
59
59
|
|
|
@@ -94,13 +94,5 @@ function initState() {
|
|
|
94
94
|
<PluginIcon :icon="SAMPLE_STRUCTURED" size="lg" />
|
|
95
95
|
</div>
|
|
96
96
|
</Variant>
|
|
97
|
-
|
|
98
|
-
<Variant title="Tone overrides">
|
|
99
|
-
<div style="padding: 2rem; display: flex; gap: 1rem; align-items: center;">
|
|
100
|
-
<PluginIcon :icon="SAMPLE_PATH" size="lg" variant="solid" color="#0EA5E9" />
|
|
101
|
-
<PluginIcon :icon="SAMPLE_PATH" size="lg" variant="solid" color="#F97316" />
|
|
102
|
-
<PluginIcon :icon="SAMPLE_PATH" size="lg" variant="solid" color="#22C55E" />
|
|
103
|
-
</div>
|
|
104
|
-
</Variant>
|
|
105
97
|
</Story>
|
|
106
98
|
</template>
|
|
@@ -18,9 +18,9 @@ interface Props {
|
|
|
18
18
|
icon?: string
|
|
19
19
|
size?: 'sm' | 'md' | 'topbar' | 'lg'
|
|
20
20
|
variant?: 'solid' | 'tinted'
|
|
21
|
-
/**
|
|
21
|
+
/** @deprecated v2 design: the tile is always the neutral accent-soft tile, so the tone has no visible effect. Removed in 1.5. */
|
|
22
22
|
tone?: Tone
|
|
23
|
-
/**
|
|
23
|
+
/** @deprecated v2 design: the tile is always the neutral accent-soft tile, so the color has no visible effect. Removed in 1.5. */
|
|
24
24
|
color?: string
|
|
25
25
|
}
|
|
26
26
|
|
|
@@ -274,7 +274,7 @@ async function saveDoseDesign() {
|
|
|
274
274
|
</PluginWorkspaceView>
|
|
275
275
|
<p
|
|
276
276
|
v-if="lastExperimentEvent"
|
|
277
|
-
style="padding: 0.75rem 1rem; margin: 0; font-family:
|
|
277
|
+
style="padding: 0.75rem 1rem; margin: 0; font-family: var(--font-mono); font-size: 0.75rem; color: var(--text-muted);"
|
|
278
278
|
>
|
|
279
279
|
Last shell event: {{ lastExperimentEvent }}
|
|
280
280
|
</p>
|
|
@@ -135,7 +135,7 @@ function handleSmartGroup(result: AutoGroupResult, state: { groups: SampleGroup[
|
|
|
135
135
|
</div>
|
|
136
136
|
</Variant>
|
|
137
137
|
|
|
138
|
-
<Variant title="Narrow
|
|
138
|
+
<Variant title="Narrow Header">
|
|
139
139
|
<div style="padding: 2rem; width: 320px;">
|
|
140
140
|
<SampleSelector
|
|
141
141
|
:model-value="['Control_Rep1']"
|