@morscherlab/mint-sdk 1.4.0-beta.8 → 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.
Files changed (257) hide show
  1. package/dist/{ActionMenu-CScINahU.js → AlertBox-B2Bgr3ei.js} +40 -209
  2. package/dist/AlertBox-B2Bgr3ei.js.map +1 -0
  3. package/dist/{AppSidebar-BmiiPfz9.js → AppSidebar-Dq9W1jE2.js} +160 -109
  4. package/dist/AppSidebar-Dq9W1jE2.js.map +1 -0
  5. package/dist/{ConfirmDialog-CJ7hqYUP.js → ConfirmDialog-nbJj51is.js} +2 -2
  6. package/dist/{ConfirmDialog-CJ7hqYUP.js.map → ConfirmDialog-nbJj51is.js.map} +1 -1
  7. package/dist/ExperimentPopover-5T1fAq2L.js +337 -0
  8. package/dist/ExperimentPopover-5T1fAq2L.js.map +1 -0
  9. package/dist/{ExperimentSelectorModal-D-9z7cNx.js → ExperimentSelectorModal-65peG4Up.js} +198 -181
  10. package/dist/ExperimentSelectorModal-65peG4Up.js.map +1 -0
  11. package/dist/{SegmentedControl-DERBN-Xd.js → SegmentedControl-BtnnjWzs.js} +2 -2
  12. package/dist/{SegmentedControl-DERBN-Xd.js.map → SegmentedControl-BtnnjWzs.js.map} +1 -1
  13. package/dist/{SettingsModal-CSLE31yg.js → SettingsModal-483nyI6b.js} +9 -9
  14. package/dist/SettingsModal-483nyI6b.js.map +1 -0
  15. package/dist/components/AppSidebar.vue.d.ts +1 -1
  16. package/dist/components/ArtifactSaveDialog.vue.d.ts +9 -1
  17. package/dist/components/AuditTrail.vue.d.ts +1 -1
  18. package/dist/components/BaseSelect.vue.d.ts +2 -2
  19. package/dist/components/ChartContainer.vue.d.ts +2 -0
  20. package/dist/components/DatePicker.vue.d.ts +1 -1
  21. package/dist/components/ExperimentPopover.vue.d.ts +18 -0
  22. package/dist/components/ExperimentSelectorModal.vue.d.ts +0 -4
  23. package/dist/components/FilePicker.vue.d.ts +1 -1
  24. package/dist/components/FileUploader.vue.d.ts +2 -2
  25. package/dist/components/PluginIcon.vue.d.ts +2 -2
  26. package/dist/components/SampleSelector.vue.d.ts +6 -6
  27. package/dist/components/SequenceProgressBar.vue.d.ts +3 -0
  28. package/dist/components/StepWizard.vue.d.ts +3 -0
  29. package/dist/components/internal/AutoGroupModalInternal.vue.d.ts +1 -1
  30. package/dist/components/internal/DatePickerTimeInternal.vue.d.ts +1 -1
  31. package/dist/components/internal/ResourcePickerListInternal.vue.d.ts +2 -7
  32. package/dist/components/internal/SelectMultipleInternal.vue.d.ts +4 -0
  33. package/dist/composables/createClient.d.ts +2 -0
  34. package/dist/composables/index.d.ts +1 -0
  35. package/dist/composables/pluginIdentity.d.ts +24 -0
  36. package/dist/composables/useAppExperiment.d.ts +8 -0
  37. package/dist/composables/useCalendarGrid.d.ts +1 -1
  38. package/dist/composables/useExperimentSelector.d.ts +6 -2
  39. package/dist/composables/usePlatform.d.ts +1 -0
  40. package/dist/{controlSchemaModel-CP5-_nAj.js → controlSchemaModel-B8CTXagP.js} +2 -2
  41. package/dist/{controlSchemaModel-CP5-_nAj.js.map → controlSchemaModel-B8CTXagP.js.map} +1 -1
  42. package/dist/{data-C2PwI_dn.js → data-CgILxDLW.js} +178 -124
  43. package/dist/data-CgILxDLW.js.map +1 -0
  44. package/dist/data.js +8 -8
  45. package/dist/{experimentStatus-BZmU4czV.js → experimentStatus-Cqp6qNrR.js} +3 -3
  46. package/dist/{experimentStatus-BZmU4czV.js.map → experimentStatus-Cqp6qNrR.js.map} +1 -1
  47. package/dist/index.js +19 -19
  48. package/dist/{install-DAID6c2-.js → install-BtLWTk6H.js} +15 -14
  49. package/dist/{install-DAID6c2-.js.map → install-BtLWTk6H.js.map} +1 -1
  50. package/dist/install.js +1 -1
  51. package/dist/{lab-DLwRl_Ql.js → lab-MHzp-_J8.js} +128 -147
  52. package/dist/lab-MHzp-_J8.js.map +1 -0
  53. package/dist/lab.js +4 -3
  54. package/dist/{records-BzTcxekG.js → records-B6gpM_3e.js} +472 -274
  55. package/dist/records-B6gpM_3e.js.map +1 -0
  56. package/dist/{runtime-D6gVat6r.js → runtime-7vfl_bI3.js} +27 -31
  57. package/dist/runtime-7vfl_bI3.js.map +1 -0
  58. package/dist/runtime.js +6 -6
  59. package/dist/{shell-5ju97nOS.js → shell-Cs9OJMnm.js} +5 -5
  60. package/dist/{shell-5ju97nOS.js.map → shell-Cs9OJMnm.js.map} +1 -1
  61. package/dist/shell.js +5 -5
  62. package/dist/styles.css +1606 -1666
  63. package/dist/types/componentWorkflowTypes.d.ts +2 -0
  64. package/dist/types/generated/platformContext.d.ts +1 -0
  65. package/dist/types/generated-ui.d.ts +4 -0
  66. package/dist/{BaseModal-DfRIuVoj.js → useDropdownState-8yWMu-7_.js} +60 -2
  67. package/dist/useDropdownState-8yWMu-7_.js.map +1 -0
  68. package/dist/{useExperimentSamples-CxcnxZ8h.js → useExperimentSamples-DHnxKFAF.js} +3 -3
  69. package/dist/{useExperimentSamples-CxcnxZ8h.js.map → useExperimentSamples-DHnxKFAF.js.map} +1 -1
  70. package/dist/{useListReorder-CcbEYxX-.js → useListReorder-BitdUhxn.js} +109 -277
  71. package/dist/useListReorder-BitdUhxn.js.map +1 -0
  72. package/dist/{useRackEditor-BD5NIo5s.js → useRackEditor-DiwCt77M.js} +71 -57
  73. package/dist/useRackEditor-DiwCt77M.js.map +1 -0
  74. package/dist/{useRealtime-PalKue84.js → useRealtime-C3iy9QkU.js} +7 -4
  75. package/dist/useRealtime-C3iy9QkU.js.map +1 -0
  76. package/dist/useRequest-D506eHi8.js +244 -0
  77. package/dist/useRequest-D506eHi8.js.map +1 -0
  78. package/dist/utils/time.d.ts +7 -0
  79. package/package.json +1 -1
  80. package/src/__tests__/components/AppTopBar.test.ts +51 -2
  81. package/src/__tests__/components/AppTopBarPillNav.test.ts +35 -0
  82. package/src/__tests__/components/ArtifactSaveDialog.test.ts +78 -0
  83. package/src/__tests__/components/BaseSelect.multiple.test.ts +87 -32
  84. package/src/__tests__/components/BaseSelect.test.ts +2 -1
  85. package/src/__tests__/components/BatchProgressList.test.ts +16 -0
  86. package/src/__tests__/components/CalendarGridPanel.test.ts +2 -2
  87. package/src/__tests__/components/ChartContainer.test.ts +11 -0
  88. package/src/__tests__/components/ChemicalFormula.test.ts +6 -3
  89. package/src/__tests__/components/DatePicker.datetime.test.ts +6 -0
  90. package/src/__tests__/components/DatePicker.test.ts +21 -0
  91. package/src/__tests__/components/DatePicker.time.test.ts +2 -2
  92. package/src/__tests__/components/EmptyState.test.ts +1 -1
  93. package/src/__tests__/components/ExperimentPopover.test.ts +125 -16
  94. package/src/__tests__/components/ExperimentSelectorModal.test.ts +119 -13
  95. package/src/__tests__/components/GeneratedPluginView.test.ts +22 -1
  96. package/src/__tests__/components/InstrumentStateBadge.test.ts +4 -4
  97. package/src/__tests__/components/ResourcePickerListInternal.test.ts +0 -20
  98. package/src/__tests__/components/SampleSelector.test.ts +13 -8
  99. package/src/__tests__/components/SequenceProgressBar.test.ts +12 -0
  100. package/src/__tests__/components/StepWizard.test.ts +11 -0
  101. package/src/__tests__/components/WellPlate.decoration.test.ts +11 -4
  102. package/src/__tests__/components/deprecationTags.test.ts +1 -1
  103. package/src/__tests__/composables/useAppExperiment.test.ts +27 -1
  104. package/src/__tests__/composables/useCalendarGrid.test.ts +4 -2
  105. package/src/__tests__/composables/useExperimentSelector.test.ts +111 -0
  106. package/src/__tests__/styles/baseControlsRules.test.ts +6 -2
  107. package/src/__tests__/styles/controlRefreshRules.test.ts +0 -6
  108. package/src/__tests__/styles/cssTokens.test.ts +2 -2
  109. package/src/__tests__/styles/menusShellRefresh.test.ts +14 -10
  110. package/src/__tests__/utils/plotlyTemplate.test.ts +4 -4
  111. package/src/__tests__/utils/time.test.ts +18 -1
  112. package/src/components/AdductText.story.vue +7 -0
  113. package/src/components/AdductText.vue +1 -1
  114. package/src/components/AlertBox.story.vue +2 -2
  115. package/src/components/AlertBox.vue +18 -16
  116. package/src/components/AppSidebar.story.vue +0 -28
  117. package/src/components/AppTopBar.story.vue +47 -12
  118. package/src/components/AppTopBar.vue +118 -114
  119. package/src/components/ArtifactSaveDialog.story.vue +23 -0
  120. package/src/components/ArtifactSaveDialog.vue +102 -12
  121. package/src/components/AuditTrail.story.vue +2 -1
  122. package/src/components/AuditTrail.vue +2 -21
  123. package/src/components/Avatar.vue +10 -14
  124. package/src/components/BaseSelect.multiple.story.vue +13 -2
  125. package/src/components/BaseSelect.vue +4 -3
  126. package/src/components/BatchProgressList.vue +35 -25
  127. package/src/components/ChartContainer.story.vue +2 -1
  128. package/src/components/ChartContainer.vue +8 -6
  129. package/src/components/ConfirmDialog.story.vue +1 -1
  130. package/src/components/EmptyState.vue +1 -1
  131. package/src/components/ExperimentPopover.story.vue +165 -53
  132. package/src/components/ExperimentPopover.vue +169 -187
  133. package/src/components/ExperimentSelectorModal.story.vue +40 -36
  134. package/src/components/ExperimentSelectorModal.vue +124 -110
  135. package/src/components/FormField.story.vue +8 -48
  136. package/src/components/GeneratedPluginView.vue +7 -1
  137. package/src/components/InstrumentStateBadge.vue +1 -1
  138. package/src/components/JobsStatusTray.vue +1 -1
  139. package/src/components/LoadingSpinner.vue +1 -1
  140. package/src/components/NumberInput.vue +3 -6
  141. package/src/components/PluginIcon.story.vue +2 -10
  142. package/src/components/PluginIcon.vue +2 -2
  143. package/src/components/PluginWorkspaceView.story.vue +1 -1
  144. package/src/components/RuntimeUpdateNotice.vue +1 -1
  145. package/src/components/SampleSelector.story.vue +1 -1
  146. package/src/components/SampleSelector.vue +27 -37
  147. package/src/components/SampleSelectorGroupNode.vue +1 -1
  148. package/src/components/SectionCard.story.vue +2 -2
  149. package/src/components/SequenceProgressBar.story.vue +9 -0
  150. package/src/components/SequenceProgressBar.vue +6 -1
  151. package/src/components/SettingsModal.schema.ts +1 -1
  152. package/src/components/SettingsModal.vue +2 -2
  153. package/src/components/SmartGroupFieldRecipe.story.vue +1 -1
  154. package/src/components/SmartGroupManual.story.vue +1 -1
  155. package/src/components/StepWizard.story.vue +33 -0
  156. package/src/components/StepWizard.vue +8 -1
  157. package/src/components/WellPlate.story.vue +3 -1
  158. package/src/components/WellPlate.vue +7 -0
  159. package/src/components/internal/AppTopBarPillNavInternal.vue +33 -2
  160. package/src/components/internal/DatePickerDateInternal.vue +16 -40
  161. package/src/components/internal/DatePickerDateTimeInternal.vue +3 -13
  162. package/src/components/internal/DatePickerTimeInternal.vue +5 -8
  163. package/src/components/internal/ResourcePickerListInternal.vue +45 -85
  164. package/src/components/internal/SelectMultipleInternal.vue +182 -65
  165. package/src/components/internal/SelectSearchableInternal.vue +2 -3
  166. package/src/composables/createClient.ts +2 -0
  167. package/src/composables/index.ts +1 -0
  168. package/src/composables/pluginIdentity.ts +31 -0
  169. package/src/composables/useAppExperiment.ts +20 -0
  170. package/src/composables/useCalendarGrid.ts +4 -3
  171. package/src/composables/useExperimentSelector.ts +77 -31
  172. package/src/styles/components/adduct-text.css +13 -5
  173. package/src/styles/components/alert-box.css +39 -58
  174. package/src/styles/components/app-layout.css +6 -5
  175. package/src/styles/components/app-page-selector.css +3 -1
  176. package/src/styles/components/app-pill-nav.css +11 -12
  177. package/src/styles/components/app-sidebar.css +9 -18
  178. package/src/styles/components/app-top-bar.css +57 -55
  179. package/src/styles/components/artifact-save-dialog.css +153 -2
  180. package/src/styles/components/audit-trail.css +16 -19
  181. package/src/styles/components/avatar.css +6 -4
  182. package/src/styles/components/batch-progress-list.css +38 -36
  183. package/src/styles/components/button.css +28 -59
  184. package/src/styles/components/calendar.css +12 -12
  185. package/src/styles/components/chart-container.css +34 -23
  186. package/src/styles/components/checkbox.css +2 -12
  187. package/src/styles/components/collapsible-card.css +27 -29
  188. package/src/styles/components/confirm-dialog.css +13 -14
  189. package/src/styles/components/dataframe.css +12 -4
  190. package/src/styles/components/date-picker.css +80 -92
  191. package/src/styles/components/datetime-picker.css +31 -43
  192. package/src/styles/components/divider.css +20 -20
  193. package/src/styles/components/dose-calculator.css +3 -3
  194. package/src/styles/components/empty-state.css +20 -17
  195. package/src/styles/components/experiment-code-badge.css +2 -0
  196. package/src/styles/components/experiment-popover.css +174 -329
  197. package/src/styles/components/experiment-selector-modal.css +75 -56
  198. package/src/styles/components/file-picker.css +3 -3
  199. package/src/styles/components/file-uploader.css +38 -49
  200. package/src/styles/components/form-builder.css +3 -3
  201. package/src/styles/components/formula-input.css +1 -1
  202. package/src/styles/components/icon-button.css +18 -24
  203. package/src/styles/components/input.css +5 -4
  204. package/src/styles/components/instrument-monitor.css +13 -15
  205. package/src/styles/components/jobs-status-tray.css +31 -25
  206. package/src/styles/components/modal.css +2 -4
  207. package/src/styles/components/molecule-input.css +2 -2
  208. package/src/styles/components/multi-select.css +65 -117
  209. package/src/styles/components/number-input.css +26 -19
  210. package/src/styles/components/pill.css +3 -2
  211. package/src/styles/components/plate-editor.css +0 -1
  212. package/src/styles/components/plugin-icon.css +26 -23
  213. package/src/styles/components/popover.css +2 -2
  214. package/src/styles/components/presence-avatars.css +1 -1
  215. package/src/styles/components/protocol-step-editor.css +1 -3
  216. package/src/styles/components/resource-card.css +2 -2
  217. package/src/styles/components/resource-picker-list.css +6 -57
  218. package/src/styles/components/sample-hierarchy-tree.css +4 -4
  219. package/src/styles/components/sample-selector.css +95 -79
  220. package/src/styles/components/schedule-calendar.css +8 -8
  221. package/src/styles/components/searchable-select.css +12 -12
  222. package/src/styles/components/section-card.css +28 -47
  223. package/src/styles/components/segmented-control.css +18 -15
  224. package/src/styles/components/select.css +3 -3
  225. package/src/styles/components/sequence-input.css +2 -2
  226. package/src/styles/components/sequence-progress-bar.css +17 -8
  227. package/src/styles/components/smart-group.css +18 -18
  228. package/src/styles/components/step-wizard.css +52 -16
  229. package/src/styles/components/tabs.css +2 -2
  230. package/src/styles/components/textarea.css +3 -3
  231. package/src/styles/components/time-picker.css +36 -21
  232. package/src/styles/components/toast.css +12 -10
  233. package/src/styles/components/toggle.css +1 -11
  234. package/src/styles/components/tooltip.css +10 -9
  235. package/src/styles/components/unit-input.css +8 -7
  236. package/src/styles/components/well-plate.css +9 -2
  237. package/src/styles/variables.css +106 -75
  238. package/src/types/componentWorkflowTypes.ts +2 -0
  239. package/src/types/generated/platformContext.ts +1 -0
  240. package/src/types/generated-ui.ts +4 -0
  241. package/src/utils/time.ts +21 -0
  242. package/dist/ActionMenu-CScINahU.js.map +0 -1
  243. package/dist/AppSidebar-BmiiPfz9.js.map +0 -1
  244. package/dist/BaseModal-DfRIuVoj.js.map +0 -1
  245. package/dist/ExperimentPopover-C4sGw-is.js +0 -359
  246. package/dist/ExperimentPopover-C4sGw-is.js.map +0 -1
  247. package/dist/ExperimentSelectorModal-D-9z7cNx.js.map +0 -1
  248. package/dist/SettingsModal-CSLE31yg.js.map +0 -1
  249. package/dist/data-C2PwI_dn.js.map +0 -1
  250. package/dist/lab-DLwRl_Ql.js.map +0 -1
  251. package/dist/records-BzTcxekG.js.map +0 -1
  252. package/dist/runtime-D6gVat6r.js.map +0 -1
  253. package/dist/useListReorder-CcbEYxX-.js.map +0 -1
  254. package/dist/useRackEditor-BD5NIo5s.js.map +0 -1
  255. package/dist/useRealtime-PalKue84.js.map +0 -1
  256. package/dist/useRequest-D5JDfsgZ.js +0 -76
  257. package/dist/useRequest-D5JDfsgZ.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- /** Displays a user avatar as an image, a single derived initial, or a fallback icon, with a deterministic background color and optional status dot. */
2
+ /** Displays a user avatar as an image, a single derived initial, or a fallback icon, on a quiet accent face (or an explicit `color`) with an optional status dot. */
3
3
  import { computed } from 'vue'
4
4
 
5
5
  interface Props {
@@ -17,24 +17,20 @@ const props = withDefaults(defineProps<Props>(), {
17
17
  size: 'md',
18
18
  })
19
19
 
20
- const PALETTE = ['#3B82F6', '#8B5CF6', '#EC4899', '#F97316', '#10B981', '#F59E0B', '#06B6D4', '#6366F1']
21
-
22
20
  // Default: first letter of `name`, uppercased. Consumers wanting two letters
23
21
  // (e.g. role badges like "PI", "QC") pass `:initials="'XX'"` explicitly.
24
22
  const computedInitials = computed(() =>
25
23
  props.initials || props.name?.charAt(0).toUpperCase() || ''
26
24
  )
27
25
 
28
- const backgroundColor = computed(() => {
29
- if (props.color) return props.color
30
- if (!props.name) return undefined
31
-
32
- let hash = 0
33
- for (let i = 0; i < props.name.length; i++) {
34
- hash = props.name.charCodeAt(i) + ((hash << 5) - hash)
35
- }
36
- return PALETTE[Math.abs(hash) % PALETTE.length]
37
- })
26
+ // The quiet accent face lives in avatar.css; an explicit `color` fills the
27
+ // face. That fill is a fixed hue (role badges), so the ink stays white in both
28
+ // themes instead of following the theme-dependent --text-on-accent.
29
+ const faceStyle = computed(() =>
30
+ props.color
31
+ ? { backgroundColor: props.color, color: '#fff', boxShadow: 'none' }
32
+ : undefined
33
+ )
38
34
  </script>
39
35
 
40
36
  <template>
@@ -45,7 +41,7 @@ const backgroundColor = computed(() => {
45
41
  >
46
42
  <span
47
43
  class="mint-avatar__face"
48
- :style="backgroundColor ? { backgroundColor } : undefined"
44
+ :style="faceStyle"
49
45
  >
50
46
  <img
51
47
  v-if="src"
@@ -39,7 +39,7 @@ function initPlayground() {
39
39
  <Story title="Base Inputs/BaseSelect · multiple">
40
40
  <Variant title="Playground" :init-state="initPlayground">
41
41
  <template #default="{ state }">
42
- <div style="padding: 2rem; max-width: 500px; margin: 0 auto;">
42
+ <div style="padding: 2rem; max-width: 500px; min-height: 22rem; margin: 0 auto;">
43
43
  <BaseSelect
44
44
  multiple
45
45
  v-model="state.selected"
@@ -91,7 +91,7 @@ function initPlayground() {
91
91
  </Variant>
92
92
 
93
93
  <Variant title="With Max Selections">
94
- <div style="padding: 2rem; max-width: 500px; margin: 0 auto;">
94
+ <div style="padding: 2rem; max-width: 500px; min-height: 22rem; margin: 0 auto;">
95
95
  <p style="margin: 0 0 0.5rem; font-size: 0.875rem; color: var(--text-primary, #e2e8f0);">
96
96
  Maximum 3 selections allowed
97
97
  </p>
@@ -124,6 +124,17 @@ function initPlayground() {
124
124
  </div>
125
125
  </Variant>
126
126
 
127
+ <Variant title="Invalid">
128
+ <div style="padding: 2rem; max-width: 500px; margin: 0 auto;">
129
+ <BaseSelect
130
+ multiple
131
+ :model-value="['hela']"
132
+ :options="sampleOptions"
133
+ invalid
134
+ />
135
+ </div>
136
+ </Variant>
137
+
127
138
  <Variant title="Disabled">
128
139
  <div style="padding: 2rem; max-width: 500px; margin: 0 auto;">
129
140
  <BaseSelect
@@ -2,7 +2,7 @@
2
2
  /**
3
3
  * Select one or several options.
4
4
  * Default: a native `<select>`. `searchable`: a listbox with a search field and the `#option` / `#footer` slots.
5
- * `multiple`: a checkbox chip list bound to an array, capped by `max`.
5
+ * `multiple`: a field of removable chips with a filterable checkbox listbox, bound to an array and capped by `max`.
6
6
  *
7
7
  * @example
8
8
  * ```vue
@@ -25,7 +25,7 @@ const props = withDefaults(defineProps<{
25
25
  /** The selected value; an array with `multiple`. */
26
26
  modelValue?: (M extends true ? OptionPrimitive[] : OptionPrimitive) | null
27
27
  options: SelectOptionInput[]
28
- /** Bind an array and pick several options (chip list). */
28
+ /** Bind an array and pick several options (chip field + checkbox listbox). */
29
29
  multiple?: M
30
30
  /** Single selection in a listbox with a search field. Ignored with `multiple`. */
31
31
  searchable?: boolean
@@ -40,7 +40,7 @@ const props = withDefaults(defineProps<{
40
40
  invalid?: boolean
41
41
  size?: 'sm' | 'md' | 'lg'
42
42
  ariaDescribedby?: string
43
- /** Id of the visible label (`searchable`); the trigger is then named by the label and the selected value. */
43
+ /** Id of the visible label. `searchable`: the trigger is then named by the label and the selected value. */
44
44
  ariaLabelledby?: string
45
45
  }>(), {
46
46
  modelValue: null,
@@ -118,6 +118,7 @@ function handleChange(event: Event) {
118
118
  :invalid="invalid"
119
119
  :max="max"
120
120
  :size="size"
121
+ :aria-labelledby="ariaLabelledby"
121
122
  :aria-describedby="ariaDescribedby"
122
123
  @update:model-value="update"
123
124
  />
@@ -1,7 +1,8 @@
1
1
  <script setup lang="ts">
2
2
  /** Scrollable list tracking per-item status for a batch operation with overall progress summary. */
3
3
  import { computed, ref, watch, nextTick } from 'vue'
4
- import type { BatchItem, BatchSummary } from '../types'
4
+ import { CircleCheck, CircleDashed, CircleMinus, CircleX, Loader } from 'lucide-vue-next'
5
+ import type { BatchItem, BatchItemStatus, BatchSummary } from '../types'
5
6
  import DataStateInternal from './internal/DataStateInternal.vue'
6
7
 
7
8
  interface Props {
@@ -34,6 +35,28 @@ const emit = defineEmits<{
34
35
  'cancel': [id: string]
35
36
  }>()
36
37
 
38
+ const STATUS_ICONS: Record<BatchItemStatus, typeof CircleCheck> = {
39
+ completed: CircleCheck,
40
+ processing: Loader,
41
+ pending: CircleDashed,
42
+ error: CircleX,
43
+ skipped: CircleMinus,
44
+ }
45
+
46
+ const STATUS_TEXT: Partial<Record<BatchItemStatus, string>> = {
47
+ pending: 'Queued',
48
+ error: 'Failed',
49
+ skipped: 'Skipped',
50
+ }
51
+
52
+ function itemPercent(item: BatchItem): number {
53
+ return item.status === 'completed' ? 100 : (item.progress ?? 0)
54
+ }
55
+
56
+ function statusText(item: BatchItem): string {
57
+ return STATUS_TEXT[item.status] ?? `${itemPercent(item)}%`
58
+ }
59
+
37
60
  const listRef = ref<HTMLElement | null>(null)
38
61
  // 6b: completed items keep full contrast but collapse behind a toggle.
39
62
  const showCompleted = ref(false)
@@ -141,34 +164,17 @@ watch(
141
164
  >
142
165
  <slot name="item" :item="item">
143
166
  <div class="mint-batch-progress__item-row">
144
- <!-- Status by shape: hollow ring / progress arc / check / filled ! / dash -->
145
- <span :class="['mint-batch-progress__item-icon', `mint-batch-progress__item-icon--${item.status}`]" aria-hidden="true">
146
- <span v-if="item.status === 'pending'" class="mint-batch-progress__pending-ring" />
147
- <svg v-else-if="item.status === 'processing'" class="mint-batch-progress__shape" viewBox="0 0 16 16" fill="none">
148
- <circle class="mint-batch-progress__arc-track" cx="8" cy="8" r="6" />
149
- <path class="mint-batch-progress__arc" d="M8 2a6 6 0 0 1 6 6" />
150
- </svg>
151
- <svg v-else-if="item.status === 'completed'" class="mint-batch-progress__shape" viewBox="0 0 16 16" fill="none">
152
- <path class="mint-batch-progress__check" d="M3.5 8.5l3 3 6-7" />
153
- </svg>
154
- <svg v-else-if="item.status === 'error'" class="mint-batch-progress__shape" viewBox="0 0 16 16">
155
- <circle class="mint-batch-progress__error-disc" cx="8" cy="8" r="7" />
156
- <path class="mint-batch-progress__error-mark" d="M8 4.5v4M8 11v.01" />
157
- </svg>
158
- <svg v-else class="mint-batch-progress__shape" viewBox="0 0 16 16" fill="none">
159
- <path class="mint-batch-progress__dash" d="M4 8h8" />
160
- </svg>
161
- </span>
167
+ <component
168
+ :is="STATUS_ICONS[item.status]"
169
+ :class="['mint-batch-progress__item-icon', `mint-batch-progress__item-icon--${item.status}`]"
170
+ :size="16"
171
+ aria-hidden="true"
172
+ />
162
173
 
163
174
  <span class="mint-batch-progress__item-label">{{ item.label }}</span>
164
175
 
165
176
  <span class="mint-batch-progress__item-meta">
166
- <template v-if="item.status === 'processing' && item.progress !== undefined">
167
- <span class="mint-batch-progress__item-progress">
168
- <span class="mint-batch-progress__item-progress-bar" :style="{ width: `${item.progress}%` }" />
169
- </span>
170
- {{ item.progress }}%
171
- </template>
177
+ <span class="mint-batch-progress__item-status">{{ statusText(item) }}</span>
172
178
  <button
173
179
  v-if="item.status === 'error'"
174
180
  type="button"
@@ -186,6 +192,10 @@ watch(
186
192
  Cancel
187
193
  </button>
188
194
  </span>
195
+
196
+ <span class="mint-batch-progress__item-progress" aria-hidden="true">
197
+ <span class="mint-batch-progress__item-progress-bar" :style="{ width: `${itemPercent(item)}%` }" />
198
+ </span>
189
199
  </div>
190
200
 
191
201
  <div v-if="item.status === 'error' && item.message" class="mint-batch-progress__item-message">
@@ -76,7 +76,8 @@ function initLegendState() {
76
76
  <ChartContainer
77
77
  title="Experiment Results"
78
78
  empty
79
- empty-text="No results found. Run an analysis to see data here."
79
+ empty-text="No samples selected"
80
+ empty-hint="Pick samples to draw the distribution."
80
81
  />
81
82
  </div>
82
83
  </Variant>
@@ -2,7 +2,7 @@
2
2
  /** Wraps a chart with header, toolbar slot, loading overlay, empty state, and legend slot. */
3
3
  import type { ChartLegendItem } from '../types'
4
4
  import LoadingSpinner from './LoadingSpinner.vue'
5
- import EmptyState from './EmptyState.vue'
5
+ import { ChartLine } from 'lucide-vue-next'
6
6
 
7
7
  interface Props {
8
8
  title?: string
@@ -10,6 +10,8 @@ interface Props {
10
10
  loading?: boolean
11
11
  empty?: boolean
12
12
  emptyText?: string
13
+ /** Muted line under the empty title. */
14
+ emptyHint?: string
13
15
  /** `frame` fills its parent and uses compact workbench chrome. */
14
16
  variant?: 'card' | 'frame'
15
17
  /** Series shown as clickable items in the header; a click emits `legend-toggle`. */
@@ -77,11 +79,11 @@ defineSlots<{
77
79
  <!-- Empty state -->
78
80
  <template v-else-if="empty">
79
81
  <slot name="empty">
80
- <EmptyState
81
- :title="emptyText"
82
- size="sm"
83
- icon-path="M3 13.125C3 12.504 3.504 12 4.125 12h2.25c.621 0 1.125.504 1.125 1.125v6.75C7.5 20.496 6.996 21 6.375 21h-2.25A1.125 1.125 0 013 19.875v-6.75zM9.75 8.625c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125v11.25c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 01-1.125-1.125V8.625zM16.5 4.125c0-.621.504-1.125 1.125-1.125h2.25C20.496 3 21 3.504 21 4.125v15.75c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 01-1.125-1.125V4.125z"
84
- />
82
+ <div class="mint-chart__empty">
83
+ <ChartLine :size="22" aria-hidden="true" />
84
+ <span class="mint-chart__empty-title">{{ emptyText }}</span>
85
+ <span v-if="emptyHint" class="mint-chart__empty-hint">{{ emptyHint }}</span>
86
+ </div>
85
87
  </slot>
86
88
  </template>
87
89
 
@@ -49,7 +49,7 @@ function initPlayground() {
49
49
  <template #default="{ state }">
50
50
  <div style="padding: 2rem; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1rem;">
51
51
  <BaseButton variant="secondary" @click="dialogOpen = true">Open dialog</BaseButton>
52
- <div v-if="lastAction" style="font-family: 'Fira Code', monospace; font-size: 0.75rem; color: var(--text-muted);">
52
+ <div v-if="lastAction" style="font-family: var(--font-mono); font-size: 0.75rem; color: var(--text-muted);">
53
53
  Last event: <code>{{ lastAction }}</code>
54
54
  </div>
55
55
  <ConfirmDialog
@@ -62,7 +62,7 @@ const defaultIconPaths = [
62
62
  </div>
63
63
  </div>
64
64
  <div v-if="actionLabel" class="mint-empty-state__action">
65
- <BaseButton variant="secondary" @click="emit('action')">
65
+ <BaseButton variant="secondary" size="sm" @click="emit('action')">
66
66
  {{ actionLabel }}
67
67
  </BaseButton>
68
68
  </div>