@morscherlab/mint-sdk 1.0.51 → 1.0.53

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 (43) hide show
  1. package/dist/__tests__/components/JobsStatusTray.test.d.ts +1 -0
  2. package/dist/__tests__/composables/useJobsStatusTray.test.d.ts +1 -0
  3. package/dist/__tests__/utils/jobs.test.d.ts +1 -0
  4. package/dist/components/BioTemplateExperimentWorkspaceView.vue.d.ts +1 -1
  5. package/dist/components/JobsStatusTray.vue.d.ts +26 -0
  6. package/dist/components/index.d.ts +1 -0
  7. package/dist/components/index.js +2 -2
  8. package/dist/{components-C7UFkNIp.js → components-Lk_h_rON.js} +1663 -1339
  9. package/dist/components-Lk_h_rON.js.map +1 -0
  10. package/dist/composables/index.d.ts +1 -0
  11. package/dist/composables/index.js +3 -3
  12. package/dist/composables/useJobsStatusTray.d.ts +43 -0
  13. package/dist/composables/usePluginClient.d.ts +4 -1
  14. package/dist/{composables-CpBhNKHf.js → composables-DyfGpYZw.js} +50 -17
  15. package/dist/{composables-CpBhNKHf.js.map → composables-DyfGpYZw.js.map} +1 -1
  16. package/dist/index.d.ts +1 -0
  17. package/dist/index.js +4 -4
  18. package/dist/install.js +1 -1
  19. package/dist/jobs.d.ts +19 -0
  20. package/dist/styles.css +731 -0
  21. package/dist/types/index.d.ts +1 -0
  22. package/dist/types/jobs.d.ts +49 -0
  23. package/dist/{useProtocolTemplates-C8-YlHj1.js → useJobsStatusTray-DAH999_N.js} +250 -2
  24. package/dist/useJobsStatusTray-DAH999_N.js.map +1 -0
  25. package/package.json +1 -1
  26. package/src/__tests__/components/JobsStatusTray.test.ts +141 -0
  27. package/src/__tests__/composables/useJobsStatusTray.test.ts +241 -0
  28. package/src/__tests__/composables/usePluginClient.test.ts +291 -0
  29. package/src/__tests__/utils/jobs.test.ts +95 -0
  30. package/src/components/JobsStatusTray.story.vue +120 -0
  31. package/src/components/JobsStatusTray.vue +385 -0
  32. package/src/components/index.ts +1 -0
  33. package/src/composables/index.ts +8 -0
  34. package/src/composables/useJobsStatusTray.ts +304 -0
  35. package/src/composables/usePluginClient.ts +65 -15
  36. package/src/index.ts +3 -0
  37. package/src/jobs.ts +75 -0
  38. package/src/styles/components/jobs-status-tray.css +420 -0
  39. package/src/styles/index.css +1 -0
  40. package/src/types/index.ts +10 -0
  41. package/src/types/jobs.ts +61 -0
  42. package/dist/components-C7UFkNIp.js.map +0 -1
  43. package/dist/useProtocolTemplates-C8-YlHj1.js.map +0 -1
@@ -0,0 +1,420 @@
1
+ .mint-jobs-tray {
2
+ position: fixed;
3
+ right: max(1.25rem, env(safe-area-inset-right));
4
+ bottom: max(1.25rem, env(safe-area-inset-bottom));
5
+ z-index: 1000;
6
+ color: var(--text-primary);
7
+ font-family: 'Fira Sans', system-ui, sans-serif;
8
+ }
9
+
10
+ .mint-jobs-tray__trigger {
11
+ display: inline-flex;
12
+ min-height: 2.75rem;
13
+ align-items: center;
14
+ gap: 0.625rem;
15
+ padding: 0.5rem 1rem;
16
+ border: 0;
17
+ border-radius: 9999px;
18
+ background: var(--color-primary);
19
+ color: white;
20
+ box-shadow: var(--shadow-lg);
21
+ cursor: pointer;
22
+ transition: transform var(--mint-transition), background var(--mint-transition), box-shadow var(--mint-transition);
23
+ }
24
+
25
+ .mint-jobs-tray__trigger:hover {
26
+ transform: translateY(-1px);
27
+ background: var(--color-primary-hover);
28
+ }
29
+
30
+ .mint-jobs-tray__trigger:focus-visible,
31
+ .mint-jobs-tray__panel:focus-visible,
32
+ .mint-jobs-tray button:focus-visible {
33
+ outline: none;
34
+ box-shadow: var(--focus-ring-offset);
35
+ }
36
+
37
+ .mint-jobs-tray__trigger-icon {
38
+ width: 1.125rem;
39
+ height: 1.125rem;
40
+ stroke-width: 1.8;
41
+ stroke-linecap: round;
42
+ stroke-linejoin: round;
43
+ }
44
+
45
+ .mint-jobs-tray__trigger-icon--active {
46
+ animation: mint-jobs-tray-pulse 1.8s ease-in-out infinite;
47
+ }
48
+
49
+ .mint-jobs-tray__trigger-label {
50
+ font-size: 0.875rem;
51
+ font-weight: 600;
52
+ }
53
+
54
+ .mint-jobs-tray__count,
55
+ .mint-jobs-tray__tab-count {
56
+ display: inline-flex;
57
+ min-width: 1.25rem;
58
+ height: 1.25rem;
59
+ align-items: center;
60
+ justify-content: center;
61
+ padding: 0 0.375rem;
62
+ border-radius: 9999px;
63
+ font: 600 0.6875rem/1 'Fira Code', monospace;
64
+ }
65
+
66
+ .mint-jobs-tray__count {
67
+ background: var(--bg-secondary);
68
+ color: var(--color-primary);
69
+ }
70
+
71
+ .mint-jobs-tray__backdrop {
72
+ position: fixed;
73
+ inset: 0;
74
+ z-index: -2;
75
+ background: rgb(15 23 42 / 0.22);
76
+ backdrop-filter: blur(2px);
77
+ }
78
+
79
+ .mint-jobs-tray__panel {
80
+ position: absolute;
81
+ right: 0;
82
+ bottom: 3.75rem;
83
+ display: flex;
84
+ width: min(27.5rem, calc(100vw - 2rem));
85
+ max-height: min(42rem, calc(100vh - 7rem));
86
+ flex-direction: column;
87
+ overflow: hidden;
88
+ border: 1px solid var(--border-color);
89
+ border-radius: var(--radius-lg);
90
+ background: var(--bg-secondary);
91
+ box-shadow: var(--shadow-lg);
92
+ }
93
+
94
+ .mint-jobs-tray__header,
95
+ .mint-jobs-tray__job-heading,
96
+ .mint-jobs-tray__job-footer,
97
+ .mint-jobs-tray__header-actions,
98
+ .mint-jobs-tray__clear-row {
99
+ display: flex;
100
+ align-items: center;
101
+ }
102
+
103
+ .mint-jobs-tray__header {
104
+ justify-content: space-between;
105
+ padding: 1rem 1.125rem;
106
+ border-bottom: 1px solid var(--border-color);
107
+ }
108
+
109
+ .mint-jobs-tray__title {
110
+ margin: 0;
111
+ color: var(--text-primary);
112
+ font-size: 1rem;
113
+ font-weight: 600;
114
+ }
115
+
116
+ .mint-jobs-tray__subtitle {
117
+ margin: 0.2rem 0 0;
118
+ color: var(--text-secondary);
119
+ font: 0.6875rem/1.3 'Fira Code', monospace;
120
+ }
121
+
122
+ .mint-jobs-tray__header-actions {
123
+ gap: 0.25rem;
124
+ }
125
+
126
+ .mint-jobs-tray__icon-button {
127
+ display: inline-flex;
128
+ width: 2rem;
129
+ height: 2rem;
130
+ align-items: center;
131
+ justify-content: center;
132
+ padding: 0;
133
+ border: 0;
134
+ border-radius: var(--radius-md);
135
+ background: transparent;
136
+ color: var(--text-secondary-strong);
137
+ cursor: pointer;
138
+ transition: background var(--mint-transition), color var(--mint-transition);
139
+ }
140
+
141
+ .mint-jobs-tray__icon-button:hover {
142
+ background: var(--bg-hover);
143
+ color: var(--text-primary);
144
+ }
145
+
146
+ .mint-jobs-tray__icon-button svg {
147
+ width: 1rem;
148
+ height: 1rem;
149
+ stroke-width: 1.8;
150
+ stroke-linecap: round;
151
+ stroke-linejoin: round;
152
+ }
153
+
154
+ .mint-jobs-tray__icon-button--danger {
155
+ color: var(--mint-error);
156
+ }
157
+
158
+ .mint-jobs-tray__tabs {
159
+ display: grid;
160
+ grid-template-columns: 1fr 1fr;
161
+ border-bottom: 1px solid var(--border-color);
162
+ }
163
+
164
+ .mint-jobs-tray__tab {
165
+ position: relative;
166
+ display: inline-flex;
167
+ min-height: 2.75rem;
168
+ align-items: center;
169
+ justify-content: center;
170
+ gap: 0.375rem;
171
+ padding: 0.5rem 1rem;
172
+ border: 0;
173
+ background: transparent;
174
+ color: var(--text-secondary-strong);
175
+ font: 500 0.8125rem/1 'Fira Sans', sans-serif;
176
+ cursor: pointer;
177
+ }
178
+
179
+ .mint-jobs-tray__tab--active {
180
+ color: var(--color-primary);
181
+ }
182
+
183
+ .mint-jobs-tray__tab--active::after {
184
+ position: absolute;
185
+ right: 1rem;
186
+ bottom: 0;
187
+ left: 1rem;
188
+ height: 2px;
189
+ background: var(--color-primary);
190
+ content: '';
191
+ }
192
+
193
+ .mint-jobs-tray__tab-count {
194
+ background: var(--bg-tertiary);
195
+ color: currentColor;
196
+ }
197
+
198
+ .mint-jobs-tray__error {
199
+ margin: 0.75rem 1rem 0;
200
+ padding: 0.625rem 0.75rem;
201
+ border: 1px solid var(--mint-error-border);
202
+ border-radius: var(--radius-md);
203
+ background: var(--mint-error-bg);
204
+ color: var(--mint-error);
205
+ font-size: 0.75rem;
206
+ }
207
+
208
+ .mint-jobs-tray__body {
209
+ flex: 1;
210
+ overflow-y: auto;
211
+ padding: 0.875rem;
212
+ scrollbar-color: var(--scrollbar-thumb) transparent;
213
+ }
214
+
215
+ .mint-jobs-tray__empty {
216
+ margin: 0;
217
+ padding: 3rem 1rem;
218
+ color: var(--text-secondary);
219
+ text-align: center;
220
+ font-size: 0.8125rem;
221
+ }
222
+
223
+ .mint-jobs-tray__job {
224
+ padding: 0.875rem;
225
+ border: 1px solid var(--border-color);
226
+ border-radius: var(--radius-md);
227
+ background: var(--bg-card);
228
+ box-shadow: var(--shadow-sm);
229
+ }
230
+
231
+ .mint-jobs-tray__job + .mint-jobs-tray__job {
232
+ margin-top: 0.625rem;
233
+ }
234
+
235
+ .mint-jobs-tray__job--active {
236
+ border-color: var(--mint-info-border);
237
+ background: linear-gradient(135deg, var(--bg-card), var(--mint-info-bg));
238
+ }
239
+
240
+ .mint-jobs-tray__job-heading,
241
+ .mint-jobs-tray__job-footer {
242
+ justify-content: space-between;
243
+ gap: 0.75rem;
244
+ }
245
+
246
+ .mint-jobs-tray__job-identity {
247
+ min-width: 0;
248
+ }
249
+
250
+ .mint-jobs-tray__job-select {
251
+ display: block;
252
+ max-width: 100%;
253
+ padding: 0;
254
+ overflow: hidden;
255
+ border: 0;
256
+ background: transparent;
257
+ color: var(--text-primary);
258
+ cursor: pointer;
259
+ font-size: 0.8125rem;
260
+ font-weight: 600;
261
+ text-align: left;
262
+ text-overflow: ellipsis;
263
+ white-space: nowrap;
264
+ }
265
+
266
+ .mint-jobs-tray__kind {
267
+ display: block;
268
+ margin-top: 0.125rem;
269
+ color: var(--text-secondary);
270
+ font: 0.6875rem/1.3 'Fira Code', monospace;
271
+ }
272
+
273
+ .mint-jobs-tray__status {
274
+ flex: 0 0 auto;
275
+ padding: 0.25rem 0.5rem;
276
+ border: 1px solid var(--border-color);
277
+ border-radius: 9999px;
278
+ background: var(--bg-tertiary);
279
+ color: var(--text-secondary-strong);
280
+ font-size: 0.6875rem;
281
+ font-weight: 600;
282
+ }
283
+
284
+ .mint-jobs-tray__status--awaiting-input,
285
+ .mint-jobs-tray__status--queued {
286
+ border-color: var(--mint-warning-border);
287
+ background: var(--mint-warning-bg);
288
+ color: var(--mint-warning-hover);
289
+ }
290
+
291
+ .mint-jobs-tray__status--running {
292
+ border-color: var(--mint-info-border);
293
+ background: var(--mint-info-bg);
294
+ color: var(--mint-info);
295
+ }
296
+
297
+ .mint-jobs-tray__status--completed {
298
+ border-color: var(--mint-success-border);
299
+ background: var(--mint-success-bg);
300
+ color: var(--mint-success-hover);
301
+ }
302
+
303
+ .mint-jobs-tray__status--failed {
304
+ border-color: var(--mint-error-border);
305
+ background: var(--mint-error-bg);
306
+ color: var(--mint-error);
307
+ }
308
+
309
+ .mint-jobs-tray__progress {
310
+ height: 0.375rem;
311
+ margin-top: 0.75rem;
312
+ overflow: hidden;
313
+ border-radius: 9999px;
314
+ background: var(--bg-tertiary);
315
+ }
316
+
317
+ .mint-jobs-tray__progress span {
318
+ display: block;
319
+ height: 100%;
320
+ border-radius: inherit;
321
+ background: var(--color-primary);
322
+ transition: width var(--mint-transition);
323
+ }
324
+
325
+ .mint-jobs-tray__job-footer {
326
+ min-height: 1.75rem;
327
+ margin-top: 0.625rem;
328
+ color: var(--text-secondary);
329
+ font-size: 0.6875rem;
330
+ }
331
+
332
+ .mint-jobs-tray__action {
333
+ min-height: 1.75rem;
334
+ padding: 0.375rem 0.625rem;
335
+ border: 1px solid var(--border-color);
336
+ border-radius: var(--radius);
337
+ background: var(--bg-secondary);
338
+ color: var(--text-secondary-strong);
339
+ font: 500 0.6875rem/1 'Fira Sans', sans-serif;
340
+ cursor: pointer;
341
+ transition: background var(--mint-transition), border-color var(--mint-transition), color var(--mint-transition);
342
+ }
343
+
344
+ .mint-jobs-tray__job-actions {
345
+ display: inline-flex;
346
+ align-items: center;
347
+ gap: 0.25rem;
348
+ }
349
+
350
+ .mint-jobs-tray__action--danger {
351
+ border-color: var(--mint-error-border);
352
+ color: var(--mint-error);
353
+ }
354
+
355
+ .mint-jobs-tray__action--danger:hover {
356
+ background: var(--mint-error-bg);
357
+ }
358
+
359
+ .mint-jobs-tray__clear-row {
360
+ justify-content: flex-end;
361
+ margin-bottom: 0.625rem;
362
+ }
363
+
364
+ .mint-jobs-tray button:disabled {
365
+ opacity: var(--mint-disabled-opacity);
366
+ cursor: not-allowed;
367
+ }
368
+
369
+ .mint-jobs-tray-fade-enter-active,
370
+ .mint-jobs-tray-fade-leave-active,
371
+ .mint-jobs-tray-slide-enter-active,
372
+ .mint-jobs-tray-slide-leave-active {
373
+ transition: opacity var(--mint-transition), transform var(--mint-transition);
374
+ }
375
+
376
+ .mint-jobs-tray-fade-enter-from,
377
+ .mint-jobs-tray-fade-leave-to {
378
+ opacity: 0;
379
+ }
380
+
381
+ .mint-jobs-tray-slide-enter-from,
382
+ .mint-jobs-tray-slide-leave-to {
383
+ opacity: 0;
384
+ transform: translateY(0.5rem) scale(0.98);
385
+ }
386
+
387
+ @keyframes mint-jobs-tray-pulse {
388
+ 50% { opacity: 0.55; }
389
+ }
390
+
391
+ @media (max-width: 480px) {
392
+ .mint-jobs-tray {
393
+ right: max(1rem, env(safe-area-inset-right));
394
+ bottom: max(1rem, env(safe-area-inset-bottom));
395
+ }
396
+
397
+ .mint-jobs-tray__panel {
398
+ position: fixed;
399
+ right: 1rem;
400
+ bottom: 4.75rem;
401
+ left: 1rem;
402
+ width: auto;
403
+ max-height: calc(100vh - 6.75rem - env(safe-area-inset-bottom));
404
+ }
405
+ }
406
+
407
+ @media (prefers-reduced-motion: reduce) {
408
+ .mint-jobs-tray *,
409
+ .mint-jobs-tray *::before,
410
+ .mint-jobs-tray *::after {
411
+ scroll-behavior: auto !important;
412
+ animation-duration: 0.01ms !important;
413
+ animation-iteration-count: 1 !important;
414
+ transition-duration: 0.01ms !important;
415
+ }
416
+
417
+ .mint-jobs-tray__trigger:hover {
418
+ transform: none;
419
+ }
420
+ }
@@ -21,6 +21,7 @@
21
21
  @import './components/form-field.css';
22
22
  @import './components/icon-button.css';
23
23
  @import './components/instrument-monitor.css';
24
+ @import './components/jobs-status-tray.css';
24
25
  @import './components/input.css';
25
26
  @import './components/modal.css';
26
27
  @import './components/number-input.css';
@@ -176,6 +176,16 @@ export type {
176
176
  TreeNode,
177
177
  } from './components'
178
178
 
179
+ export type {
180
+ JobListPayload,
181
+ JobProgress,
182
+ JobSnapshotPayload,
183
+ JobState,
184
+ JobStateInput,
185
+ JobStatus,
186
+ JobStreamData,
187
+ } from './jobs'
188
+
179
189
  export type {
180
190
  InstrumentAlert,
181
191
  InstrumentAlertBody,
@@ -0,0 +1,61 @@
1
+ /** Canonical lifecycle values emitted by the MINT Python SDK job contract. */
2
+ export type JobStatus =
3
+ | 'awaiting_input'
4
+ | 'queued'
5
+ | 'running'
6
+ | 'completed'
7
+ | 'failed'
8
+ | 'cancelled'
9
+
10
+ export interface JobProgress {
11
+ current_file: number
12
+ total_files: number
13
+ current_filename: string | null
14
+ percent: number
15
+ message: string
16
+ stage: string
17
+ }
18
+
19
+ /** Normalized job state used by SDK job UI. */
20
+ export interface JobState {
21
+ id: string
22
+ job_id: string
23
+ kind: string
24
+ name: string
25
+ status: JobStatus
26
+ progress: JobProgress
27
+ queue_position: number
28
+ warnings: string[]
29
+ error: string | null
30
+ output_path: string | null
31
+ save_path: string | null
32
+ session_id: string | null
33
+ folders: string[]
34
+ folder_path: string | null
35
+ user_id: string | null
36
+ owner_user_id: string | null
37
+ experiment_id: string | null
38
+ extraction_result_id: string | null
39
+ metadata: Record<string, unknown>
40
+ created_at: string
41
+ started_at: string | null
42
+ completed_at: string | null
43
+ can_cancel: boolean
44
+ can_delete: boolean
45
+ }
46
+
47
+ /** Backward-compatible transport shape accepted from pre-capability backends. */
48
+ export type JobStateInput = Omit<JobState, 'can_cancel' | 'can_delete'> & {
49
+ can_cancel?: boolean | null
50
+ can_delete?: boolean | null
51
+ }
52
+
53
+ export interface JobListPayload {
54
+ jobs: JobStateInput[]
55
+ }
56
+
57
+ export interface JobSnapshotPayload {
58
+ jobs: JobStateInput[]
59
+ }
60
+
61
+ export type JobStreamData = JobStateInput | JobSnapshotPayload