@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.
- package/dist/__tests__/components/JobsStatusTray.test.d.ts +1 -0
- package/dist/__tests__/composables/useJobsStatusTray.test.d.ts +1 -0
- package/dist/__tests__/utils/jobs.test.d.ts +1 -0
- package/dist/components/BioTemplateExperimentWorkspaceView.vue.d.ts +1 -1
- package/dist/components/JobsStatusTray.vue.d.ts +26 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.js +2 -2
- package/dist/{components-C7UFkNIp.js → components-Lk_h_rON.js} +1663 -1339
- package/dist/components-Lk_h_rON.js.map +1 -0
- package/dist/composables/index.d.ts +1 -0
- package/dist/composables/index.js +3 -3
- package/dist/composables/useJobsStatusTray.d.ts +43 -0
- package/dist/composables/usePluginClient.d.ts +4 -1
- package/dist/{composables-CpBhNKHf.js → composables-DyfGpYZw.js} +50 -17
- package/dist/{composables-CpBhNKHf.js.map → composables-DyfGpYZw.js.map} +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +4 -4
- package/dist/install.js +1 -1
- package/dist/jobs.d.ts +19 -0
- package/dist/styles.css +731 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/jobs.d.ts +49 -0
- package/dist/{useProtocolTemplates-C8-YlHj1.js → useJobsStatusTray-DAH999_N.js} +250 -2
- package/dist/useJobsStatusTray-DAH999_N.js.map +1 -0
- package/package.json +1 -1
- package/src/__tests__/components/JobsStatusTray.test.ts +141 -0
- package/src/__tests__/composables/useJobsStatusTray.test.ts +241 -0
- package/src/__tests__/composables/usePluginClient.test.ts +291 -0
- package/src/__tests__/utils/jobs.test.ts +95 -0
- package/src/components/JobsStatusTray.story.vue +120 -0
- package/src/components/JobsStatusTray.vue +385 -0
- package/src/components/index.ts +1 -0
- package/src/composables/index.ts +8 -0
- package/src/composables/useJobsStatusTray.ts +304 -0
- package/src/composables/usePluginClient.ts +65 -15
- package/src/index.ts +3 -0
- package/src/jobs.ts +75 -0
- package/src/styles/components/jobs-status-tray.css +420 -0
- package/src/styles/index.css +1 -0
- package/src/types/index.ts +10 -0
- package/src/types/jobs.ts +61 -0
- package/dist/components-C7UFkNIp.js.map +0 -1
- package/dist/useProtocolTemplates-C8-YlHj1.js.map +0 -1
package/dist/types/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export type { ContainerDirection, ButtonVariant, ButtonSize, InputType, ModalSize, ModalVariant, AlertType, Toast, TabItem, TabItemInput, OptionPrimitive, SelectOption, SelectOptionInput, RadioOption, RadioOptionInput, FormFieldProps, SidebarBadgeTone, SidebarToolSection, SidebarToolSectionAction, CollapsibleState, TopBarVariant, TopBarSettingsConfig, PillNavOption, PillNavOptionInput, PillNavItem, PillNavItemInput, PageSelectorItem, PageSelectorItemInput, PluginSwitcherPlugin, PluginSwitcherInfo, AccountMenuItem, WellPlateFormat, WellState, WellPlateSelectionMode, WellPlateSize, WellShape, Well, HeatmapColorScale, HeatmapConfig, SlotPosition, WellExtendedData, WellEditData, WellEditField, WellSampleDropData, WellSampleDropContext, WellSampleDropParser, WellLegendItem, PlateCondition, ColumnCondition, RowCondition, Rack, RackSampleDropContext, RackSampleDropMapper, SampleType, PlateMap, PlateMapEditorState, ProtocolStepType, ProtocolStepStatus, ProtocolStep, SampleGroup, GroupItem, FileUploaderMode, SegmentedOption, SegmentedOptionInput, SegmentedControlVariant, SegmentedControlSize, MultiSelectOption, MultiSelectOptionInput, MultiSelectSize, PillVariant, PillColor, PillSize, CalendarSelectionMode, CalendarMarker, CalendarDayContext, SortDirection, SortState, DataFrameColumn, PaginationState, SpinnerSize, SpinnerVariant, DividerSpacing, StatusType, ProgressVariant, ProgressSize, AvatarSize, EmptyStateColor, EmptyStateSize, BreadcrumbItem, BreadcrumbItemInput, TooltipPosition, ConfirmVariant, SettingsTab, SettingsTabInput, SettingsModalLayout, SettingsGroup, SettingsModalSchema, SettingsUserType, SettingsAudience, SettingsAudienceInput, NumberNotation, UnitOption, WizardStep, WizardStepState, AuditEntryType, AuditEntry, BatchItemStatus, BatchItem, BatchSummary, TimePickerFormat, TimeRange, ScheduleView, ScheduleEventStatus, ScheduleEvent, ScheduleBlockedSlot, ScheduleSlotContext, ScheduleEventCreateContext, ScheduleEventUpdateContext, SummarySectionItem, SummarySection, SummaryData, ResourceStatus, ResourceSpec, MoleculeData, ExperimentStatus, DatePreset, ExperimentSortField, ExperimentTypeOption, ExperimentSummary, ExperimentListResponse, ExperimentFilters, FitState, FitResultSummary, StorageCondition, ReagentColumn, Reagent, TreeNodeType, BadgeVariant, TreeNode, } from './components';
|
|
2
|
+
export type { JobListPayload, JobProgress, JobSnapshotPayload, JobState, JobStateInput, JobStatus, JobStreamData, } from './jobs';
|
|
2
3
|
export type { InstrumentAlert, InstrumentAlertBody, InstrumentAlertLevel, InstrumentState, InstrumentStatus, SampleInfo, SampleInfo as InstrumentSampleInfo, SequenceProgress, } from './instrument';
|
|
3
4
|
export type { LcmsContainerType, LcmsPolarity, LcmsSequenceItem, LcmsSequenceTableColumn, } from '../lcms';
|
|
4
5
|
export type { AccessAudience, AccessAudienceInput, AccessPolicy, AccessControlled, PermissionUser, RoleInfo, } from '../permissions';
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/** Canonical lifecycle values emitted by the MINT Python SDK job contract. */
|
|
2
|
+
export type JobStatus = 'awaiting_input' | 'queued' | 'running' | 'completed' | 'failed' | 'cancelled';
|
|
3
|
+
export interface JobProgress {
|
|
4
|
+
current_file: number;
|
|
5
|
+
total_files: number;
|
|
6
|
+
current_filename: string | null;
|
|
7
|
+
percent: number;
|
|
8
|
+
message: string;
|
|
9
|
+
stage: string;
|
|
10
|
+
}
|
|
11
|
+
/** Normalized job state used by SDK job UI. */
|
|
12
|
+
export interface JobState {
|
|
13
|
+
id: string;
|
|
14
|
+
job_id: string;
|
|
15
|
+
kind: string;
|
|
16
|
+
name: string;
|
|
17
|
+
status: JobStatus;
|
|
18
|
+
progress: JobProgress;
|
|
19
|
+
queue_position: number;
|
|
20
|
+
warnings: string[];
|
|
21
|
+
error: string | null;
|
|
22
|
+
output_path: string | null;
|
|
23
|
+
save_path: string | null;
|
|
24
|
+
session_id: string | null;
|
|
25
|
+
folders: string[];
|
|
26
|
+
folder_path: string | null;
|
|
27
|
+
user_id: string | null;
|
|
28
|
+
owner_user_id: string | null;
|
|
29
|
+
experiment_id: string | null;
|
|
30
|
+
extraction_result_id: string | null;
|
|
31
|
+
metadata: Record<string, unknown>;
|
|
32
|
+
created_at: string;
|
|
33
|
+
started_at: string | null;
|
|
34
|
+
completed_at: string | null;
|
|
35
|
+
can_cancel: boolean;
|
|
36
|
+
can_delete: boolean;
|
|
37
|
+
}
|
|
38
|
+
/** Backward-compatible transport shape accepted from pre-capability backends. */
|
|
39
|
+
export type JobStateInput = Omit<JobState, 'can_cancel' | 'can_delete'> & {
|
|
40
|
+
can_cancel?: boolean | null;
|
|
41
|
+
can_delete?: boolean | null;
|
|
42
|
+
};
|
|
43
|
+
export interface JobListPayload {
|
|
44
|
+
jobs: JobStateInput[];
|
|
45
|
+
}
|
|
46
|
+
export interface JobSnapshotPayload {
|
|
47
|
+
jobs: JobStateInput[];
|
|
48
|
+
}
|
|
49
|
+
export type JobStreamData = JobStateInput | JobSnapshotPayload;
|
|
@@ -4488,6 +4488,254 @@ function useProtocolTemplates() {
|
|
|
4488
4488
|
};
|
|
4489
4489
|
}
|
|
4490
4490
|
//#endregion
|
|
4491
|
-
|
|
4491
|
+
//#region src/jobs.ts
|
|
4492
|
+
var ACTIVE_JOB_STATUSES = new Set([
|
|
4493
|
+
"awaiting_input",
|
|
4494
|
+
"queued",
|
|
4495
|
+
"running"
|
|
4496
|
+
]);
|
|
4497
|
+
var TERMINAL_JOB_STATUSES = new Set([
|
|
4498
|
+
"completed",
|
|
4499
|
+
"failed",
|
|
4500
|
+
"cancelled"
|
|
4501
|
+
]);
|
|
4502
|
+
/** Resolve action support while retaining one-cycle legacy status inference. */
|
|
4503
|
+
function resolveJobCapabilities(job) {
|
|
4504
|
+
const legacyCanCancel = job.status === "queued" || job.status === "running";
|
|
4505
|
+
const legacyCanDelete = TERMINAL_JOB_STATUSES.has(job.status);
|
|
4506
|
+
return {
|
|
4507
|
+
can_cancel: typeof job.can_cancel === "boolean" ? job.can_cancel : legacyCanCancel,
|
|
4508
|
+
can_delete: typeof job.can_delete === "boolean" ? job.can_delete : legacyCanDelete
|
|
4509
|
+
};
|
|
4510
|
+
}
|
|
4511
|
+
/** Clamp invalid or out-of-range progress values for safe display. */
|
|
4512
|
+
function normalizeJobPercent(value) {
|
|
4513
|
+
if (!Number.isFinite(value)) return 0;
|
|
4514
|
+
return Math.min(100, Math.max(0, value));
|
|
4515
|
+
}
|
|
4516
|
+
/** Create a detached canonical state without changing the transport input. */
|
|
4517
|
+
function normalizeJobState(job) {
|
|
4518
|
+
const capabilities = resolveJobCapabilities(job);
|
|
4519
|
+
return {
|
|
4520
|
+
...job,
|
|
4521
|
+
progress: {
|
|
4522
|
+
...job.progress,
|
|
4523
|
+
percent: normalizeJobPercent(job.progress.percent)
|
|
4524
|
+
},
|
|
4525
|
+
warnings: [...job.warnings],
|
|
4526
|
+
folders: [...job.folders],
|
|
4527
|
+
metadata: { ...job.metadata },
|
|
4528
|
+
...capabilities
|
|
4529
|
+
};
|
|
4530
|
+
}
|
|
4531
|
+
function isActiveJobStatus(status) {
|
|
4532
|
+
return ACTIVE_JOB_STATUSES.has(status);
|
|
4533
|
+
}
|
|
4534
|
+
function isTerminalJobStatus(status) {
|
|
4535
|
+
return TERMINAL_JOB_STATUSES.has(status);
|
|
4536
|
+
}
|
|
4537
|
+
function jobStatusLabel(status) {
|
|
4538
|
+
return {
|
|
4539
|
+
awaiting_input: "Waiting for input",
|
|
4540
|
+
queued: "Queued",
|
|
4541
|
+
running: "Running",
|
|
4542
|
+
completed: "Completed",
|
|
4543
|
+
failed: "Failed",
|
|
4544
|
+
cancelled: "Cancelled"
|
|
4545
|
+
}[status];
|
|
4546
|
+
}
|
|
4547
|
+
//#endregion
|
|
4548
|
+
//#region src/composables/useJobsStatusTray.ts
|
|
4549
|
+
function responseJobs(response) {
|
|
4550
|
+
return "jobs" in response ? response.jobs : response;
|
|
4551
|
+
}
|
|
4552
|
+
function isSnapshotPayload(data) {
|
|
4553
|
+
return "jobs" in data && Array.isArray(data.jobs);
|
|
4554
|
+
}
|
|
4555
|
+
function errorMessage(error, fallback) {
|
|
4556
|
+
return error instanceof Error ? error.message : fallback;
|
|
4557
|
+
}
|
|
4558
|
+
/** Headless state and action controller for the standard SDK jobs tray. */
|
|
4559
|
+
function useJobsStatusTray(options = {}) {
|
|
4560
|
+
const jobs = shallowRef([]);
|
|
4561
|
+
const isOpen = ref(false);
|
|
4562
|
+
const activeTab = ref("active");
|
|
4563
|
+
const isLoading = ref(false);
|
|
4564
|
+
const error = shallowRef(null);
|
|
4565
|
+
const pendingJobIds = ref(/* @__PURE__ */ new Set());
|
|
4566
|
+
const jobRevisions = /* @__PURE__ */ new Map();
|
|
4567
|
+
let stateRevision = 0;
|
|
4568
|
+
let requestGeneration = 0;
|
|
4569
|
+
let active = true;
|
|
4570
|
+
const adapter = computed(() => toValue(options.adapter));
|
|
4571
|
+
const activeJobs = computed(() => jobs.value.filter((job) => isActiveJobStatus(job.status)));
|
|
4572
|
+
const historyJobs = computed(() => jobs.value.filter((job) => !isActiveJobStatus(job.status)));
|
|
4573
|
+
const deletableJobs = computed(() => historyJobs.value.filter((job) => job.can_delete));
|
|
4574
|
+
const featuredJob = computed(() => activeJobs.value[0] ?? historyJobs.value[0] ?? null);
|
|
4575
|
+
function bumpJobRevision(jobId) {
|
|
4576
|
+
jobRevisions.set(jobId, (jobRevisions.get(jobId) ?? 0) + 1);
|
|
4577
|
+
}
|
|
4578
|
+
function replaceJobs(nextJobs) {
|
|
4579
|
+
const normalized = nextJobs.map(normalizeJobState);
|
|
4580
|
+
new Set([...jobs.value.map((job) => job.job_id), ...normalized.map((job) => job.job_id)]).forEach(bumpJobRevision);
|
|
4581
|
+
jobs.value = normalized;
|
|
4582
|
+
stateRevision += 1;
|
|
4583
|
+
}
|
|
4584
|
+
function upsertJob(nextJob) {
|
|
4585
|
+
const normalized = normalizeJobState(nextJob);
|
|
4586
|
+
const existingIndex = jobs.value.findIndex((job) => job.job_id === normalized.job_id);
|
|
4587
|
+
if (existingIndex === -1) jobs.value = [normalized, ...jobs.value];
|
|
4588
|
+
else {
|
|
4589
|
+
const nextJobs = [...jobs.value];
|
|
4590
|
+
nextJobs[existingIndex] = normalized;
|
|
4591
|
+
jobs.value = nextJobs;
|
|
4592
|
+
}
|
|
4593
|
+
bumpJobRevision(normalized.job_id);
|
|
4594
|
+
stateRevision += 1;
|
|
4595
|
+
}
|
|
4596
|
+
function removeJobs(jobIds) {
|
|
4597
|
+
jobs.value = jobs.value.filter((job) => !jobIds.has(job.job_id));
|
|
4598
|
+
jobIds.forEach(bumpJobRevision);
|
|
4599
|
+
stateRevision += 1;
|
|
4600
|
+
}
|
|
4601
|
+
function setPending(jobId, pending) {
|
|
4602
|
+
const next = new Set(pendingJobIds.value);
|
|
4603
|
+
if (pending) next.add(jobId);
|
|
4604
|
+
else next.delete(jobId);
|
|
4605
|
+
pendingJobIds.value = next;
|
|
4606
|
+
}
|
|
4607
|
+
function applyStreamMessage(message) {
|
|
4608
|
+
if (!active) return;
|
|
4609
|
+
if (message.event === "snapshot" && isSnapshotPayload(message.data)) {
|
|
4610
|
+
replaceJobs(message.data.jobs);
|
|
4611
|
+
return;
|
|
4612
|
+
}
|
|
4613
|
+
if ((message.event === "job" || message.event === "terminal") && !isSnapshotPayload(message.data)) upsertJob(message.data);
|
|
4614
|
+
}
|
|
4615
|
+
async function refresh() {
|
|
4616
|
+
const listJobs = adapter.value?.listJobs;
|
|
4617
|
+
if (!listJobs) return false;
|
|
4618
|
+
const generation = ++requestGeneration;
|
|
4619
|
+
const revision = stateRevision;
|
|
4620
|
+
isLoading.value = true;
|
|
4621
|
+
error.value = null;
|
|
4622
|
+
try {
|
|
4623
|
+
const response = await listJobs();
|
|
4624
|
+
if (!active || generation !== requestGeneration || revision !== stateRevision) return false;
|
|
4625
|
+
replaceJobs(responseJobs(response));
|
|
4626
|
+
return true;
|
|
4627
|
+
} catch (cause) {
|
|
4628
|
+
if (active && generation === requestGeneration) error.value = errorMessage(cause, "Failed to load jobs");
|
|
4629
|
+
return false;
|
|
4630
|
+
} finally {
|
|
4631
|
+
if (active && generation === requestGeneration) isLoading.value = false;
|
|
4632
|
+
}
|
|
4633
|
+
}
|
|
4634
|
+
async function cancelJob(job) {
|
|
4635
|
+
const cancel = adapter.value?.cancelJob;
|
|
4636
|
+
if (!job.can_cancel || !cancel || pendingJobIds.value.has(job.job_id)) return false;
|
|
4637
|
+
const revision = jobRevisions.get(job.job_id) ?? 0;
|
|
4638
|
+
setPending(job.job_id, true);
|
|
4639
|
+
error.value = null;
|
|
4640
|
+
try {
|
|
4641
|
+
const updated = await cancel(job);
|
|
4642
|
+
if (!active) return false;
|
|
4643
|
+
if (revision === (jobRevisions.get(job.job_id) ?? 0)) if (updated) upsertJob(updated);
|
|
4644
|
+
else await refresh();
|
|
4645
|
+
return true;
|
|
4646
|
+
} catch (cause) {
|
|
4647
|
+
if (active) error.value = errorMessage(cause, "Failed to cancel job");
|
|
4648
|
+
return false;
|
|
4649
|
+
} finally {
|
|
4650
|
+
if (active) setPending(job.job_id, false);
|
|
4651
|
+
}
|
|
4652
|
+
}
|
|
4653
|
+
async function deleteJob(job) {
|
|
4654
|
+
const deleteJobWithAdapter = adapter.value?.deleteJob;
|
|
4655
|
+
if (!job.can_delete || !deleteJobWithAdapter || pendingJobIds.value.has(job.job_id)) return false;
|
|
4656
|
+
setPending(job.job_id, true);
|
|
4657
|
+
error.value = null;
|
|
4658
|
+
try {
|
|
4659
|
+
const deleted = await deleteJobWithAdapter(job);
|
|
4660
|
+
if (!active) return false;
|
|
4661
|
+
if (deleted === false) await refresh();
|
|
4662
|
+
else removeJobs(new Set([job.job_id]));
|
|
4663
|
+
return deleted !== false;
|
|
4664
|
+
} catch (cause) {
|
|
4665
|
+
if (active) error.value = errorMessage(cause, "Failed to delete job");
|
|
4666
|
+
return false;
|
|
4667
|
+
} finally {
|
|
4668
|
+
if (active) setPending(job.job_id, false);
|
|
4669
|
+
}
|
|
4670
|
+
}
|
|
4671
|
+
async function clearFinished() {
|
|
4672
|
+
const targets = deletableJobs.value;
|
|
4673
|
+
if (targets.length === 0) return false;
|
|
4674
|
+
error.value = null;
|
|
4675
|
+
try {
|
|
4676
|
+
const currentAdapter = adapter.value;
|
|
4677
|
+
if (currentAdapter?.clearFinishedJobs) {
|
|
4678
|
+
const deleted = await currentAdapter.clearFinishedJobs(targets);
|
|
4679
|
+
if (!active) return false;
|
|
4680
|
+
if (typeof deleted === "number" && deleted !== targets.length) {
|
|
4681
|
+
await refresh();
|
|
4682
|
+
return false;
|
|
4683
|
+
}
|
|
4684
|
+
removeJobs(new Set(targets.map((job) => job.job_id)));
|
|
4685
|
+
return true;
|
|
4686
|
+
}
|
|
4687
|
+
if (!currentAdapter?.deleteJob) return false;
|
|
4688
|
+
return (await Promise.all(targets.map((job) => deleteJob(job)))).every(Boolean);
|
|
4689
|
+
} catch (cause) {
|
|
4690
|
+
if (active) error.value = errorMessage(cause, "Failed to clear jobs");
|
|
4691
|
+
return false;
|
|
4692
|
+
}
|
|
4693
|
+
}
|
|
4694
|
+
if (options.jobs !== void 0) watch(() => toValue(options.jobs), (value) => {
|
|
4695
|
+
if (value) replaceJobs(value);
|
|
4696
|
+
}, {
|
|
4697
|
+
immediate: true,
|
|
4698
|
+
deep: true
|
|
4699
|
+
});
|
|
4700
|
+
if (options.eventStream !== void 0) watch(() => toValue(options.eventStream)?.lastMessage.value ?? null, (message) => {
|
|
4701
|
+
if (message) applyStreamMessage(message);
|
|
4702
|
+
}, { immediate: true });
|
|
4703
|
+
onMounted(() => {
|
|
4704
|
+
if (options.loadOnMount !== false) refresh();
|
|
4705
|
+
});
|
|
4706
|
+
onUnmounted(() => {
|
|
4707
|
+
active = false;
|
|
4708
|
+
requestGeneration += 1;
|
|
4709
|
+
});
|
|
4710
|
+
return {
|
|
4711
|
+
jobs,
|
|
4712
|
+
activeJobs,
|
|
4713
|
+
historyJobs,
|
|
4714
|
+
deletableJobs,
|
|
4715
|
+
featuredJob,
|
|
4716
|
+
isOpen,
|
|
4717
|
+
activeTab,
|
|
4718
|
+
isLoading,
|
|
4719
|
+
error,
|
|
4720
|
+
pendingJobIds,
|
|
4721
|
+
open: () => {
|
|
4722
|
+
isOpen.value = true;
|
|
4723
|
+
},
|
|
4724
|
+
close: () => {
|
|
4725
|
+
isOpen.value = false;
|
|
4726
|
+
},
|
|
4727
|
+
toggle: () => {
|
|
4728
|
+
isOpen.value = !isOpen.value;
|
|
4729
|
+
},
|
|
4730
|
+
refresh,
|
|
4731
|
+
applyStreamMessage,
|
|
4732
|
+
cancelJob,
|
|
4733
|
+
deleteJob,
|
|
4734
|
+
clearFinished,
|
|
4735
|
+
isPending: (job) => pendingJobIds.value.has(job.job_id)
|
|
4736
|
+
};
|
|
4737
|
+
}
|
|
4738
|
+
//#endregion
|
|
4739
|
+
export { useTheme as $, useExpansionSet as A, extractSamplesFromDesignData as B, useExperimentSave as C, currentExperimentFromContext as D, useExperimentData as E, detectDelimiter as F, unwrapExperimentDesignData as G, parseCSV as H, parseDelimitedText as I, useDoseCalculator as J, DEFAULT_COLORS as K, readFileAsText as L, deriveShade as M, hexToHsl as N, getInjectedPlatformContext as O, hslToHex as P, useAppExperiment as Q, useFileImport as R, useTemplateCollection as S, useExperimentSamples as T, extractSampleNamesFromDesignData as U, useAutoGroup as V, extractSampleOptionsFromDesignData as W, useMobileSupportGate as X, DEFAULT_MOBILE_VIEWPORT_QUERY as Y, APP_EXPERIMENT_KEY as Z, useBioTemplateWorkspace as _, normalizeJobPercent as a, useSortedItems as at, useBioTemplateComponents as b, useProtocolTemplates as c, generateDilutionSeries as d, useToast as et, useReagentSeries as f, useBioTemplatePackWorkspace as g, useBioTemplatePresetWorkspace as h, jobStatusLabel as i, compareSortValues as it, useSampleGroups as j, resolveCurrentExperimentId as k, DEFAULT_PRESETS as l, useRackEditor as m, isActiveJobStatus as n, normalizeSearchQuery as nt, normalizeJobState as o, useGroupAssignment as p, useWellPlateEditor as q, isTerminalJobStatus as r, useTextSearch as rt, resolveJobCapabilities as s, useJobsStatusTray as t, candidateMatchesSearch as tt, DEFAULT_UNITS as u, getBioTemplateComponentProps as v, useScheduleDrag as w, useBioTemplateControls as x, toBioTemplateComponentPropsByComponent as y, validateImportFile as z };
|
|
4492
4740
|
|
|
4493
|
-
//# sourceMappingURL=
|
|
4741
|
+
//# sourceMappingURL=useJobsStatusTray-DAH999_N.js.map
|