taxonium-component
Version:
React component for exploring large phylogenetic trees in the browser
289 lines (288 loc) • 13.4 kB
JavaScript
import { jsxs as d, jsx as t, Fragment as B } from "react/jsx-runtime";
import { useState as k, useEffect as F, Suspense as L } from "react";
import { m as b, T as v, o as y, u as l, c as T, b_ as _, P as O, b$ as E, aw as G, bN as M, a7 as P, by as R, t as H, a as C, aR as $, bL as j, B as A, bK as V, bH as q, c0 as K } from "./JBrowsePanel-uJIA-L6s.js";
import { M as I } from "./MenuItem-D4Mw907e.js";
import { L as w } from "./Link-CZ78-213.js";
import { D as z } from "./Delete-bchuKNyZ.js";
import { C as Y, a as Q } from "./CardContent-G_V1s50Q.js";
import { L as W } from "./ListItem-shOX3Ebz.js";
import { F as X } from "./FormControlLabel-CwjOxa71.js";
import { C as Z } from "./Checkbox-BG4jcGUl.js";
import { S as ee, a as te, b as ae, c as ne } from "./Stepper-BhvIoojA.js";
const re = b()((e) => ({
spacing: {
marginBottom: e.spacing(3)
}
}));
function se({ trackAdapter: e, trackType: a }) {
const { classes: o } = re(), { type: r, subadapter: n } = e;
return r === "SNPCoverageAdapter" ? d(v, { className: o.spacing, children: ["Selected ", t("code", { children: a }), ". Using adapter ", t("code", { children: r }), " with subadapter ", t("code", { children: n == null ? void 0 : n.type }), ". Please enter a track name and, if necessary, update the track type."] }) : d(v, { className: o.spacing, children: ["Using adapter ", t("code", { children: r }), " and guessing track type", " ", t("code", { children: a }), ". Please enter a track name and, if necessary, update the track type."] });
}
function oe(e) {
var a;
const o = {};
for (const r of e) {
const n = ((a = r.adapterMetadata) === null || a === void 0 ? void 0 : a.category) || "Default";
o[n] || (o[n] = []), o[n].push(r);
}
return o;
}
const U = y(({ model: e }) => {
const { trackAdapter: a } = e, { pluginManager: o } = l.getEnv(e);
return t(T, { value: (a == null ? void 0 : a.type) !== "UNKNOWN" ? a == null ? void 0 : a.type : "", label: "Adapter type", variant: "outlined", select: !0, fullWidth: !0, onChange: (r) => {
e.setAdapterHint(r.target.value);
}, slotProps: {
select: {
SelectDisplayProps: {
"data-testid": "adapterTypeSelect"
}
}
}, children: Object.entries(oe(o.getAdapterElements().filter((r) => {
var n;
return !(!((n = r.adapterMetadata) === null || n === void 0) && n.hiddenFromGUI);
}))).map(([r, n]) => [
t(_, { children: r }, r),
n.map((c) => t(I, { value: c.name, children: c.displayName }, c.name))
]) });
}), ce = b()((e) => ({
spacing: {
marginBottom: e.spacing(3)
}
}));
function ie({ model: e }) {
const { classes: a } = ce();
return d(B, { children: [d(v, { className: a.spacing, children: ["JBrowse was not able to guess the adapter type for this data, but it may be in the list below. If not, you can", " ", t(w, { href: "https://github.com/GMOD/jbrowse-components/releases", target: "_blank", rel: "noopener noreferrer", children: "check for new releases" }), " ", "of JBrowse to see if they support this data type or", " ", t(w, { href: "https://github.com/GMOD/jbrowse-components/issues/new", target: "_blank", rel: "noopener noreferrer", children: "file an issue" }), " ", "and add a feature request for this data type."] }), t(U, { model: e })] });
}
const le = b()((e) => ({
paper: {
display: "flex",
flexDirection: "column",
padding: e.spacing(1)
},
card: {
marginTop: e.spacing(1)
}
})), de = y(function({ model: e }) {
const { classes: a } = le(), [o, r] = k(""), [n, c] = k(""), [s, p] = k(["Name", "ID"]), [i, f] = k(["CDS", "exon"]), S = [
{
label: "Indexing attributes",
values: s
},
{
label: "Feature types to exclude",
values: i
}
];
return F(() => {
e.setTextIndexingConf({ attributes: s, exclude: i });
}, [e, s, i]), d(O, { className: a.paper, children: [t(E, { children: "Indexing configuration" }), S.map((u, h) => t(Y, { raised: !0, className: a.card, children: d(Q, { children: [t(E, { children: u.label }), d(G, { disablePadding: !0, children: [u.values.map((g, x) => t(W, { disableGutters: !0, children: t(T, { value: g, slotProps: {
input: {
endAdornment: t(M, { position: "end", children: t(P, { onClick: () => {
const m = u.values.filter((D, J) => J !== x);
h === 0 ? p(m) : f(m);
}, children: t(z, {}) }) })
}
} }) }, `${g}-${x}`)), t(W, { disableGutters: !0, children: t(T, { value: h === 0 ? o : n, placeholder: "add new", onChange: (g) => {
h === 0 ? r(g.target.value) : c(g.target.value);
}, slotProps: {
input: {
endAdornment: t(M, { position: "end", children: t(P, { onClick: () => {
h === 0 ? (p([...s, o]), r("")) : (f([...i, n]), c(""));
}, disabled: h === 0 ? o === "" : n === "", "data-testid": "stringArrayAdd-Feat", children: t(R, {}) }) })
}
} }) })] })] }) }, u.label))] });
}), pe = y(function({ model: e }) {
const { pluginManager: a } = l.getEnv(e), { trackType: o } = e, r = a.getTrackElements();
return t(T, { value: o, variant: "outlined", label: "Track type", select: !0, fullWidth: !0, onChange: (n) => {
e.setTrackType(n.target.value);
}, slotProps: {
select: {
SelectDisplayProps: {
"data-testid": "trackTypeSelect"
}
}
}, children: r.map(({ name: n, displayName: c }) => t(I, { value: n, children: c }, n)) });
}), ue = b()((e) => ({
spacing: {
marginBottom: e.spacing(3)
}
}));
function fe() {
const { classes: e } = ue();
return d(v, { className: e.spacing, children: ["This version of JBrowse cannot display data of this type. It is possible, however, that there is a newer version that can display them. You can", " ", t(w, { href: "https://github.com/GMOD/jbrowse-components/releases", target: "_blank", rel: "noopener noreferrer", children: "check for new releases" }), " ", "of JBrowse or", " ", t(w, { href: "https://github.com/GMOD/jbrowse-components/issues/new", target: "_blank", rel: "noopener noreferrer", children: "file an issue" }), " ", "and add a feature request for this data type."] });
}
const he = b()((e) => ({
spacing: {
marginBottom: e.spacing(3)
}
})), ge = y(function({ model: a }) {
const { classes: o } = he(), [r, n] = k(!0), c = l.getSession(a), { trackName: s, unsupported: p, trackAdapter: i, trackType: f, warningMessage: S, adapterHint: u } = a;
if (F(() => {
u === "" && i && a.setAdapterHint(i.type);
}, [u, i, i == null ? void 0 : i.type, a]), p)
return t(fe, {});
if ((i == null ? void 0 : i.type) === H.UNKNOWN)
return t(ie, { model: a });
if (i != null && i.type) {
const h = l.isSupportedIndexingAdapter(i.type), { pluginManager: g } = l.getEnv(a), x = g.evaluateExtensionPoint("Core-addTrackComponent", ({ model: m }) => t(C.AssemblySelector, { session: c, helperText: "Select assembly to add track to", selected: m.assembly, onChange: (D) => {
m.setAssembly(D);
}, TextFieldProps: {
fullWidth: !0,
SelectProps: {
SelectDisplayProps: {
"data-testid": "assemblyNameSelect"
}
}
} }), { model: a });
return d("div", { children: [t(se, { trackAdapter: i, trackType: f }), S ? t(v, { color: "warning", children: S }) : null, t(T, { className: o.spacing, label: "trackName", helperText: "A name for this track", fullWidth: !0, value: s, onChange: (m) => {
a.setTrackName(m.target.value);
}, slotProps: {
htmlInput: {
"data-testid": "trackNameInput"
}
} }), d("div", { style: {
display: "flex",
flexDirection: "column",
gap: 10
}, children: [t(U, { model: a }), t(pe, { model: a }), t(L, { fallback: null, children: t(x, { model: a }) })] }), l.isElectron && h && t($, { children: t(X, { label: "Index track for text searching?", control: t(Z, { checked: r, onChange: (m) => {
n(m.target.checked), a.setTextIndexTrack(m.target.checked);
} }) }) }), l.isElectron && r && h ? t(de, { model: a }) : null] });
} else
return t(v, { children: "Could not recognize this data type." });
}), me = b()((e) => ({
paper: {
padding: e.spacing(2)
},
spacer: {
height: e.spacing(8)
}
})), ke = y(function({ model: e }) {
const { classes: a } = me(), o = j(e);
return d(O, { className: a.paper, children: [t(C.FileSelector, { name: "Main file", description: "", location: e.trackData, setLocation: e.setTrackData, setName: e.setTrackName, rootModel: o }), t("div", { className: a.spacer }), t(C.FileSelector, { name: "Index file", description: "(Optional) The URL of the index file is automatically inferred from the URL of the main file if it is not supplied.", location: e.indexTrackData, setLocation: e.setIndexTrackData, setName: e.setTrackName, rootModel: o })] });
});
function be({ trackId: e, model: a }) {
const { textIndexingConf: o, trackName: r, assembly: n } = a, { jobsManager: c } = j(a), s = o || {
attributes: ["Name", "ID"],
exclude: ["CDS", "exon"]
}, p = `${r}-index`;
c.queueJob({
indexingParams: {
...s,
assemblies: [n],
tracks: [e],
indexType: "perTrack",
name: p,
timestamp: (/* @__PURE__ */ new Date()).toISOString()
},
name: p,
cancelCallback: () => c.abortJob()
});
}
function ye({ model: e }) {
var a;
const { textIndexTrack: o, trackAdapter: r, view: n } = e, c = l.getSession(e), s = e.getTrackConfig(Date.now());
if (l.isSessionWithAddTracks(c))
if (s && r) {
const { trackId: p } = s;
c.addTrackConf(s), (a = n == null ? void 0 : n.showTrack) === null || a === void 0 || a.call(n, p), l.isElectron && o && l.isSupportedIndexingAdapter(r.type) && be({
model: e,
trackId: p
}), e.clearData(), l.isSessionModelWithWidgets(c) && c.hideWidget(e);
} else
throw new Error(`Failed to add track.
The configuration of this file is not currently supported.`);
else throw new Error("Can't add tracks to this session");
}
const ve = b()((e) => ({
root: {
marginTop: e.spacing(1)
},
stepper: {
backgroundColor: e.palette.background.default
},
button: {
marginRight: e.spacing(1)
},
actionsContainer: {
marginTop: e.spacing(10),
marginBottom: e.spacing(2)
},
alertContainer: {
padding: `${e.spacing(2)}px 0px ${e.spacing(2)}px 0px`
}
})), N = ["Enter track data", "Confirm track type"], Se = y(function({ model: e }) {
const [a, o] = k(0), { classes: r } = ve(), { assembly: n, trackAdapter: c, trackData: s, trackName: p, trackType: i } = e;
function f(u) {
switch (u) {
case 0:
return t(ke, { model: e });
case 1:
return t(ge, { model: e });
default:
return t(v, { children: "Unknown step" });
}
}
function S() {
switch (a) {
case 0:
return !s;
case 1:
return !(p && i && (c != null && c.type) && n);
default:
return !0;
}
}
return t("div", { className: r.root, children: t(ee, { className: r.stepper, activeStep: a, orientation: "vertical", children: N.map((u, h) => d(te, { children: [t(ae, { children: u }), d(ne, { children: [f(h), d("div", { className: r.actionsContainer, children: [t(A, { disabled: a === 0, className: r.button, onClick: () => {
o(a - 1);
}, children: "Back" }), t(A, { disabled: S(), variant: "contained", color: "primary", onClick: () => {
if (a !== N.length - 1)
o(a + 1);
else
try {
ye({ model: e });
} catch (g) {
l.getSession(e).notifyError(`${g}`, g);
}
}, className: r.button, "data-testid": "addTrackNextButton", children: a === N.length - 1 ? "Add" : "Next" })] })] })] }, u)) }) });
}), Te = b()({
textbox: {
width: "100%"
},
submit: {
marginTop: 25,
marginBottom: 100,
display: "block"
}
}), xe = y(function({ model: e }) {
const { classes: a } = Te(), [o, r] = k(""), [n, c] = k();
return d("div", { children: [n ? t(C.ErrorMessage, { error: n }) : null, t(T, { multiline: !0, rows: 10, value: o, placeholder: "Paste track config or array of track configs in JSON format", variant: "outlined", className: a.textbox, onChange: (s) => {
r(s.target.value);
} }), t(A, { variant: "contained", className: a.submit, onClick: () => {
try {
c(void 0);
const s = l.getSession(e), p = JSON.parse(o), i = Array.isArray(p) ? p : [p];
l.isSessionWithAddTracks(s) && l.isSessionModelWithWidgets(s) && (V(() => {
for (const f of i)
s.addTrackConf(f);
for (const f of i)
e.view.showTrack(f.trackId);
e.clearData();
}), s.hideWidget(e));
} catch (s) {
console.error(s), c(s);
}
}, children: "Submit" })] });
}), Fe = y(function({ model: e }) {
const [a, o] = k("Default add track workflow"), r = {
"Default add track workflow": Se,
"Add track JSON": xe,
...Object.fromEntries(l.getEnv(e).pluginManager.getAddTrackWorkflowElements().map((s) => [s.name, s.ReactComponent]))
}, n = r[a] ? a : "Default add track workflow", c = r[n];
return d(B, { children: [d($, { children: [t(q, { value: n, onChange: (s) => {
o(s.target.value);
}, children: Object.keys(r).map((s) => t(I, { value: s, children: s }, s)) }), t(K, { children: "Type of add track workflow" })] }), t(L, { fallback: null, children: t(c, { model: e }) })] });
});
export {
Fe as default
};
//# sourceMappingURL=AddTrackWidget-B2nYWJWu.js.map