@morscherlab/mint-sdk 1.3.0-beta.6 → 1.3.0-beta.8
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/{ResourcePickerListInternal-BEXnyBNz.js → ResourcePickerListInternal-CFAw4vTZ.js} +20 -17
- package/dist/ResourcePickerListInternal-CFAw4vTZ.js.map +1 -0
- package/dist/components/SettingsModal.schema.d.ts +1 -1
- package/dist/components/SettingsModal.vue.d.ts +2 -0
- package/dist/components/index.js +3 -3
- package/dist/components/internal/ResourcePickerListInternal.vue.d.ts +9 -3
- package/dist/{components-C-CAD2Ma.js → components-GDDvof8D.js} +18 -14
- package/dist/components-GDDvof8D.js.map +1 -0
- package/dist/composables/index.js +3 -3
- package/dist/{composables-BKhsoONv.js → composables-D6uqp0UF.js} +3 -3
- package/dist/{composables-BKhsoONv.js.map → composables-D6uqp0UF.js.map} +1 -1
- package/dist/index.js +5 -5
- package/dist/install.js +1 -1
- package/dist/styles.css +93 -61
- package/dist/templates/index.js +1 -1
- package/dist/{templates-DcxyATPT.js → templates-BU1pet28.js} +2 -2
- package/dist/{templates-DcxyATPT.js.map → templates-BU1pet28.js.map} +1 -1
- package/dist/types/components.d.ts +4 -0
- package/dist/{validation-kbTxfKYD.js → validation-Dmp9Q5W0.js} +2 -2
- package/dist/{validation-kbTxfKYD.js.map → validation-Dmp9Q5W0.js.map} +1 -1
- package/package.json +1 -1
- package/src/__tests__/components/ExperimentSelectorModal.test.ts +12 -5
- package/src/__tests__/components/ResourcePickerListInternal.test.ts +23 -4
- package/src/__tests__/components/SettingsModal.test.ts +22 -0
- package/src/__tests__/styles/controlRefreshRules.test.ts +22 -3
- package/src/__tests__/styles/menusShellRefresh.test.ts +14 -5
- package/src/components/AppTopBar.vue +1 -0
- package/src/components/ExperimentSelectorModal.vue +4 -1
- package/src/components/SettingsModal.schema.ts +4 -2
- package/src/components/SettingsModal.vue +4 -2
- package/src/components/internal/ResourcePickerListInternal.vue +21 -27
- package/src/styles/components/app-page-selector.css +3 -3
- package/src/styles/components/app-pill-nav.css +1 -1
- package/src/styles/components/app-top-bar.css +16 -12
- package/src/styles/components/experiment-selector-modal.css +3 -9
- package/src/styles/components/resource-picker-list.css +70 -36
- package/src/types/components.ts +4 -0
- package/dist/ResourcePickerListInternal-BEXnyBNz.js.map +0 -1
- package/dist/components-C-CAD2Ma.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@morscherlab/mint-sdk",
|
|
3
|
-
"version": "1.3.0-beta.
|
|
3
|
+
"version": "1.3.0-beta.8",
|
|
4
4
|
"description": "MINT Platform SDK — Vue 3 components, composables, and types for plugin development. MINT = Mass-spec INtegrated Toolkit.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -129,25 +129,32 @@ describe('ExperimentSelectorModal', () => {
|
|
|
129
129
|
expect(wrapper.emitted('update:modelValue')).toEqual([[false]])
|
|
130
130
|
})
|
|
131
131
|
|
|
132
|
-
it('should
|
|
132
|
+
it('should show the experiment code as a pill on the second line', () => {
|
|
133
133
|
experiments.value = [experiment()]
|
|
134
134
|
const wrapper = mountModal({ modelValue: true })
|
|
135
135
|
|
|
136
136
|
expect(wrapper.get('.mint-resource-picker__code').text()).toBe('EXP-007')
|
|
137
137
|
})
|
|
138
138
|
|
|
139
|
-
it('should state the status as text
|
|
139
|
+
it('should state the status as text in the right-hand column', () => {
|
|
140
140
|
experiments.value = [experiment()]
|
|
141
141
|
const wrapper = mountModal({ modelValue: true })
|
|
142
142
|
|
|
143
|
-
expect(wrapper.get('.mint-resource-
|
|
143
|
+
expect(wrapper.get('.mint-resource-picker__aside').text()).toContain('Ongoing')
|
|
144
144
|
})
|
|
145
145
|
|
|
146
|
-
it('should
|
|
146
|
+
it('should tint the status with the experiment status variant', () => {
|
|
147
|
+
experiments.value = [experiment()]
|
|
148
|
+
const wrapper = mountModal({ modelValue: true })
|
|
149
|
+
|
|
150
|
+
expect(wrapper.get('.mint-resource-picker__status').classes()).toContain('mint-resource-picker__status--primary')
|
|
151
|
+
})
|
|
152
|
+
|
|
153
|
+
it('should fill the current experiment row', () => {
|
|
147
154
|
experiments.value = [experiment()]
|
|
148
155
|
const wrapper = mountModal({ modelValue: true, currentExperimentId: 7 })
|
|
149
156
|
|
|
150
|
-
expect(wrapper.find('.mint-resource-
|
|
157
|
+
expect(wrapper.find('.mint-resource-picker__row--selected').exists()).toBe(true)
|
|
151
158
|
})
|
|
152
159
|
|
|
153
160
|
it('clears the shared store from the clear-selection footer', async () => {
|
|
@@ -40,8 +40,27 @@ describe('ResourcePickerListInternal', () => {
|
|
|
40
40
|
expect(setup().get('.mint-resource-picker__code').text()).toBe('EXP-042')
|
|
41
41
|
})
|
|
42
42
|
|
|
43
|
-
it('should
|
|
44
|
-
expect(setup().get('.mint-resource-
|
|
43
|
+
it('should render the code as the shared gray code pill', () => {
|
|
44
|
+
expect(setup().get('.mint-resource-picker__code').classes()).toContain('mint-exp-code')
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
it('should tint the status by its variant', () => {
|
|
48
|
+
const wrapper = setup({
|
|
49
|
+
describe: (item: unknown) => ({ title: (item as Item).name, status: { label: 'Completed', variant: 'success' } }),
|
|
50
|
+
})
|
|
51
|
+
expect(wrapper.get('.mint-resource-picker__status').classes()).toContain('mint-resource-picker__status--success')
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
it('should keep the title line to the title alone', () => {
|
|
55
|
+
expect(setup().get('.mint-resource-picker__title').text()).toBe('Liver microsome stability')
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
it('should lead the second line with the code and meta', () => {
|
|
59
|
+
expect(setup().get('.mint-resource-picker__meta').text()).toBe('EXP-042Zhang')
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
it('should put the date in the right-hand column', () => {
|
|
63
|
+
expect(setup().get('.mint-resource-picker__aside .mint-resource-picker__date').text()).toBe('09-24')
|
|
45
64
|
})
|
|
46
65
|
|
|
47
66
|
it('should mark the selected row', () => {
|
|
@@ -49,8 +68,8 @@ describe('ResourcePickerListInternal', () => {
|
|
|
49
68
|
expect(wrapper.findAll('[role="option"]')[1]!.attributes('aria-selected')).toBe('true')
|
|
50
69
|
})
|
|
51
70
|
|
|
52
|
-
it('should
|
|
53
|
-
expect(setup({ selectedKey: 2 }).findAll('.mint-resource-
|
|
71
|
+
it('should fill the selected row only', () => {
|
|
72
|
+
expect(setup({ selectedKey: 2 }).findAll('.mint-resource-picker__row--selected')).toHaveLength(1)
|
|
54
73
|
})
|
|
55
74
|
|
|
56
75
|
it('should emit select when a row is clicked', async () => {
|
|
@@ -540,6 +540,28 @@ describe('SettingsModal', () => {
|
|
|
540
540
|
expect(wrapper.findAll('.mint-modal__rail-section').map(heading => heading.text())).toEqual(['Plugin', 'Personal'])
|
|
541
541
|
})
|
|
542
542
|
|
|
543
|
+
it('should list and open Appearance first when appearanceFirst is set', () => {
|
|
544
|
+
const wrapper = mountSettingsModal({
|
|
545
|
+
tabs: [{ id: 'plugins', label: 'Plugins' }],
|
|
546
|
+
showAppearance: true,
|
|
547
|
+
appearanceFirst: true,
|
|
548
|
+
layout: 'vertical',
|
|
549
|
+
})
|
|
550
|
+
|
|
551
|
+
expect(wrapper.get('.mint-modal__rail-item--active').text()).toContain('Appearance')
|
|
552
|
+
})
|
|
553
|
+
|
|
554
|
+
it('should label a manual tab rail section from its section', () => {
|
|
555
|
+
const wrapper = mountSettingsModal({
|
|
556
|
+
tabs: [{ id: 'plugins', label: 'Plugins', section: 'Platform' }],
|
|
557
|
+
showAppearance: true,
|
|
558
|
+
appearanceFirst: true,
|
|
559
|
+
layout: 'vertical',
|
|
560
|
+
})
|
|
561
|
+
|
|
562
|
+
expect(wrapper.findAll('.mint-modal__rail-section').map(heading => heading.text())).toEqual(['Personal', 'Platform'])
|
|
563
|
+
})
|
|
564
|
+
|
|
543
565
|
it('should not render rail section headings when appearance is hidden', () => {
|
|
544
566
|
const wrapper = mountSettingsModal({ schema: railSchema })
|
|
545
567
|
|
|
@@ -184,11 +184,30 @@ describe('SDK control refresh style rules', () => {
|
|
|
184
184
|
expect(rule).toMatch(/flex-wrap:\s*wrap/)
|
|
185
185
|
})
|
|
186
186
|
|
|
187
|
-
it('should pad resource picker rows
|
|
188
|
-
// 16.25px title + 1px gap + 15px meta + 10px padding + 1px border = 43.25px, under min-height.
|
|
187
|
+
it('should pad resource picker rows to the roomier two-column layout when scanning resource-picker-list.css', () => {
|
|
189
188
|
const css = stripComments(readFileSync(component('resource-picker-list.css'), 'utf-8'))
|
|
190
189
|
const rule = /\.mint-resource-picker__row\s*\{([^}]*)\}/.exec(css)?.[1] ?? ''
|
|
191
|
-
expect(rule).toMatch(/padding:\s*
|
|
190
|
+
expect(rule).toMatch(/padding:\s*10px 12px/)
|
|
191
|
+
})
|
|
192
|
+
|
|
193
|
+
// Group bars and the list frame were inset by the modal body padding; the list now runs edge to edge.
|
|
194
|
+
it('should drop the modal body padding around the resource picker when scanning resource-picker-list.css', () => {
|
|
195
|
+
const css = stripComments(readFileSync(component('resource-picker-list.css'), 'utf-8'))
|
|
196
|
+
const rule = /\.mint-modal__body:has\(> \.mint-resource-picker\)\s*\{([^}]*)\}/.exec(css)?.[1] ?? ''
|
|
197
|
+
expect(rule).toMatch(/padding:\s*0/)
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
it('should pad resource picker group bars to the modal gutter when scanning resource-picker-list.css', () => {
|
|
201
|
+
const css = stripComments(readFileSync(component('resource-picker-list.css'), 'utf-8'))
|
|
202
|
+
const rule = /\.mint-resource-picker__group\s*\{([^}]*)\}/.exec(css)?.[1] ?? ''
|
|
203
|
+
expect(rule).toMatch(/padding:\s*0 1\.25rem/)
|
|
204
|
+
})
|
|
205
|
+
|
|
206
|
+
// The list sat in a bordered card inside the modal card.
|
|
207
|
+
it('should draw no frame around the resource picker list when scanning resource-picker-list.css', () => {
|
|
208
|
+
const css = stripComments(readFileSync(component('resource-picker-list.css'), 'utf-8'))
|
|
209
|
+
const rule = /\.mint-resource-picker__frame\s*\{([^}]*)\}/.exec(css)?.[1] ?? ''
|
|
210
|
+
expect(rule).not.toMatch(/(^|;)\s*border:/)
|
|
192
211
|
})
|
|
193
212
|
|
|
194
213
|
it('should paint the clear-selection link with primary ink when scanning experiment-selector-modal.css (8b)', () => {
|
|
@@ -21,22 +21,31 @@ describe('menus and app shell styles', () => {
|
|
|
21
21
|
expect(css('step-wizard.css')).not.toMatch(/\.mint-wizard__nav-btn/)
|
|
22
22
|
})
|
|
23
23
|
|
|
24
|
-
it('should pad the top bar to
|
|
25
|
-
expect(css('app-top-bar.css')).toMatch(/\.mint-topbar\s*\{[^}]*padding:\s*0\.
|
|
24
|
+
it('should pad the top bar to the 1.2 height (62px)', () => {
|
|
25
|
+
expect(css('app-top-bar.css')).toMatch(/\.mint-topbar\s*\{[^}]*padding:\s*0\.75rem 1rem;/)
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
// 28px items + 3px track padding + 1px border on each side = the 36px top-bar control height.
|
|
29
|
+
it('should size pill nav items so the track matches the 36px top-bar controls', () => {
|
|
30
|
+
expect(css('app-pill-nav.css')).toMatch(/\.mint-pill-nav__item\s*\{[^}]*height:\s*1\.75rem;/)
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
it('should size the page selector trigger to the 36px identity tile', () => {
|
|
34
|
+
expect(css('app-page-selector.css')).toMatch(/\.mint-page-selector__trigger\s*\{[^}]*height:\s*2\.25rem;/)
|
|
26
35
|
})
|
|
27
36
|
|
|
28
37
|
// Shrinking the tile beside the identity also shrank structured icons inside their solid chip, drawing a ring.
|
|
29
|
-
it('should keep the
|
|
38
|
+
it('should keep the plugin tile beside the static plugin identity (5a)', () => {
|
|
30
39
|
expect(css('app-top-bar.css')).not.toMatch(/:has\(\+ \.mint-topbar__plugin-identity\)/)
|
|
31
40
|
})
|
|
32
41
|
|
|
33
42
|
// A slotted 36px logo shrank to 32px wide but kept its height, drawing a 32x36 tile.
|
|
34
|
-
it('should fit slotted identity content inside the
|
|
43
|
+
it('should fit slotted identity content inside the identity tile (5a)', () => {
|
|
35
44
|
expect(css('app-top-bar.css')).toMatch(/\.mint-topbar__identity > \*\s*\{[^}]*max-width:\s*100%;[^}]*max-height:\s*100%;/)
|
|
36
45
|
})
|
|
37
46
|
|
|
38
47
|
// 15px x 1.15 + 12px x 1.2 = 31.7px, so the title group fits the 32px control row.
|
|
39
|
-
it('should fit the top-bar title and subtitle inside the
|
|
48
|
+
it('should fit the top-bar title and subtitle inside the control row (5a)', () => {
|
|
40
49
|
expect(css('app-top-bar.css')).toMatch(/\.mint-topbar-title\s*\{[^}]*line-height:\s*1\.15;/)
|
|
41
50
|
})
|
|
42
51
|
|
|
@@ -444,6 +444,7 @@ const effectiveCurrentPageSelectorId = computed(() =>
|
|
|
444
444
|
:title="settingsConfig?.title"
|
|
445
445
|
:tabs="normalizedSettingsTabs"
|
|
446
446
|
:show-appearance="settingsConfig?.showAppearance ?? true"
|
|
447
|
+
:appearance-first="settingsConfig?.appearanceFirst"
|
|
447
448
|
:size="settingsConfig?.size"
|
|
448
449
|
:layout="settingsConfig?.layout"
|
|
449
450
|
:schema="settingsConfig?.schema"
|
|
@@ -14,6 +14,7 @@ import { useExperimentStore } from '../stores/experiment'
|
|
|
14
14
|
import {
|
|
15
15
|
formatExperimentDate,
|
|
16
16
|
formatExperimentStatus,
|
|
17
|
+
getExperimentStatusVariant,
|
|
17
18
|
EXPERIMENT_STATUS_OPTIONS,
|
|
18
19
|
DATE_PRESET_OPTIONS,
|
|
19
20
|
SORT_OPTIONS,
|
|
@@ -105,8 +106,10 @@ function describe(experiment: ExperimentSummary) {
|
|
|
105
106
|
meta: [
|
|
106
107
|
...(groupToggle.value ? [] : [experiment.project_name || experiment.project || '']),
|
|
107
108
|
owner ? [owner.first_name, owner.last_name].filter(Boolean).join(' ') || owner.username : '',
|
|
108
|
-
formatExperimentStatus(experiment.status),
|
|
109
109
|
].filter(Boolean),
|
|
110
|
+
status: experiment.status
|
|
111
|
+
? { label: formatExperimentStatus(experiment.status), variant: getExperimentStatusVariant(experiment.status) }
|
|
112
|
+
: undefined,
|
|
110
113
|
date: formatExperimentDate(experiment.created_at),
|
|
111
114
|
}
|
|
112
115
|
}
|
|
@@ -68,7 +68,9 @@ export function normalizeVisibleSettingsTabs(
|
|
|
68
68
|
|
|
69
69
|
export function buildSettingsTabs(
|
|
70
70
|
baseTabs: SettingsTab[],
|
|
71
|
-
showAppearance: boolean
|
|
71
|
+
showAppearance: boolean,
|
|
72
|
+
appearanceFirst = false
|
|
72
73
|
): SettingsTab[] {
|
|
73
|
-
|
|
74
|
+
if (!showAppearance) return baseTabs
|
|
75
|
+
return appearanceFirst ? [APPEARANCE_TAB, ...baseTabs] : [...baseTabs, APPEARANCE_TAB]
|
|
74
76
|
}
|
|
@@ -90,6 +90,8 @@ interface Props {
|
|
|
90
90
|
/** Manual tab descriptors. Ignored when `schema` is set (groups become tabs). */
|
|
91
91
|
tabs?: SettingsTabInput[]
|
|
92
92
|
showAppearance?: boolean
|
|
93
|
+
/** List Appearance before the other tabs and open on it. */
|
|
94
|
+
appearanceFirst?: boolean
|
|
93
95
|
size?: 'md' | 'lg' | 'xl'
|
|
94
96
|
layout?: SettingsModalLayout
|
|
95
97
|
/** Declarative schema — fields auto-render via SDK form components. */
|
|
@@ -238,7 +240,7 @@ const allTabs = computed<SettingsTab[]>(() => {
|
|
|
238
240
|
const base: SettingsTab[] = settingsSchema.value
|
|
239
241
|
? visibleSchemaGroups.value.map(settingsGroupToTab)
|
|
240
242
|
: manualTabs.value
|
|
241
|
-
return buildSettingsTabs(base, props.showAppearance)
|
|
243
|
+
return buildSettingsTabs(base, props.showAppearance, props.appearanceFirst)
|
|
242
244
|
})
|
|
243
245
|
|
|
244
246
|
const activeTab = ref(allTabs.value[0]?.id || APPEARANCE_TAB_ID)
|
|
@@ -272,7 +274,7 @@ const modalTabs = computed<ModalTab[]>(() =>
|
|
|
272
274
|
description: tab.description,
|
|
273
275
|
meta: group ? (modified ? String(modified) : undefined) : tab.meta,
|
|
274
276
|
// Sections only split plugin groups from Appearance; without it there is nothing to split.
|
|
275
|
-
section: props.showAppearance ? (tab.id === APPEARANCE_TAB_ID ? 'Personal' : 'Plugin') : undefined,
|
|
277
|
+
section: props.showAppearance ? (tab.id === APPEARANCE_TAB_ID ? 'Personal' : tab.section ?? 'Plugin') : undefined,
|
|
276
278
|
}
|
|
277
279
|
}),
|
|
278
280
|
)
|
|
@@ -1,21 +1,25 @@
|
|
|
1
1
|
<script setup lang="ts" generic="T">
|
|
2
2
|
/**
|
|
3
3
|
* Searchable, optionally grouped single-select list shared by the experiment and
|
|
4
|
-
* artifact selector modals
|
|
4
|
+
* artifact selector modals: two-line rows (title, then code + meta) with status and date
|
|
5
|
+
* in a right-hand column, a filled selected row, skeleton,
|
|
5
6
|
* error and empty states, and the combobox keyboard model (↑ ↓ Enter).
|
|
6
7
|
*/
|
|
7
8
|
import { computed, nextTick, reactive, ref, useId, watch } from 'vue'
|
|
8
9
|
import BaseInput from '../BaseInput.vue'
|
|
9
10
|
import Skeleton from '../Skeleton.vue'
|
|
10
11
|
import EmptyState from '../EmptyState.vue'
|
|
12
|
+
import type { PillVariant } from '../../types'
|
|
11
13
|
|
|
12
14
|
export interface ResourcePickerRow {
|
|
13
|
-
/** Identifier shown
|
|
15
|
+
/** Identifier shown as a gray pill at the start of the second line, e.g. an experiment code. */
|
|
14
16
|
code?: string
|
|
15
17
|
title: string
|
|
16
|
-
/** Second-line facts, joined with " · ". */
|
|
18
|
+
/** Second-line facts after the code, joined with " · ". */
|
|
17
19
|
meta?: string[]
|
|
18
|
-
/**
|
|
20
|
+
/** Right column, above the date, tinted by its variant. */
|
|
21
|
+
status?: { label: string; variant: PillVariant }
|
|
22
|
+
/** Right column, in mono. */
|
|
19
23
|
date?: string
|
|
20
24
|
}
|
|
21
25
|
|
|
@@ -206,36 +210,26 @@ watch(
|
|
|
206
210
|
@mouseenter="activeIndex = indexOf(item)"
|
|
207
211
|
>
|
|
208
212
|
<span class="mint-resource-picker__text">
|
|
209
|
-
<span class="mint-resource-picker__title"
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
+
<span class="mint-resource-picker__title">{{ describe(item).title }}</span>
|
|
214
|
+
<span v-if="describe(item).code || describe(item).meta?.length" class="mint-resource-picker__meta"
|
|
215
|
+
><span v-if="describe(item).code" class="mint-resource-picker__code mint-exp-code mint-exp-code--sm">{{
|
|
216
|
+
describe(item).code
|
|
217
|
+
}}</span
|
|
218
|
+
><span v-if="describe(item).meta?.length">{{ describe(item).meta!.join(' · ') }}</span></span
|
|
213
219
|
>
|
|
220
|
+
</span>
|
|
221
|
+
<span v-if="describe(item).status || describe(item).date" class="mint-resource-picker__aside">
|
|
214
222
|
<span
|
|
215
|
-
v-if="describe(item).
|
|
216
|
-
class="mint-resource-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
>{{ describe(item).meta?.length ? ' · ' : ''
|
|
220
|
-
}}<span class="mint-resource-picker__date">{{ describe(item).date }}</span></template
|
|
221
|
-
></span
|
|
223
|
+
v-if="describe(item).status"
|
|
224
|
+
class="mint-resource-picker__status"
|
|
225
|
+
:class="`mint-resource-picker__status--${describe(item).status!.variant}`"
|
|
226
|
+
>{{ describe(item).status!.label }}</span
|
|
222
227
|
>
|
|
228
|
+
<span v-if="describe(item).date" class="mint-resource-picker__date">{{ describe(item).date }}</span>
|
|
223
229
|
</span>
|
|
224
230
|
<span v-if="$slots.actions" class="mint-resource-picker__actions" @click.stop>
|
|
225
231
|
<slot name="actions" :item="item" />
|
|
226
232
|
</span>
|
|
227
|
-
<span class="mint-resource-picker__check-slot" aria-hidden="true">
|
|
228
|
-
<svg
|
|
229
|
-
v-if="itemKey(item) === selectedKey"
|
|
230
|
-
class="mint-resource-picker__check"
|
|
231
|
-
viewBox="0 0 16 16"
|
|
232
|
-
fill="none"
|
|
233
|
-
stroke="currentColor"
|
|
234
|
-
stroke-width="2"
|
|
235
|
-
>
|
|
236
|
-
<path d="M3.5 8.5l3 3 6-7" />
|
|
237
|
-
</svg>
|
|
238
|
-
</span>
|
|
239
233
|
</div>
|
|
240
234
|
</template>
|
|
241
235
|
</div>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* AppTopBar page selector — left-side route/page dropdown.
|
|
2
|
-
Trigger speaks the field language (5a):
|
|
2
|
+
Trigger speaks the field language (5a): 36px (the identity tile height), hover changes the background
|
|
3
3
|
only, open = field focus, inline 12px chevron. Menu = .mint-popover +
|
|
4
4
|
.mint-menu-item (2d); __menu / __item stay as aliases. */
|
|
5
5
|
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
align-items: center;
|
|
14
14
|
gap: 0.5rem;
|
|
15
15
|
width: 100%;
|
|
16
|
-
height:
|
|
17
|
-
padding: 0 0.5rem 0 0.
|
|
16
|
+
height: 2.25rem;
|
|
17
|
+
padding: 0 0.5rem 0 0.4375rem;
|
|
18
18
|
border: 1px solid var(--border-color);
|
|
19
19
|
background: var(--bg-card);
|
|
20
20
|
color: var(--text-primary);
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
.mint-topbar {
|
|
10
10
|
display: block;
|
|
11
11
|
width: 100%;
|
|
12
|
-
padding: 0.
|
|
12
|
+
padding: 0.75rem 1rem;
|
|
13
13
|
background-color: var(--bg-secondary);
|
|
14
14
|
box-sizing: border-box;
|
|
15
15
|
}
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
display: flex;
|
|
20
20
|
align-items: center;
|
|
21
21
|
gap: 0.5rem;
|
|
22
|
-
min-height:
|
|
22
|
+
min-height: 2.375rem;
|
|
23
23
|
position: relative;
|
|
24
24
|
}
|
|
25
25
|
|
|
@@ -31,24 +31,28 @@
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
.mint-topbar__identity {
|
|
34
|
-
width:
|
|
35
|
-
height:
|
|
34
|
+
width: 2.25rem;
|
|
35
|
+
height: 2.25rem;
|
|
36
36
|
display: inline-flex;
|
|
37
37
|
align-items: center;
|
|
38
38
|
justify-content: center;
|
|
39
39
|
flex-shrink: 0;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
/* Slotted logos sized above
|
|
42
|
+
/* Slotted logos sized above 36px shrink to fit instead of stretching the tile. */
|
|
43
43
|
.mint-topbar__identity > * {
|
|
44
44
|
max-width: 100%;
|
|
45
45
|
max-height: 100%;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
/*
|
|
49
|
-
.mint-
|
|
50
|
-
|
|
51
|
-
height:
|
|
48
|
+
/* Left and right fields share the 36px identity tile height. */
|
|
49
|
+
.mint-topbar .mint-experiment-popover__trigger,
|
|
50
|
+
.mint-topbar .mint-experiment-popover__save-trigger {
|
|
51
|
+
height: 2.25rem;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.mint-topbar .mint-experiment-popover__save-trigger {
|
|
55
|
+
width: 2.25rem;
|
|
52
56
|
}
|
|
53
57
|
|
|
54
58
|
/* Centered section — absolute so asymmetric left/right weight never shifts the
|
|
@@ -87,8 +91,8 @@
|
|
|
87
91
|
}
|
|
88
92
|
|
|
89
93
|
.mint-topbar__logo-icon {
|
|
90
|
-
width:
|
|
91
|
-
height:
|
|
94
|
+
width: 2.25rem;
|
|
95
|
+
height: 2.25rem;
|
|
92
96
|
background-color: var(--color-primary);
|
|
93
97
|
border-radius: var(--radius-md);
|
|
94
98
|
display: flex;
|
|
@@ -151,7 +155,7 @@
|
|
|
151
155
|
opacity: 0.8;
|
|
152
156
|
}
|
|
153
157
|
|
|
154
|
-
/* Title + subtitle stay inside the
|
|
158
|
+
/* Title + subtitle stay inside the 36px control row. */
|
|
155
159
|
.mint-topbar-title-group {
|
|
156
160
|
display: flex;
|
|
157
161
|
flex-direction: column;
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
align-items: center;
|
|
6
6
|
gap: 0.5rem;
|
|
7
7
|
flex-wrap: wrap;
|
|
8
|
+
padding: 0 1.25rem;
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
.mint-experiment-selector__filter-select {
|
|
@@ -65,14 +66,6 @@ html.dark .mint-experiment-selector__filters-toggle--active {
|
|
|
65
66
|
flex-shrink: 0;
|
|
66
67
|
}
|
|
67
68
|
|
|
68
|
-
/* Advanced filters row */
|
|
69
|
-
.mint-experiment-selector__filters-advanced {
|
|
70
|
-
padding: 0.625rem;
|
|
71
|
-
border: 1px solid var(--border-light);
|
|
72
|
-
border-radius: var(--radius-md);
|
|
73
|
-
background-color: color-mix(in srgb, var(--bg-secondary) 72%, transparent);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
69
|
/* Group toggle checkbox label */
|
|
77
70
|
.mint-experiment-selector__group-toggle {
|
|
78
71
|
display: inline-flex;
|
|
@@ -103,7 +96,8 @@ html.dark .mint-experiment-selector__filters-toggle--active {
|
|
|
103
96
|
.mint-experiment-selector__footer {
|
|
104
97
|
display: flex;
|
|
105
98
|
justify-content: flex-start;
|
|
106
|
-
padding
|
|
99
|
+
padding: 0.5rem 1.25rem 0.75rem;
|
|
100
|
+
border-top: 1px solid var(--border-light);
|
|
107
101
|
}
|
|
108
102
|
|
|
109
103
|
.mint-experiment-selector__clear-btn {
|
|
@@ -1,4 +1,16 @@
|
|
|
1
|
-
/* ResourcePickerList
|
|
1
|
+
/* ResourcePickerList: shared list for ExperimentSelectorModal and ArtifactSelectorModal.
|
|
2
|
+
No frame of its own (the modal is the card); rows are inset and rounded, groups are
|
|
3
|
+
pinned bars. */
|
|
4
|
+
|
|
5
|
+
/* The modal is the only card: the list runs edge to edge, and the toolbar, group
|
|
6
|
+
bars and row text keep the modal's 1.25rem gutter themselves. */
|
|
7
|
+
.mint-modal__body:has(> .mint-resource-picker) {
|
|
8
|
+
padding: 0;
|
|
9
|
+
}
|
|
10
|
+
.mint-modal__container:has(.mint-resource-picker) .mint-modal__header {
|
|
11
|
+
border-bottom: none;
|
|
12
|
+
padding-bottom: 0.75rem;
|
|
13
|
+
}
|
|
2
14
|
|
|
3
15
|
.mint-resource-picker {
|
|
4
16
|
display: flex;
|
|
@@ -11,6 +23,7 @@
|
|
|
11
23
|
align-items: center;
|
|
12
24
|
flex-wrap: wrap;
|
|
13
25
|
gap: 0.5rem;
|
|
26
|
+
padding: 0 1.25rem;
|
|
14
27
|
}
|
|
15
28
|
.mint-resource-picker__search {
|
|
16
29
|
flex: 1;
|
|
@@ -20,12 +33,10 @@
|
|
|
20
33
|
.mint-resource-picker__frame {
|
|
21
34
|
display: flex;
|
|
22
35
|
flex-direction: column;
|
|
23
|
-
|
|
24
|
-
border: 1px solid var(--border-color);
|
|
25
|
-
border-radius: var(--radius-md);
|
|
26
|
-
background-color: var(--bg-card);
|
|
36
|
+
border-top: 1px solid var(--border-color);
|
|
27
37
|
}
|
|
28
38
|
.mint-resource-picker__list {
|
|
39
|
+
padding-bottom: 0.5rem;
|
|
29
40
|
max-height: min(28rem, calc(100vh - 16rem));
|
|
30
41
|
overflow-y: auto;
|
|
31
42
|
overscroll-behavior: contain;
|
|
@@ -38,14 +49,17 @@
|
|
|
38
49
|
gap: 0.5rem;
|
|
39
50
|
flex-shrink: 0;
|
|
40
51
|
width: 100%;
|
|
52
|
+
position: sticky;
|
|
53
|
+
top: 0;
|
|
54
|
+
z-index: 1;
|
|
41
55
|
height: 30px;
|
|
42
|
-
padding: 0
|
|
56
|
+
padding: 0 1.25rem;
|
|
43
57
|
border: 0;
|
|
44
58
|
border-bottom: 1px solid var(--border-light);
|
|
45
59
|
background-color: var(--bg-primary);
|
|
46
60
|
font-family: inherit;
|
|
47
61
|
font-size: 12px;
|
|
48
|
-
font-weight:
|
|
62
|
+
font-weight: 600;
|
|
49
63
|
color: var(--text-secondary);
|
|
50
64
|
text-align: left;
|
|
51
65
|
cursor: pointer;
|
|
@@ -77,24 +91,25 @@
|
|
|
77
91
|
.mint-resource-picker__group-count {
|
|
78
92
|
font: 11px var(--font-mono);
|
|
79
93
|
font-variant-numeric: tabular-nums;
|
|
94
|
+
color: var(--text-muted);
|
|
80
95
|
}
|
|
81
96
|
|
|
82
97
|
.mint-resource-picker__row {
|
|
83
98
|
display: grid;
|
|
84
|
-
grid-template-columns: minmax(0, 1fr)
|
|
99
|
+
grid-template-columns: minmax(0, 1fr);
|
|
100
|
+
grid-auto-flow: column;
|
|
101
|
+
grid-auto-columns: auto;
|
|
85
102
|
align-items: center;
|
|
86
|
-
gap:
|
|
103
|
+
gap: 12px;
|
|
87
104
|
box-sizing: border-box;
|
|
88
105
|
flex-shrink: 0;
|
|
89
|
-
min-height:
|
|
90
|
-
|
|
91
|
-
|
|
106
|
+
min-height: 56px;
|
|
107
|
+
margin: 2px 0.5rem;
|
|
108
|
+
padding: 10px 12px;
|
|
109
|
+
border-radius: var(--radius-md);
|
|
92
110
|
cursor: pointer;
|
|
93
111
|
transition: background-color 150ms ease;
|
|
94
112
|
}
|
|
95
|
-
.mint-resource-picker__row:last-child {
|
|
96
|
-
border-bottom: 0;
|
|
97
|
-
}
|
|
98
113
|
.mint-resource-picker__row:hover {
|
|
99
114
|
background-color: var(--bg-hover);
|
|
100
115
|
}
|
|
@@ -110,7 +125,7 @@
|
|
|
110
125
|
.mint-resource-picker__text {
|
|
111
126
|
display: flex;
|
|
112
127
|
flex-direction: column;
|
|
113
|
-
gap:
|
|
128
|
+
gap: 4px;
|
|
114
129
|
min-width: 0;
|
|
115
130
|
line-height: 1.25;
|
|
116
131
|
}
|
|
@@ -118,18 +133,49 @@
|
|
|
118
133
|
overflow: hidden;
|
|
119
134
|
text-overflow: ellipsis;
|
|
120
135
|
white-space: nowrap;
|
|
121
|
-
font-size:
|
|
122
|
-
font-weight:
|
|
136
|
+
font-size: 15px;
|
|
137
|
+
font-weight: 600;
|
|
123
138
|
color: var(--text-primary);
|
|
124
139
|
}
|
|
125
140
|
.mint-resource-picker__row--selected .mint-resource-picker__title {
|
|
126
141
|
color: var(--_ink-primary);
|
|
127
142
|
}
|
|
128
|
-
.mint-resource-picker__code
|
|
143
|
+
.mint-resource-picker__code {
|
|
144
|
+
margin-right: 0.5rem;
|
|
145
|
+
}
|
|
146
|
+
.mint-resource-picker__aside {
|
|
147
|
+
display: flex;
|
|
148
|
+
flex-direction: column;
|
|
149
|
+
align-items: flex-end;
|
|
150
|
+
gap: 4px;
|
|
151
|
+
line-height: 1.25;
|
|
152
|
+
white-space: nowrap;
|
|
153
|
+
}
|
|
129
154
|
.mint-resource-picker__date {
|
|
130
|
-
font
|
|
155
|
+
font: 12px var(--font-mono);
|
|
131
156
|
font-variant-numeric: tabular-nums;
|
|
157
|
+
color: var(--text-muted);
|
|
158
|
+
}
|
|
159
|
+
.mint-resource-picker__status {
|
|
160
|
+
display: inline-flex;
|
|
161
|
+
align-items: center;
|
|
162
|
+
gap: 5px;
|
|
163
|
+
font-size: 12px;
|
|
164
|
+
font-weight: 500;
|
|
165
|
+
color: var(--text-secondary);
|
|
132
166
|
}
|
|
167
|
+
.mint-resource-picker__status::before {
|
|
168
|
+
content: '';
|
|
169
|
+
width: 6px;
|
|
170
|
+
height: 6px;
|
|
171
|
+
border-radius: 50%;
|
|
172
|
+
background-color: currentColor;
|
|
173
|
+
}
|
|
174
|
+
.mint-resource-picker__status--primary { color: var(--_ink-primary); }
|
|
175
|
+
.mint-resource-picker__status--success { color: var(--mint-success); }
|
|
176
|
+
.mint-resource-picker__status--warning { color: var(--mint-warning); }
|
|
177
|
+
.mint-resource-picker__status--error { color: var(--mint-error); }
|
|
178
|
+
.mint-resource-picker__status--info { color: var(--mint-info); }
|
|
133
179
|
.mint-resource-picker__meta {
|
|
134
180
|
overflow: hidden;
|
|
135
181
|
text-overflow: ellipsis;
|
|
@@ -142,29 +188,17 @@
|
|
|
142
188
|
align-items: center;
|
|
143
189
|
gap: 4px;
|
|
144
190
|
}
|
|
145
|
-
.mint-resource-picker__check-slot {
|
|
146
|
-
display: flex;
|
|
147
|
-
width: 14px;
|
|
148
|
-
}
|
|
149
|
-
.mint-resource-picker__check {
|
|
150
|
-
width: 14px;
|
|
151
|
-
height: 14px;
|
|
152
|
-
color: var(--color-primary);
|
|
153
|
-
}
|
|
154
191
|
|
|
155
192
|
.mint-resource-picker__skeleton-row {
|
|
156
193
|
display: flex;
|
|
157
194
|
flex-direction: column;
|
|
158
195
|
justify-content: center;
|
|
159
|
-
gap:
|
|
160
|
-
min-height:
|
|
161
|
-
padding:
|
|
162
|
-
border-bottom: 1px solid var(--border-light);
|
|
163
|
-
}
|
|
164
|
-
.mint-resource-picker__skeleton-row:last-child {
|
|
165
|
-
border-bottom: 0;
|
|
196
|
+
gap: 8px;
|
|
197
|
+
min-height: 56px;
|
|
198
|
+
padding: 10px 1.25rem;
|
|
166
199
|
}
|
|
167
200
|
.mint-resource-picker__error {
|
|
201
|
+
margin: 0 1.25rem 1.25rem;
|
|
168
202
|
padding: 0.75rem;
|
|
169
203
|
border: 1px solid var(--mint-error-border);
|
|
170
204
|
border-radius: var(--radius-md);
|