UNPKG

taxonium-component

Version:

React component for exploring large phylogenetic trees in the browser

217 lines (216 loc) 9.26 kB
import { jsxs as h, Fragment as x, jsx as t } from "react/jsx-runtime"; import { useState as C } from "react"; import { D as O } from "./DraggableDialog-SkGHL3cH.js"; import { m as E, D as G, T as P, a as I, c as R, d as N, B as p, aZ as T, u as w, ap as A, aq as B, ar as F, as as _ } from "./JBrowsePanel-BNE3gNW1.js"; import { r as U } from "./util-B1Sm35mH.js"; import { a as W, C as K } from "./ColorPicker-BTI_Q3I7.js"; import { D as L } from "./DataGrid-cokHFdGI.js"; const V = E()({ textAreaFont: { fontFamily: "Courier New" } }); function $({ onClose: e, currLayout: l }) { const { classes: i } = V(), [o, a] = C(""), [r, n] = C(); return h(x, { children: [h(G, { children: [t(P, { children: 'Paste CSV or TSV. If a header column is present. First line is a header. If a column called "name" is present, it uses that to connect to IDs in the table, otherwise it uses the first column no.' }), r ? t(I.ErrorMessage, { error: r }) : null, t(R, { variant: "outlined", multiline: !0, minRows: 5, placeholder: `name,population HG00098,GBR HG00101,GBR HG00459,CHS ...`, maxRows: 10, fullWidth: !0, value: o, onChange: (s) => { a(s.target.value); }, slotProps: { input: { classes: { input: i.textAreaFont } } } })] }), h(N, { children: [t(p, { variant: "contained", color: "secondary", onClick: () => { const s = o.split(` `).map((u) => u.trim()).filter((u) => !!u), m = s[0].split(/[,\t]/gm); if (m.includes("name")) { n(""); const u = Object.fromEntries(l.map((c) => [c.name, c])), f = Object.fromEntries(s.slice(1).map((c) => { const S = c.split(/[,\t]/gm), d = Object.fromEntries(S.map((b, g) => [m[g], b])); return [ d.name, { ...d, ...u[d.name] } ]; })); e(l.map((c) => ({ ...c, ...f[c.name] }))); } else n(new Error('No "name" column found on line 1')); }, children: "Update rows" }), t(p, { variant: "contained", color: "primary", onClick: () => { const s = o.split(` `).map((u) => u.trim()).filter((u) => !!u), m = s[0].split(/[,\t]/gm); if (m.includes("name")) { n(""); const u = Object.fromEntries(l.map((c) => [c.name, c])), f = Object.fromEntries(s.slice(1).map((c) => { const S = c.split(/[,\t]/gm), d = Object.fromEntries(S.map((b, g) => [m[g], b])); return [ d.name, { ...d, ...u[d.name] } ]; })); e(l.map((c) => ({ ...f[c.name] }))); } else n(new Error('No "name" column found on line 1')); }, children: "Replace rows" }), t(p, { variant: "contained", color: "inherit", onClick: () => { e(); }, children: "Cancel" })] })] }); } function z() { return h(x, { children: ["Helpful tips", h("ul", { children: [t("li", { children: "You can select rows in the table with the checkboxes" }), t("li", { children: "Multi-select is enabled with shift-click and control-click" }), t("li", { children: 'The "Move selected items up/down" can re-arrange subtracks' }), t("li", { children: "Sorting the data grid itself can also re-arrange subtracks" }), t("li", { children: "Changes are applied when you hit Submit" }), t("li", { children: "You can click and drag the dialog box to move it on the screen" }), t("li", { children: "Columns in the table can be hidden using a vertical '...' menu on the right side of each column" })] })] }); } function Y({ setCurrLayout: e, currLayout: l }) { var i; return h("div", { children: ["Create color palette based on...", Object.keys((i = l[0]) !== null && i !== void 0 ? i : []).filter((o) => o !== "name" && o !== "color" && o !== "label" && o !== "id" && o !== "HP").map((o) => t(p, { variant: "contained", color: "inherit", onClick: () => { const a = /* @__PURE__ */ new Map(); for (const n of l) { const s = a.get(n[o]); s ? a.set(n[o], s + 1) : a.set(n[o], 1); } const r = Object.fromEntries([...a.entries()].sort((n, s) => n[1] - s[1]).map((n, s) => [n[0], T.set1[s] || U(n[0])])); e(l.map((n) => ({ ...n, color: r[n[o]] }))); }, children: o }, o)), t(p, { onClick: () => { e(l.map((o) => ({ ...o, color: void 0 }))); }, children: "Clear colors" })] }); } const q = E()({ cell: { whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" } }); function Z({ rows: e, onChange: l, setSelected: i }) { const { classes: o } = q(), { id: a, name: r, label: n, color: s, baseUri: m, HP: u, ...f } = e[0], [c, S] = C({ idx: 0, field: null }); return t("div", { style: { height: 400, width: "100%" }, children: t(L, { checkboxSelection: !0, disableRowSelectionOnClick: !0, onRowSelectionModelChange: (d) => { i([...d.ids]); }, rows: e, rowHeight: 25, columnHeaderHeight: 33, columns: [ { field: "color", headerName: "Color", renderCell: (d) => { const { value: b, id: g } = d; return t(W, { color: b || "blue", onChange: (v) => { const k = e.find((y) => y.name === g); k && (k.color = v), l([...e]); } }); } }, { field: "label", headerName: "Name", width: w.measureGridWidth(e.map((d) => d.label)) }, ...Object.keys(f).map((d) => ({ field: d, renderCell: ({ value: b }) => t("div", { className: o.cell, children: t(I.SanitizedHTML, { html: w.getStr(b) }) }), width: w.measureGridWidth(e.map((b) => `${b[d]}`)) })) ], sortModel: [], onSortModelChange: (d) => { const b = d[0], g = (c.idx + 1) % 2, v = b.field || c.field; S({ idx: g, field: v }), l(v ? [...e].sort((k, y) => { const D = w.getStr(k[v]), H = w.getStr(y[v]); return g === 1 ? D.localeCompare(H) : H.localeCompare(D); }) : e); } }) }); } function M(e, l, i = 1) { const o = l.map((r) => e.findIndex((n) => n.name === r)).sort((r, n) => r - n); let a = 0; for (const r of o) { const n = Math.max(a, r - i); n >= a && e.splice(n, 0, e.splice(r, 1)[0]), a = a + 1; } return e; } function j(e, l, i = 1) { const o = l.map((r) => e.findIndex((n) => n.name === r)).sort((r, n) => n - r); let a = e.length - 1; for (const r of o) { const n = Math.min(a, r + i); n <= a && e.splice(n, 0, e.splice(r, 1)[0]), a = a - 1; } return e; } function J({ selected: e, onChange: l, rows: i, showTips: o }) { const [a, r] = C(null), [n, s] = C("blue"); return h(x, { children: [t(p, { disabled: !e.length, onClick: (m) => { r(m.currentTarget); }, children: "Change color of selected items" }), h(p, { onClick: () => { l(M([...i], e)); }, disabled: !e.length, children: [t(A, {}), o ? "Move selected items up" : null] }), h(p, { onClick: () => { l(j([...i], e)); }, disabled: !e.length, children: [t(B, {}), o ? "Move selected items down" : null] }), h(p, { onClick: () => { l(M([...i], e, i.length)); }, disabled: !e.length, children: [t(F, {}), o ? "Move selected items to top" : null] }), h(p, { onClick: () => { l(j([...i], e, i.length)); }, disabled: !e.length, children: [t(_, {}), o ? "Move selected items to bottom" : null] }), t(K.ColorPopover, { anchorEl: a, color: n, onChange: (m) => { s(m); for (const u of e) { const f = i.find((c) => c.name === u); f && (f.color = m); } l([...i]); }, onClose: () => { r(null); } })] }); } function Q({ rows: e, onChange: l, showTips: i }) { const [o, a] = C([]); return h("div", { children: [t(J, { selected: o, rows: e, showTips: i, onChange: l }), e.length ? t(Z, { rows: e, onChange: l, setSelected: a }) : t("div", { children: "No rows" })] }); } const X = E()({ content: { minWidth: 800 }, fr: { float: "right", display: "flex", gap: 8 }, textAreaFont: { fontFamily: "Courier New" } }); function ae({ model: e, handleClose: l }) { const { classes: i } = X(), { sources: o } = e, [a, r] = C(!1), [n, s] = C(o || []), [m, u] = w.useLocalStorage("multivariant-showTips", !1); return t(O, { open: !0, onClose: l, maxWidth: "xl", title: "Multi-sample variant display - Color/arrangement editor", children: a ? t($, { currLayout: n, onClose: (f) => { f && s(f), r(!1); } }) : h(x, { children: [h(G, { className: i.content, children: [h("div", { className: i.fr, children: [t(p, { variant: "contained", onClick: () => { u(!m); }, children: m ? "Hide tips" : "Show tips" }), t(p, { color: "secondary", variant: "contained", onClick: () => { r(!a); }, children: "Show Bulk row editor" })] }), m ? t(z, {}) : null, t("br", {}), t(Y, { currLayout: n, setCurrLayout: s }), t(Q, { rows: n, onChange: s, showTips: m })] }), h(N, { children: [t(p, { variant: "contained", type: "submit", color: "inherit", onClick: () => { e.clearLayout(), s(e.sources || []); }, children: "Clear custom settings" }), t(p, { variant: "contained", color: "secondary", onClick: () => { l(), s([...e.sources || []]); }, children: "Cancel" }), t(p, { variant: "contained", color: "primary", type: "submit", onClick: () => { e.setLayout(n), l(); }, children: "Submit" })] })] }) }); } export { ae as default }; //# sourceMappingURL=SetColorDialog-CzpTQ92l.js.map