@morscherlab/mint-sdk 1.0.0-alpha.8 → 1.0.0-alpha.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/README.md +15 -15
- package/dist/{auth-BYmxZdJl.js → auth-DsI0rQ7_.js} +6 -6
- package/dist/auth-DsI0rQ7_.js.map +1 -0
- package/dist/components/index.js +2 -2
- package/dist/{components-CKf-UpGi.js → components-CzbQQPCb.js} +1429 -1429
- package/dist/components-CzbQQPCb.js.map +1 -0
- package/dist/composables/index.js +2 -2
- package/dist/composables/usePlatformContext.d.ts +3 -3
- package/dist/{composables-D0QfFzq1.js → composables-BXklV5ii.js} +3 -3
- package/dist/{composables-D0QfFzq1.js.map → composables-BXklV5ii.js.map} +1 -1
- package/dist/index.js +4 -4
- package/dist/install.d.ts +3 -3
- package/dist/install.js +5 -5
- package/dist/install.js.map +1 -1
- package/dist/stores/auth.d.ts +1 -1
- package/dist/stores/index.js +1 -1
- package/dist/stores/settings.d.ts +1 -1
- package/dist/styles.css +5388 -5388
- package/dist/types/platform.d.ts +1 -1
- package/dist/{useScheduleDrag-DAJueTbK.js → useScheduleDrag-CxBeqYcu.js} +331 -331
- package/dist/useScheduleDrag-CxBeqYcu.js.map +1 -0
- package/package.json +2 -2
- package/src/__tests__/components/AppLayout.test.ts +23 -23
- package/src/__tests__/components/AppSidebar.test.ts +29 -29
- package/src/__tests__/components/AppTopBar.test.ts +45 -45
- package/src/__tests__/components/BaseInput.test.ts +2 -2
- package/src/__tests__/components/BasePill.test.ts +37 -37
- package/src/__tests__/components/Calendar.test.ts +52 -52
- package/src/__tests__/components/CollapsibleCard.test.ts +81 -81
- package/src/__tests__/components/DataFrame.test.ts +80 -80
- package/src/__tests__/components/DropdownButton.test.ts +80 -80
- package/src/__tests__/composables/usePlatformContext.test.ts +1 -1
- package/src/components/AlertBox.story.vue +1 -1
- package/src/components/AlertBox.vue +14 -14
- package/src/components/AppAvatarMenu.vue +26 -26
- package/src/components/AppContainer.vue +3 -3
- package/src/components/AppLayout.vue +7 -7
- package/src/components/AppPageSelector.vue +30 -30
- package/src/components/AppPillNav.vue +10 -10
- package/src/components/AppPluginSwitcher.vue +31 -31
- package/src/components/AppSidebar.vue +8 -8
- package/src/components/AppTopBar.story.vue +7 -7
- package/src/components/AppTopBar.vue +102 -102
- package/src/components/AuditTrail.vue +19 -19
- package/src/components/AutoGroupModal.vue +76 -76
- package/src/components/Avatar.vue +6 -6
- package/src/components/BaseButton.vue +6 -6
- package/src/components/BaseCheckbox.vue +9 -9
- package/src/components/BaseInput.vue +4 -4
- package/src/components/BaseModal.story.vue +1 -1
- package/src/components/BaseModal.vue +14 -14
- package/src/components/BasePill.vue +9 -9
- package/src/components/BaseRadioGroup.vue +21 -21
- package/src/components/BaseSelect.vue +6 -6
- package/src/components/BaseSlider.vue +8 -8
- package/src/components/BaseTabs.vue +7 -7
- package/src/components/BaseTextarea.vue +5 -5
- package/src/components/BaseToggle.vue +10 -10
- package/src/components/BatchProgressList.vue +25 -25
- package/src/components/Breadcrumb.vue +8 -8
- package/src/components/Calendar.vue +19 -19
- package/src/components/ChartContainer.vue +9 -9
- package/src/components/ChemicalFormula.vue +7 -7
- package/src/components/CollapsibleCard.vue +20 -20
- package/src/components/ColorSlider.vue +6 -6
- package/src/components/ConcentrationInput.vue +12 -12
- package/src/components/ConfirmDialog.story.vue +1 -1
- package/src/components/ConfirmDialog.vue +7 -7
- package/src/components/DataFrame.vue +40 -40
- package/src/components/DatePicker.vue +29 -29
- package/src/components/DateTimePicker.vue +41 -41
- package/src/components/Divider.vue +9 -9
- package/src/components/DoseCalculator.vue +66 -66
- package/src/components/DropdownButton.vue +19 -19
- package/src/components/EmptyState.vue +9 -9
- package/src/components/ExperimentCodeBadge.vue +3 -3
- package/src/components/ExperimentDataViewer.vue +25 -25
- package/src/components/ExperimentPopover.vue +35 -35
- package/src/components/ExperimentSelectorModal.vue +40 -40
- package/src/components/ExperimentTimeline.vue +48 -48
- package/src/components/FileUploader.vue +31 -31
- package/src/components/FitPanel.vue +9 -9
- package/src/components/FormActions.vue +1 -1
- package/src/components/FormBuilder.vue +2 -2
- package/src/components/FormField.vue +7 -7
- package/src/components/FormSection.vue +7 -7
- package/src/components/FormulaInput.vue +10 -10
- package/src/components/GroupAssigner.vue +40 -40
- package/src/components/GroupingModal.vue +45 -45
- package/src/components/IconButton.vue +6 -6
- package/src/components/LoadingSpinner.vue +5 -5
- package/src/components/MoleculeInput.vue +21 -21
- package/src/components/MultiSelect.vue +13 -13
- package/src/components/NumberInput.vue +13 -13
- package/src/components/PlateMapEditor.vue +63 -63
- package/src/components/ProgressBar.vue +18 -18
- package/src/components/ProtocolStepEditor.vue +57 -57
- package/src/components/RackEditor.vue +28 -28
- package/src/components/ReagentEditor.vue +61 -61
- package/src/components/ReagentList.vue +49 -49
- package/src/components/ResourceCard.vue +28 -28
- package/src/components/SampleHierarchyTree.vue +13 -13
- package/src/components/SampleLegend.vue +12 -12
- package/src/components/SampleSelector.vue +104 -104
- package/src/components/ScheduleCalendar.vue +42 -42
- package/src/components/ScientificNumber.vue +11 -11
- package/src/components/SegmentedControl.vue +12 -12
- package/src/components/SequenceInput.vue +32 -32
- package/src/components/SettingsButton.vue +5 -5
- package/src/components/SettingsModal.vue +17 -17
- package/src/components/StatusIndicator.vue +5 -5
- package/src/components/StepWizard.vue +16 -16
- package/src/components/TagsInput.vue +20 -20
- package/src/components/ThemeToggle.vue +3 -3
- package/src/components/TimePicker.vue +21 -21
- package/src/components/TimeRangeInput.vue +5 -5
- package/src/components/ToastNotification.vue +8 -8
- package/src/components/Tooltip.vue +7 -7
- package/src/components/UnitInput.vue +12 -12
- package/src/components/WellEditPopup.vue +28 -28
- package/src/components/WellPlate.vue +37 -37
- package/src/composables/useAppExperiment.ts +1 -1
- package/src/composables/usePlatformContext.ts +16 -16
- package/src/composables/useProtocolTemplates.ts +1 -1
- package/src/install.ts +3 -3
- package/src/stores/auth.ts +3 -3
- package/src/stores/settings.ts +2 -2
- package/src/styles/components/alert-box.css +30 -30
- package/src/styles/components/app-avatar-menu.css +23 -23
- package/src/styles/components/app-container.css +6 -6
- package/src/styles/components/app-layout.css +15 -15
- package/src/styles/components/app-page-selector.css +26 -26
- package/src/styles/components/app-pill-nav.css +7 -7
- package/src/styles/components/app-plugin-switcher.css +27 -27
- package/src/styles/components/app-sidebar.css +24 -24
- package/src/styles/components/app-top-bar.css +65 -65
- package/src/styles/components/audit-trail.css +29 -29
- package/src/styles/components/auto-group-modal.css +91 -91
- package/src/styles/components/avatar.css +15 -15
- package/src/styles/components/batch-progress-list.css +40 -40
- package/src/styles/components/breadcrumb.css +8 -8
- package/src/styles/components/button.css +31 -31
- package/src/styles/components/calendar.css +27 -27
- package/src/styles/components/chart-container.css +9 -9
- package/src/styles/components/checkbox.css +20 -20
- package/src/styles/components/chemical-formula.css +8 -8
- package/src/styles/components/collapsible-card.css +35 -35
- package/src/styles/components/color-slider.css +8 -8
- package/src/styles/components/concentration-input.css +27 -27
- package/src/styles/components/confirm-dialog.css +32 -32
- package/src/styles/components/dataframe.css +66 -66
- package/src/styles/components/date-picker.css +40 -40
- package/src/styles/components/datetime-picker.css +37 -37
- package/src/styles/components/divider.css +13 -13
- package/src/styles/components/dose-calculator.css +43 -43
- package/src/styles/components/dropdown-button.css +46 -46
- package/src/styles/components/empty-state.css +44 -44
- package/src/styles/components/experiment-code-badge.css +8 -8
- package/src/styles/components/experiment-data-viewer.css +23 -23
- package/src/styles/components/experiment-popover.css +97 -97
- package/src/styles/components/experiment-selector-modal.css +39 -39
- package/src/styles/components/experiment-timeline.css +98 -98
- package/src/styles/components/file-uploader.css +44 -44
- package/src/styles/components/fit-panel.css +12 -12
- package/src/styles/components/form-builder.css +11 -11
- package/src/styles/components/form-field.css +7 -7
- package/src/styles/components/formula-input.css +17 -17
- package/src/styles/components/group-assigner.css +26 -26
- package/src/styles/components/grouping-modal.css +51 -51
- package/src/styles/components/icon-button.css +41 -41
- package/src/styles/components/input.css +13 -13
- package/src/styles/components/loading-spinner.css +12 -12
- package/src/styles/components/modal.css +69 -69
- package/src/styles/components/molecule-input.css +27 -27
- package/src/styles/components/multi-select.css +23 -23
- package/src/styles/components/number-input.css +32 -32
- package/src/styles/components/pill.css +37 -37
- package/src/styles/components/plate-map-editor.css +67 -67
- package/src/styles/components/progress-bar.css +41 -41
- package/src/styles/components/protocol-step-editor.css +63 -63
- package/src/styles/components/rack-editor.css +34 -34
- package/src/styles/components/radio-group.css +41 -41
- package/src/styles/components/reagent-editor.css +70 -70
- package/src/styles/components/reagent-list.css +65 -65
- package/src/styles/components/resource-card.css +52 -52
- package/src/styles/components/sample-hierarchy-tree.css +56 -56
- package/src/styles/components/sample-legend.css +37 -37
- package/src/styles/components/sample-selector.css +121 -121
- package/src/styles/components/schedule-calendar.css +67 -67
- package/src/styles/components/scientific-number.css +11 -11
- package/src/styles/components/segmented-control.css +33 -33
- package/src/styles/components/select.css +11 -11
- package/src/styles/components/sequence-input.css +29 -29
- package/src/styles/components/settings-button.css +16 -16
- package/src/styles/components/settings-modal.css +14 -14
- package/src/styles/components/skeleton.css +2 -2
- package/src/styles/components/slider.css +10 -10
- package/src/styles/components/status-indicator.css +12 -12
- package/src/styles/components/step-wizard.css +32 -32
- package/src/styles/components/tabs.css +16 -16
- package/src/styles/components/tags-input.css +46 -46
- package/src/styles/components/textarea.css +17 -17
- package/src/styles/components/theme-toggle.css +13 -13
- package/src/styles/components/time-picker.css +28 -28
- package/src/styles/components/time-range-input.css +8 -8
- package/src/styles/components/toast.css +18 -18
- package/src/styles/components/toggle.css +27 -27
- package/src/styles/components/tooltip.css +18 -18
- package/src/styles/components/unit-input.css +25 -25
- package/src/styles/components/well-edit-popup.css +32 -32
- package/src/styles/components/well-plate.css +49 -49
- package/src/styles/index.css +1 -1
- package/src/styles/variables.css +3 -3
- package/src/types/platform.ts +6 -6
- package/dist/auth-BYmxZdJl.js.map +0 -1
- package/dist/components-CKf-UpGi.js.map +0 -1
- package/dist/useScheduleDrag-DAJueTbK.js.map +0 -1
|
@@ -218,7 +218,7 @@ const isFirstStep = computed(() => currentStep.value === 0)
|
|
|
218
218
|
@update:model-value="emit('update:modelValue', $event)"
|
|
219
219
|
@close="handleCancel"
|
|
220
220
|
>
|
|
221
|
-
<div class="
|
|
221
|
+
<div class="mint-auto-group">
|
|
222
222
|
<StepWizard
|
|
223
223
|
ref="wizardRef"
|
|
224
224
|
v-model="currentStep"
|
|
@@ -228,9 +228,9 @@ const isFirstStep = computed(() => currentStep.value === 0)
|
|
|
228
228
|
>
|
|
229
229
|
<!-- Step: Input -->
|
|
230
230
|
<template #step-input>
|
|
231
|
-
<div class="
|
|
231
|
+
<div class="mint-auto-group__input-step">
|
|
232
232
|
<!-- Mode toggle -->
|
|
233
|
-
<div class="
|
|
233
|
+
<div class="mint-auto-group__mode-toggle">
|
|
234
234
|
<BaseButton
|
|
235
235
|
v-if="experimentId || designData"
|
|
236
236
|
:variant="autoGroup.inputMode.value === 'experiment' ? 'primary' : 'secondary'"
|
|
@@ -257,56 +257,56 @@ const isFirstStep = computed(() => currentStep.value === 0)
|
|
|
257
257
|
</div>
|
|
258
258
|
|
|
259
259
|
<!-- Experiment mode -->
|
|
260
|
-
<div v-if="autoGroup.inputMode.value === 'experiment'" class="
|
|
261
|
-
<div v-if="experimentLoading" class="
|
|
260
|
+
<div v-if="autoGroup.inputMode.value === 'experiment'" class="mint-auto-group__experiment">
|
|
261
|
+
<div v-if="experimentLoading" class="mint-auto-group__experiment-loading">
|
|
262
262
|
<LoadingSpinner size="sm" />
|
|
263
263
|
<span>Loading experiment metadata…</span>
|
|
264
264
|
</div>
|
|
265
|
-
<div v-else-if="experimentError" class="
|
|
265
|
+
<div v-else-if="experimentError" class="mint-auto-group__experiment-error">
|
|
266
266
|
<p>{{ experimentError }}</p>
|
|
267
267
|
<p>
|
|
268
|
-
Switch to <button type="button" class="
|
|
269
|
-
or <button type="button" class="
|
|
268
|
+
Switch to <button type="button" class="mint-auto-group__link-btn" @click="autoGroup.inputMode.value = 'paste'">Paste</button>
|
|
269
|
+
or <button type="button" class="mint-auto-group__link-btn" @click="autoGroup.inputMode.value = 'csv'">CSV</button> mode instead.
|
|
270
270
|
</p>
|
|
271
271
|
</div>
|
|
272
|
-
<div v-else-if="autoGroup.csvData.value" class="
|
|
273
|
-
<div class="
|
|
274
|
-
<span class="
|
|
272
|
+
<div v-else-if="autoGroup.csvData.value" class="mint-auto-group__experiment-loaded">
|
|
273
|
+
<div class="mint-auto-group__experiment-summary">
|
|
274
|
+
<span class="mint-auto-group__experiment-stat">
|
|
275
275
|
<strong>{{ autoGroup.csvData.value.rows.length }}</strong> samples
|
|
276
276
|
</span>
|
|
277
|
-
<span class="
|
|
277
|
+
<span class="mint-auto-group__experiment-stat">
|
|
278
278
|
<strong>{{ experimentFieldNames.length }}</strong> metadata fields
|
|
279
279
|
</span>
|
|
280
280
|
</div>
|
|
281
|
-
<div class="
|
|
281
|
+
<div class="mint-auto-group__experiment-fields">
|
|
282
282
|
<span
|
|
283
283
|
v-for="col in experimentFieldNames"
|
|
284
284
|
:key="col"
|
|
285
|
-
class="
|
|
285
|
+
class="mint-auto-group__field-value"
|
|
286
286
|
>{{ col }}</span>
|
|
287
287
|
</div>
|
|
288
288
|
</div>
|
|
289
289
|
</div>
|
|
290
290
|
|
|
291
291
|
<!-- Paste mode -->
|
|
292
|
-
<div v-if="autoGroup.inputMode.value === 'paste'" class="
|
|
292
|
+
<div v-if="autoGroup.inputMode.value === 'paste'" class="mint-auto-group__paste">
|
|
293
293
|
<textarea
|
|
294
294
|
v-model="autoGroup.rawText.value"
|
|
295
|
-
class="
|
|
295
|
+
class="mint-auto-group__textarea"
|
|
296
296
|
rows="12"
|
|
297
297
|
placeholder="Paste sample names, one per line..."
|
|
298
298
|
/>
|
|
299
|
-
<div v-if="autoGroup.samples.value.length > 0" class="
|
|
299
|
+
<div v-if="autoGroup.samples.value.length > 0" class="mint-auto-group__sample-count">
|
|
300
300
|
{{ autoGroup.samples.value.length }} samples
|
|
301
301
|
</div>
|
|
302
302
|
</div>
|
|
303
303
|
|
|
304
304
|
<!-- CSV mode -->
|
|
305
|
-
<div v-if="autoGroup.inputMode.value === 'csv'" class="
|
|
305
|
+
<div v-if="autoGroup.inputMode.value === 'csv'" class="mint-auto-group__csv">
|
|
306
306
|
<div v-if="!autoGroup.csvData.value"
|
|
307
307
|
:class="[
|
|
308
|
-
'
|
|
309
|
-
isDragOver ? '
|
|
308
|
+
'mint-auto-group__dropzone',
|
|
309
|
+
isDragOver ? 'mint-auto-group__dropzone--dragover' : '',
|
|
310
310
|
]"
|
|
311
311
|
@drop="handleFileDrop"
|
|
312
312
|
@dragover.prevent="isDragOver = true"
|
|
@@ -315,34 +315,34 @@ const isFirstStep = computed(() => currentStep.value === 0)
|
|
|
315
315
|
<input
|
|
316
316
|
type="file"
|
|
317
317
|
accept=".csv,.tsv"
|
|
318
|
-
class="
|
|
318
|
+
class="mint-auto-group__file-input"
|
|
319
319
|
@change="handleFileInput"
|
|
320
320
|
/>
|
|
321
|
-
<svg class="
|
|
321
|
+
<svg class="mint-auto-group__upload-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
322
322
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9 17v-2m3 2v-4m3 4v-6m2 10H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
|
|
323
323
|
</svg>
|
|
324
|
-
<p class="
|
|
325
|
-
<span class="
|
|
324
|
+
<p class="mint-auto-group__upload-text">
|
|
325
|
+
<span class="mint-auto-group__upload-highlight">Click to upload</span>
|
|
326
326
|
or drag and drop a CSV file
|
|
327
327
|
</p>
|
|
328
|
-
<p class="
|
|
328
|
+
<p class="mint-auto-group__upload-hint">
|
|
329
329
|
CSV or TSV with a header row. First column or column named
|
|
330
330
|
"Sample" / "File Name" is used as sample identifier.
|
|
331
331
|
Other columns become grouping fields.
|
|
332
332
|
</p>
|
|
333
333
|
</div>
|
|
334
334
|
|
|
335
|
-
<div v-if="csvError && !autoGroup.csvData.value" class="
|
|
335
|
+
<div v-if="csvError && !autoGroup.csvData.value" class="mint-auto-group__csv-error">
|
|
336
336
|
{{ csvError }}
|
|
337
337
|
</div>
|
|
338
338
|
|
|
339
|
-
<div v-if="autoGroup.csvData.value" class="
|
|
340
|
-
<svg class="
|
|
339
|
+
<div v-if="autoGroup.csvData.value" class="mint-auto-group__file-info">
|
|
340
|
+
<svg class="mint-auto-group__file-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
341
341
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
|
|
342
342
|
</svg>
|
|
343
|
-
<span class="
|
|
344
|
-
<span class="
|
|
345
|
-
<button type="button" class="
|
|
343
|
+
<span class="mint-auto-group__file-name">{{ csvFileName }}</span>
|
|
344
|
+
<span class="mint-auto-group__file-rows">{{ autoGroup.csvData.value.rows.length }} rows</span>
|
|
345
|
+
<button type="button" class="mint-auto-group__file-clear" @click="clearCsvFile">
|
|
346
346
|
Change file
|
|
347
347
|
</button>
|
|
348
348
|
</div>
|
|
@@ -352,15 +352,15 @@ const isFirstStep = computed(() => currentStep.value === 0)
|
|
|
352
352
|
|
|
353
353
|
<!-- Step: Outliers -->
|
|
354
354
|
<template #step-outliers>
|
|
355
|
-
<div class="
|
|
356
|
-
<div class="
|
|
355
|
+
<div class="mint-auto-group__outlier-step">
|
|
356
|
+
<div class="mint-auto-group__outlier-banner">
|
|
357
357
|
{{ autoGroup.outliers.value.length }} of {{ autoGroup.samples.value.length }}
|
|
358
358
|
samples have irregular structure
|
|
359
359
|
(fewer than {{ autoGroup.dominantFieldCount.value }} fields, delimiter
|
|
360
360
|
<code>{{ autoGroup.delimiter.value }}</code>)
|
|
361
361
|
</div>
|
|
362
362
|
|
|
363
|
-
<div class="
|
|
363
|
+
<div class="mint-auto-group__outlier-batch">
|
|
364
364
|
<BaseButton size="sm" variant="secondary" @click="autoGroup.setAllOutlierActions('include')">
|
|
365
365
|
Include All
|
|
366
366
|
</BaseButton>
|
|
@@ -369,30 +369,30 @@ const isFirstStep = computed(() => currentStep.value === 0)
|
|
|
369
369
|
</BaseButton>
|
|
370
370
|
</div>
|
|
371
371
|
|
|
372
|
-
<div class="
|
|
372
|
+
<div class="mint-auto-group__outlier-list">
|
|
373
373
|
<div
|
|
374
374
|
v-for="outlier in autoGroup.outliers.value"
|
|
375
375
|
:key="outlier.index"
|
|
376
|
-
class="
|
|
376
|
+
class="mint-auto-group__outlier-item"
|
|
377
377
|
>
|
|
378
|
-
<div class="
|
|
379
|
-
<code class="
|
|
380
|
-
<span class="
|
|
378
|
+
<div class="mint-auto-group__outlier-info">
|
|
379
|
+
<code class="mint-auto-group__outlier-name">{{ outlier.sample }}</code>
|
|
380
|
+
<span class="mint-auto-group__outlier-badge">{{ outlier.fieldCount }} fields</span>
|
|
381
381
|
</div>
|
|
382
|
-
<div class="
|
|
382
|
+
<div class="mint-auto-group__outlier-actions">
|
|
383
383
|
<button
|
|
384
384
|
type="button"
|
|
385
|
-
:class="['
|
|
385
|
+
:class="['mint-auto-group__action-btn', outlier.action === 'include' ? 'mint-auto-group__action-btn--active' : '']"
|
|
386
386
|
@click="autoGroup.setOutlierAction(outlier.index, 'include')"
|
|
387
387
|
>Include</button>
|
|
388
388
|
<button
|
|
389
389
|
type="button"
|
|
390
|
-
:class="['
|
|
390
|
+
:class="['mint-auto-group__action-btn', outlier.action === 'exclude' ? 'mint-auto-group__action-btn--active mint-auto-group__action-btn--exclude' : '']"
|
|
391
391
|
@click="autoGroup.setOutlierAction(outlier.index, 'exclude')"
|
|
392
392
|
>Exclude</button>
|
|
393
393
|
<button
|
|
394
394
|
type="button"
|
|
395
|
-
:class="['
|
|
395
|
+
:class="['mint-auto-group__action-btn', outlier.action === 'qc' ? 'mint-auto-group__action-btn--active mint-auto-group__action-btn--qc' : '']"
|
|
396
396
|
@click="autoGroup.setOutlierAction(outlier.index, 'qc')"
|
|
397
397
|
>QC</button>
|
|
398
398
|
</div>
|
|
@@ -403,50 +403,50 @@ const isFirstStep = computed(() => currentStep.value === 0)
|
|
|
403
403
|
|
|
404
404
|
<!-- Step: Fields -->
|
|
405
405
|
<template #step-fields>
|
|
406
|
-
<div class="
|
|
407
|
-
<div class="
|
|
406
|
+
<div class="mint-auto-group__field-step">
|
|
407
|
+
<div class="mint-auto-group__field-grid">
|
|
408
408
|
<div
|
|
409
409
|
v-for="col in autoGroup.effectiveColumns.value"
|
|
410
410
|
:key="col.index"
|
|
411
411
|
:class="[
|
|
412
|
-
'
|
|
413
|
-
autoGroup.enabledFields.value.has(col.index) ? '
|
|
412
|
+
'mint-auto-group__field-card',
|
|
413
|
+
autoGroup.enabledFields.value.has(col.index) ? 'mint-auto-group__field-card--enabled' : '',
|
|
414
414
|
]"
|
|
415
415
|
>
|
|
416
|
-
<div class="
|
|
417
|
-
<label class="
|
|
416
|
+
<div class="mint-auto-group__field-header">
|
|
417
|
+
<label class="mint-auto-group__field-toggle">
|
|
418
418
|
<input
|
|
419
419
|
type="checkbox"
|
|
420
420
|
:checked="autoGroup.enabledFields.value.has(col.index)"
|
|
421
421
|
@change="autoGroup.toggleField(col.index)"
|
|
422
422
|
/>
|
|
423
|
-
<span class="
|
|
423
|
+
<span class="mint-auto-group__field-toggle-label">Group by</span>
|
|
424
424
|
</label>
|
|
425
|
-
<span class="
|
|
425
|
+
<span class="mint-auto-group__field-cardinality">{{ col.cardinality }} unique</span>
|
|
426
426
|
</div>
|
|
427
427
|
|
|
428
428
|
<BaseInput
|
|
429
429
|
:model-value="col.name"
|
|
430
430
|
placeholder="Field name..."
|
|
431
|
-
class="
|
|
431
|
+
class="mint-auto-group__field-name-input"
|
|
432
432
|
@update:model-value="autoGroup.renameField(col.index, String($event ?? ''))"
|
|
433
433
|
/>
|
|
434
434
|
|
|
435
|
-
<div class="
|
|
435
|
+
<div class="mint-auto-group__field-values">
|
|
436
436
|
<span
|
|
437
437
|
v-for="val in col.uniqueValues.slice(0, 5)"
|
|
438
438
|
:key="val"
|
|
439
|
-
class="
|
|
439
|
+
class="mint-auto-group__field-value"
|
|
440
440
|
>{{ val }}</span>
|
|
441
441
|
<span
|
|
442
442
|
v-if="col.uniqueValues.length > 5"
|
|
443
|
-
class="
|
|
443
|
+
class="mint-auto-group__field-more"
|
|
444
444
|
>+{{ col.uniqueValues.length - 5 }} more</span>
|
|
445
445
|
</div>
|
|
446
446
|
</div>
|
|
447
447
|
</div>
|
|
448
448
|
|
|
449
|
-
<div v-if="autoGroup.enabledFields.value.size > 0" class="
|
|
449
|
+
<div v-if="autoGroup.enabledFields.value.size > 0" class="mint-auto-group__field-summary">
|
|
450
450
|
Grouping by:
|
|
451
451
|
<strong>{{
|
|
452
452
|
autoGroup.effectiveColumns.value
|
|
@@ -456,7 +456,7 @@ const isFirstStep = computed(() => currentStep.value === 0)
|
|
|
456
456
|
}}</strong>
|
|
457
457
|
</div>
|
|
458
458
|
|
|
459
|
-
<div v-if="autoGroup.enabledFields.value.size === 0" class="
|
|
459
|
+
<div v-if="autoGroup.enabledFields.value.size === 0" class="mint-auto-group__field-warning">
|
|
460
460
|
Select at least one field for grouping
|
|
461
461
|
</div>
|
|
462
462
|
</div>
|
|
@@ -464,15 +464,15 @@ const isFirstStep = computed(() => currentStep.value === 0)
|
|
|
464
464
|
|
|
465
465
|
<!-- Step: Preview -->
|
|
466
466
|
<template #step-preview>
|
|
467
|
-
<div class="
|
|
468
|
-
<div class="
|
|
469
|
-
<span class="
|
|
467
|
+
<div class="mint-auto-group__preview-step">
|
|
468
|
+
<div class="mint-auto-group__preview-summary">
|
|
469
|
+
<span class="mint-auto-group__preview-stat">
|
|
470
470
|
<strong>{{ autoGroup.groups.value.length }}</strong> groups
|
|
471
471
|
</span>
|
|
472
|
-
<span class="
|
|
472
|
+
<span class="mint-auto-group__preview-stat">
|
|
473
473
|
<strong>{{ autoGroup.groups.value.reduce((sum, g) => sum + g.samples.length, 0) }}</strong> samples
|
|
474
474
|
</span>
|
|
475
|
-
<span v-if="autoGroup.excludedSamples.value.length > 0" class="
|
|
475
|
+
<span v-if="autoGroup.excludedSamples.value.length > 0" class="mint-auto-group__preview-stat mint-auto-group__preview-stat--excluded">
|
|
476
476
|
<strong>{{ autoGroup.excludedSamples.value.length }}</strong> excluded
|
|
477
477
|
</span>
|
|
478
478
|
</div>
|
|
@@ -485,40 +485,40 @@ const isFirstStep = computed(() => currentStep.value === 0)
|
|
|
485
485
|
Your enabled fields produce a unique key for every row, so no aggregation is happening. Go back to <em>Fields</em> and disable any column whose values are unique per sample.
|
|
486
486
|
</AlertBox>
|
|
487
487
|
|
|
488
|
-
<div class="
|
|
488
|
+
<div class="mint-auto-group__preview-groups">
|
|
489
489
|
<details
|
|
490
490
|
v-for="group in autoGroup.groups.value"
|
|
491
491
|
:key="group.name"
|
|
492
|
-
class="
|
|
492
|
+
class="mint-auto-group__preview-group"
|
|
493
493
|
>
|
|
494
|
-
<summary class="
|
|
494
|
+
<summary class="mint-auto-group__preview-group-header">
|
|
495
495
|
<span
|
|
496
|
-
class="
|
|
496
|
+
class="mint-auto-group__preview-dot"
|
|
497
497
|
:style="{ backgroundColor: group.color }"
|
|
498
498
|
/>
|
|
499
|
-
<span class="
|
|
499
|
+
<span class="mint-auto-group__preview-group-name">{{ group.name }}</span>
|
|
500
500
|
<span
|
|
501
|
-
class="
|
|
501
|
+
class="mint-auto-group__preview-group-count"
|
|
502
502
|
:style="{ backgroundColor: group.color + '20', color: group.color }"
|
|
503
503
|
>{{ group.samples.length }}</span>
|
|
504
504
|
</summary>
|
|
505
|
-
<div class="
|
|
505
|
+
<div class="mint-auto-group__preview-samples">
|
|
506
506
|
<span
|
|
507
507
|
v-for="sample in group.samples"
|
|
508
508
|
:key="sample"
|
|
509
|
-
class="
|
|
509
|
+
class="mint-auto-group__preview-sample"
|
|
510
510
|
>{{ sample }}</span>
|
|
511
511
|
</div>
|
|
512
512
|
</details>
|
|
513
513
|
</div>
|
|
514
514
|
|
|
515
|
-
<div v-if="autoGroup.excludedSamples.value.length > 0" class="
|
|
516
|
-
<div class="
|
|
517
|
-
<div class="
|
|
515
|
+
<div v-if="autoGroup.excludedSamples.value.length > 0" class="mint-auto-group__preview-excluded">
|
|
516
|
+
<div class="mint-auto-group__preview-excluded-title">Excluded Samples</div>
|
|
517
|
+
<div class="mint-auto-group__preview-excluded-list">
|
|
518
518
|
<span
|
|
519
519
|
v-for="sample in autoGroup.excludedSamples.value"
|
|
520
520
|
:key="sample"
|
|
521
|
-
class="
|
|
521
|
+
class="mint-auto-group__preview-sample mint-auto-group__preview-sample--excluded"
|
|
522
522
|
>{{ sample }}</span>
|
|
523
523
|
</div>
|
|
524
524
|
</div>
|
|
@@ -527,11 +527,11 @@ const isFirstStep = computed(() => currentStep.value === 0)
|
|
|
527
527
|
|
|
528
528
|
<!-- Custom navigation -->
|
|
529
529
|
<template #navigation="{ goBack, goNext, canProceed }">
|
|
530
|
-
<div class="
|
|
530
|
+
<div class="mint-auto-group__nav">
|
|
531
531
|
<BaseButton variant="secondary" @click="handleCancel">
|
|
532
532
|
Cancel
|
|
533
533
|
</BaseButton>
|
|
534
|
-
<div class="
|
|
534
|
+
<div class="mint-auto-group__nav-spacer" />
|
|
535
535
|
<BaseButton
|
|
536
536
|
v-if="!isFirstStep"
|
|
537
537
|
variant="secondary"
|
|
@@ -40,26 +40,26 @@ const backgroundColor = computed(() => {
|
|
|
40
40
|
|
|
41
41
|
<template>
|
|
42
42
|
<span
|
|
43
|
-
:class="['
|
|
43
|
+
:class="['mint-avatar', `mint-avatar--${size}`]"
|
|
44
44
|
role="img"
|
|
45
45
|
:aria-label="alt || name || 'User avatar'"
|
|
46
46
|
>
|
|
47
47
|
<span
|
|
48
|
-
class="
|
|
48
|
+
class="mint-avatar__face"
|
|
49
49
|
:style="backgroundColor ? { backgroundColor } : undefined"
|
|
50
50
|
>
|
|
51
51
|
<img
|
|
52
52
|
v-if="src"
|
|
53
53
|
:src="src"
|
|
54
54
|
:alt="alt || name || ''"
|
|
55
|
-
class="
|
|
55
|
+
class="mint-avatar__image"
|
|
56
56
|
>
|
|
57
|
-
<span v-else-if="computedInitials" class="
|
|
57
|
+
<span v-else-if="computedInitials" class="mint-avatar__initials">
|
|
58
58
|
{{ computedInitials }}
|
|
59
59
|
</span>
|
|
60
60
|
<svg
|
|
61
61
|
v-else
|
|
62
|
-
class="
|
|
62
|
+
class="mint-avatar__fallback"
|
|
63
63
|
viewBox="0 0 24 24"
|
|
64
64
|
fill="currentColor"
|
|
65
65
|
>
|
|
@@ -68,7 +68,7 @@ const backgroundColor = computed(() => {
|
|
|
68
68
|
</span>
|
|
69
69
|
<span
|
|
70
70
|
v-if="status"
|
|
71
|
-
:class="['
|
|
71
|
+
:class="['mint-avatar__status', `mint-avatar__status--${status}`]"
|
|
72
72
|
aria-hidden="true"
|
|
73
73
|
/>
|
|
74
74
|
</span>
|
|
@@ -36,17 +36,17 @@ function handleClick(event: MouseEvent) {
|
|
|
36
36
|
:type="type"
|
|
37
37
|
:disabled="disabled || loading"
|
|
38
38
|
:class="[
|
|
39
|
-
'
|
|
40
|
-
`
|
|
41
|
-
`
|
|
42
|
-
fullWidth ? '
|
|
43
|
-
(disabled || loading) ? '
|
|
39
|
+
'mint-button',
|
|
40
|
+
`mint-button--${variant}`,
|
|
41
|
+
`mint-button--${size}`,
|
|
42
|
+
fullWidth ? 'mint-button--full-width' : '',
|
|
43
|
+
(disabled || loading) ? 'mint-button--disabled' : '',
|
|
44
44
|
]"
|
|
45
45
|
@click="handleClick"
|
|
46
46
|
>
|
|
47
47
|
<svg
|
|
48
48
|
v-if="loading"
|
|
49
|
-
class="
|
|
49
|
+
class="mint-button__spinner"
|
|
50
50
|
fill="none"
|
|
51
51
|
viewBox="0 0 24 24"
|
|
52
52
|
>
|
|
@@ -26,29 +26,29 @@ function handleChange(event: Event) {
|
|
|
26
26
|
<template>
|
|
27
27
|
<label
|
|
28
28
|
:class="[
|
|
29
|
-
'
|
|
30
|
-
props.disabled ? '
|
|
29
|
+
'mint-checkbox',
|
|
30
|
+
props.disabled ? 'mint-checkbox--disabled' : '',
|
|
31
31
|
]"
|
|
32
32
|
>
|
|
33
|
-
<div class="
|
|
33
|
+
<div class="mint-checkbox__input-wrapper">
|
|
34
34
|
<input
|
|
35
35
|
type="checkbox"
|
|
36
36
|
:checked="props.modelValue"
|
|
37
37
|
:disabled="props.disabled"
|
|
38
38
|
:aria-label="props.label || 'Checkbox'"
|
|
39
|
-
class="
|
|
39
|
+
class="mint-checkbox__native"
|
|
40
40
|
@change="handleChange"
|
|
41
41
|
/>
|
|
42
42
|
<div
|
|
43
43
|
:class="[
|
|
44
|
-
'
|
|
45
|
-
`
|
|
46
|
-
props.modelValue ? '
|
|
44
|
+
'mint-checkbox__box',
|
|
45
|
+
`mint-checkbox__box--${props.size}`,
|
|
46
|
+
props.modelValue ? 'mint-checkbox__box--checked' : '',
|
|
47
47
|
]"
|
|
48
48
|
>
|
|
49
49
|
<svg
|
|
50
50
|
v-if="props.modelValue"
|
|
51
|
-
:class="['
|
|
51
|
+
:class="['mint-checkbox__icon', `mint-checkbox__icon--${props.size}`]"
|
|
52
52
|
fill="none"
|
|
53
53
|
stroke="currentColor"
|
|
54
54
|
viewBox="0 0 24 24"
|
|
@@ -58,7 +58,7 @@ function handleChange(event: Event) {
|
|
|
58
58
|
</svg>
|
|
59
59
|
</div>
|
|
60
60
|
</div>
|
|
61
|
-
<span v-if="props.label" :class="['
|
|
61
|
+
<span v-if="props.label" :class="['mint-checkbox__label', `mint-checkbox__label--${props.size}`]">
|
|
62
62
|
{{ props.label }}
|
|
63
63
|
</span>
|
|
64
64
|
</label>
|
|
@@ -57,10 +57,10 @@ function handleInput(event: Event) {
|
|
|
57
57
|
:aria-invalid="error || undefined"
|
|
58
58
|
:aria-describedby="ariaDescribedby || undefined"
|
|
59
59
|
:class="[
|
|
60
|
-
'
|
|
61
|
-
`
|
|
62
|
-
error ? '
|
|
63
|
-
disabled ? '
|
|
60
|
+
'mint-input',
|
|
61
|
+
`mint-input--${size}`,
|
|
62
|
+
error ? 'mint-input--error' : '',
|
|
63
|
+
disabled ? 'mint-input--disabled' : '',
|
|
64
64
|
]"
|
|
65
65
|
@input="handleInput"
|
|
66
66
|
@focus="emit('focus', $event)"
|
|
@@ -31,7 +31,7 @@ const sheetOpen = ref(false)
|
|
|
31
31
|
<BaseModal
|
|
32
32
|
v-model="refreshOpen"
|
|
33
33
|
title="Confirm uninstall"
|
|
34
|
-
subtitle="
|
|
34
|
+
subtitle="mint-plugin-metabolomics · v2.4.1"
|
|
35
35
|
size="md"
|
|
36
36
|
>
|
|
37
37
|
Removing this plugin will delete its routes from the platform on next restart.
|
|
@@ -116,35 +116,35 @@ onUnmounted(() => {
|
|
|
116
116
|
<Transition :name="`modal-${variant}`">
|
|
117
117
|
<div
|
|
118
118
|
v-if="modelValue"
|
|
119
|
-
:class="['
|
|
119
|
+
:class="['mint-modal', `mint-modal--${variant}`]"
|
|
120
120
|
@click="handleOverlayClick"
|
|
121
121
|
>
|
|
122
122
|
<!-- Overlay -->
|
|
123
|
-
<div class="
|
|
123
|
+
<div class="mint-modal__overlay" />
|
|
124
124
|
|
|
125
125
|
<!-- Modal -->
|
|
126
126
|
<div
|
|
127
127
|
ref="containerRef"
|
|
128
128
|
:class="[
|
|
129
|
-
'
|
|
130
|
-
`
|
|
131
|
-
`
|
|
129
|
+
'mint-modal__container',
|
|
130
|
+
`mint-modal__container--${size}`,
|
|
131
|
+
`mint-modal__container--${variant}`,
|
|
132
132
|
]"
|
|
133
133
|
role="dialog"
|
|
134
134
|
aria-modal="true"
|
|
135
135
|
tabindex="-1"
|
|
136
136
|
>
|
|
137
137
|
<!-- Sheet grab-hint bar (sheet variant only) -->
|
|
138
|
-
<div v-if="variant === 'sheet'" class="
|
|
138
|
+
<div v-if="variant === 'sheet'" class="mint-modal__grab-hint" aria-hidden="true" />
|
|
139
139
|
|
|
140
140
|
<!-- Header -->
|
|
141
|
-
<div v-if="title || subtitle || closable || $slots.header" class="
|
|
142
|
-
<div v-if="title || subtitle || $slots.header" class="
|
|
141
|
+
<div v-if="title || subtitle || closable || $slots.header" class="mint-modal__header">
|
|
142
|
+
<div v-if="title || subtitle || $slots.header" class="mint-modal__header-text">
|
|
143
143
|
<slot name="header">
|
|
144
|
-
<h3 v-if="title" class="
|
|
144
|
+
<h3 v-if="title" class="mint-modal__title">
|
|
145
145
|
{{ title }}
|
|
146
146
|
</h3>
|
|
147
|
-
<p v-if="subtitle" class="
|
|
147
|
+
<p v-if="subtitle" class="mint-modal__subtitle">
|
|
148
148
|
{{ subtitle }}
|
|
149
149
|
</p>
|
|
150
150
|
</slot>
|
|
@@ -152,23 +152,23 @@ onUnmounted(() => {
|
|
|
152
152
|
<button
|
|
153
153
|
v-if="closable"
|
|
154
154
|
type="button"
|
|
155
|
-
class="
|
|
155
|
+
class="mint-modal__close"
|
|
156
156
|
aria-label="Close modal"
|
|
157
157
|
@click="close"
|
|
158
158
|
>
|
|
159
|
-
<svg class="
|
|
159
|
+
<svg class="mint-modal__close-icon" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24">
|
|
160
160
|
<path d="M18 6 6 18" /><path d="m6 6 12 12" />
|
|
161
161
|
</svg>
|
|
162
162
|
</button>
|
|
163
163
|
</div>
|
|
164
164
|
|
|
165
165
|
<!-- Body -->
|
|
166
|
-
<div class="
|
|
166
|
+
<div class="mint-modal__body">
|
|
167
167
|
<slot />
|
|
168
168
|
</div>
|
|
169
169
|
|
|
170
170
|
<!-- Footer -->
|
|
171
|
-
<div v-if="$slots.footer" class="
|
|
171
|
+
<div v-if="$slots.footer" class="mint-modal__footer">
|
|
172
172
|
<slot name="footer" />
|
|
173
173
|
</div>
|
|
174
174
|
</div>
|
|
@@ -57,27 +57,27 @@ function handleRemove(event: MouseEvent) {
|
|
|
57
57
|
<template>
|
|
58
58
|
<span
|
|
59
59
|
:class="[
|
|
60
|
-
'
|
|
61
|
-
`
|
|
62
|
-
color && `
|
|
63
|
-
`
|
|
64
|
-
{ '
|
|
60
|
+
'mint-pill',
|
|
61
|
+
`mint-pill--${variant}`,
|
|
62
|
+
color && `mint-pill--${color}`,
|
|
63
|
+
`mint-pill--${size}`,
|
|
64
|
+
{ 'mint-pill--disabled': disabled, 'mint-pill--with-icon': icon },
|
|
65
65
|
]"
|
|
66
66
|
>
|
|
67
|
-
<span v-if="icon" class="
|
|
67
|
+
<span v-if="icon" class="mint-pill__icon">
|
|
68
68
|
<slot name="icon" />
|
|
69
69
|
</span>
|
|
70
|
-
<span class="
|
|
70
|
+
<span class="mint-pill__label">
|
|
71
71
|
<slot />
|
|
72
72
|
</span>
|
|
73
73
|
<button
|
|
74
74
|
v-if="removable && !disabled"
|
|
75
75
|
type="button"
|
|
76
|
-
class="
|
|
76
|
+
class="mint-pill__remove"
|
|
77
77
|
aria-label="Remove"
|
|
78
78
|
@click="handleRemove"
|
|
79
79
|
>
|
|
80
|
-
<svg class="
|
|
80
|
+
<svg class="mint-pill__remove-icon" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24">
|
|
81
81
|
<path d="M18 6 6 18" /><path d="m6 6 12 12" />
|
|
82
82
|
</svg>
|
|
83
83
|
</button>
|