gramene-search 2.21.0 → 2.22.0
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/index.css +21 -2
- package/dist/index.css.map +1 -1
- package/dist/index.js +367 -86
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -850,6 +850,42 @@ function $af4441dd29af05df$var$markSubtree(node, source, invert) {
|
|
|
850
850
|
});
|
|
851
851
|
}
|
|
852
852
|
const $af4441dd29af05df$export$6b95404109a3e2ec = 'Genomic intervals';
|
|
853
|
+
function $af4441dd29af05df$export$634f7214da1b780a({ map: map, region: region, start: start, end: end }) {
|
|
854
|
+
return `(map:${map} AND region:${region}` + ` AND start:[* TO ${end}] AND end:[${start} TO *])`;
|
|
855
|
+
}
|
|
856
|
+
function $af4441dd29af05df$export$535c09441f37845d({ mapLabel: mapLabel, map: map, region: region, start: start, end: end }) {
|
|
857
|
+
return `${mapLabel || map} ${region}:${Number(start).toLocaleString()}-${Number(end).toLocaleString()}`;
|
|
858
|
+
}
|
|
859
|
+
// Note the field order is inverted relative to the interval: `start` carries the
|
|
860
|
+
// interval's END and `end` carries its START, because the pair is an overlap test.
|
|
861
|
+
const $af4441dd29af05df$var$INTERVAL_RE = /^\(map:(\S+) AND region:(\S+) AND start:\[\* TO (\d+)\] AND end:\[(\d+) TO \*\]\)$/;
|
|
862
|
+
function $af4441dd29af05df$export$67920d3e3cb3f136(fqValue) {
|
|
863
|
+
const m = $af4441dd29af05df$var$INTERVAL_RE.exec(String(fqValue || ''));
|
|
864
|
+
if (!m) return null;
|
|
865
|
+
return {
|
|
866
|
+
map: m[1],
|
|
867
|
+
region: m[2],
|
|
868
|
+
end: Number(m[3]),
|
|
869
|
+
start: Number(m[4])
|
|
870
|
+
};
|
|
871
|
+
}
|
|
872
|
+
/** `[lo TO hi]`, as produced by the expression brush and the Location tab. */ const $af4441dd29af05df$var$RANGE_RE = /^\[\s*(\S+)\s+TO\s+(\S+)\s*\]$/;
|
|
873
|
+
function $af4441dd29af05df$export$9ee0ceaa589fc567(fqValue) {
|
|
874
|
+
const m = $af4441dd29af05df$var$RANGE_RE.exec(String(fqValue || ''));
|
|
875
|
+
return m ? {
|
|
876
|
+
lo: m[1],
|
|
877
|
+
hi: m[2]
|
|
878
|
+
} : null;
|
|
879
|
+
}
|
|
880
|
+
function $af4441dd29af05df$export$cd9b2ffd001c6d65(lo, hi) {
|
|
881
|
+
return `[${lo} TO ${hi}]`;
|
|
882
|
+
}
|
|
883
|
+
function $af4441dd29af05df$export$a7f4fa59930e5088(node) {
|
|
884
|
+
if (!node || node.hasOwnProperty('children')) return null;
|
|
885
|
+
if ($af4441dd29af05df$export$67920d3e3cb3f136(node.fq_value)) return 'interval';
|
|
886
|
+
if ($af4441dd29af05df$export$9ee0ceaa589fc567(node.fq_value)) return 'range';
|
|
887
|
+
return 'value';
|
|
888
|
+
}
|
|
853
889
|
const $af4441dd29af05df$export$da3188ffd2da2525 = {
|
|
854
890
|
orthologs: {
|
|
855
891
|
label: 'orthologs',
|
|
@@ -1061,8 +1097,19 @@ const $af4441dd29af05df$var$grameneFilters = {
|
|
|
1061
1097
|
// start, so a gene that merely crosses the boundary still matches.
|
|
1062
1098
|
const intervalNode = {
|
|
1063
1099
|
fq_field: 'location',
|
|
1064
|
-
fq_value:
|
|
1065
|
-
|
|
1100
|
+
fq_value: $af4441dd29af05df$export$634f7214da1b780a({
|
|
1101
|
+
map: map,
|
|
1102
|
+
region: region,
|
|
1103
|
+
start: start,
|
|
1104
|
+
end: end
|
|
1105
|
+
}),
|
|
1106
|
+
name: $af4441dd29af05df$export$535c09441f37845d({
|
|
1107
|
+
mapLabel: mapLabel,
|
|
1108
|
+
map: map,
|
|
1109
|
+
region: region,
|
|
1110
|
+
start: start,
|
|
1111
|
+
end: end
|
|
1112
|
+
}),
|
|
1066
1113
|
category: 'Genomic interval',
|
|
1067
1114
|
negate: false,
|
|
1068
1115
|
showMenu: false
|
|
@@ -1084,6 +1131,24 @@ const $af4441dd29af05df$var$grameneFilters = {
|
|
|
1084
1131
|
$af4441dd29af05df$var$markSubtree(newState, newState, false);
|
|
1085
1132
|
return newState;
|
|
1086
1133
|
}
|
|
1134
|
+
case 'GRAMENE_FILTER_EDITED':
|
|
1135
|
+
{
|
|
1136
|
+
// Edits only rewrite a leaf's value and label. The node keeps its place,
|
|
1137
|
+
// its negate flag and any expansion, and the tree shape is untouched — so
|
|
1138
|
+
// unlike an insert there is nothing to reindex.
|
|
1139
|
+
newState = Object.assign({}, state, {
|
|
1140
|
+
status: 'search',
|
|
1141
|
+
showMarked: true,
|
|
1142
|
+
searchOffset: 0
|
|
1143
|
+
});
|
|
1144
|
+
const node = $af4441dd29af05df$var$findNodeWithLeftIdx(newState, payload.leftIdx);
|
|
1145
|
+
if (!node || node.hasOwnProperty('children')) break;
|
|
1146
|
+
node.fq_value = payload.fq_value;
|
|
1147
|
+
if (payload.name !== undefined) node.name = payload.name;
|
|
1148
|
+
node.showMenu = false;
|
|
1149
|
+
$af4441dd29af05df$var$markSubtree(newState, node, false);
|
|
1150
|
+
return newState;
|
|
1151
|
+
}
|
|
1087
1152
|
case 'GRAMENE_FILTER_EXPANSION_SET':
|
|
1088
1153
|
{
|
|
1089
1154
|
// Setting or clearing an expansion is just a field on the node — the tree
|
|
@@ -1419,6 +1484,28 @@ const $af4441dd29af05df$var$grameneFilters = {
|
|
|
1419
1484
|
]
|
|
1420
1485
|
});
|
|
1421
1486
|
},
|
|
1487
|
+
// Replace one leaf's value in place, keeping its position in the tree.
|
|
1488
|
+
doEditGrameneFilter: (filter, fq_value, name)=>({ dispatch: dispatch })=>{
|
|
1489
|
+
dispatch({
|
|
1490
|
+
type: 'BATCH_ACTIONS',
|
|
1491
|
+
actions: [
|
|
1492
|
+
{
|
|
1493
|
+
type: 'GRAMENE_SEARCH_CLEARED'
|
|
1494
|
+
},
|
|
1495
|
+
{
|
|
1496
|
+
type: 'GRAMENE_TAXONOMY_CLEARED'
|
|
1497
|
+
},
|
|
1498
|
+
{
|
|
1499
|
+
type: 'GRAMENE_FILTER_EDITED',
|
|
1500
|
+
payload: {
|
|
1501
|
+
leftIdx: filter.leftIdx,
|
|
1502
|
+
fq_value: fq_value,
|
|
1503
|
+
name: name
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
]
|
|
1507
|
+
});
|
|
1508
|
+
},
|
|
1422
1509
|
doToggleGrameneFilterMenu: (node)=>({ dispatch: dispatch })=>{
|
|
1423
1510
|
dispatch({
|
|
1424
1511
|
type: 'GRAMENE_FILTER_MENU_TOGGLED',
|
|
@@ -20883,18 +20970,26 @@ function $909272efb41be16f$export$94955a075dcb14b2(genome) {
|
|
|
20883
20970
|
length: lengths[i]
|
|
20884
20971
|
})).filter((r)=>!$909272efb41be16f$var$UNPLACED.test(String(r.name)));
|
|
20885
20972
|
}
|
|
20886
|
-
const $909272efb41be16f$
|
|
20887
|
-
const [open, setOpen] = (0, $gXNCa$react.useState)(false);
|
|
20973
|
+
const $909272efb41be16f$export$4fa3dba3103266ea = ({ grameneMaps: grameneMaps, targetTaxonId: targetTaxonId, initial: initial, submitLabel: submitLabel, onSubmit: onSubmit, onCancel: onCancel })=>{
|
|
20888
20974
|
const [taxonId, setTaxonId] = (0, $gXNCa$react.useState)('');
|
|
20889
|
-
const [region, setRegion] = (0, $gXNCa$react.useState)('');
|
|
20890
|
-
const [start, setStart] = (0, $gXNCa$react.useState)('');
|
|
20891
|
-
const [end, setEnd] = (0, $gXNCa$react.useState)('');
|
|
20975
|
+
const [region, setRegion] = (0, $gXNCa$react.useState)(initial ? String(initial.region) : '');
|
|
20976
|
+
const [start, setStart] = (0, $gXNCa$react.useState)(initial ? String(initial.start) : '');
|
|
20977
|
+
const [end, setEnd] = (0, $gXNCa$react.useState)(initial ? String(initial.end) : '');
|
|
20892
20978
|
const { reference: reference, anchors: anchors, rest: rest } = (0, $gXNCa$react.useMemo)(()=>$909272efb41be16f$export$ac97d17982e0cb21(grameneMaps, targetTaxonId), [
|
|
20893
20979
|
grameneMaps,
|
|
20894
20980
|
targetTaxonId
|
|
20895
20981
|
]);
|
|
20896
|
-
//
|
|
20897
|
-
|
|
20982
|
+
// An edit starts on the filter's own genome; a new interval starts on the
|
|
20983
|
+
// site's reference. `initial.map` is an assembly accession, so find its genome.
|
|
20984
|
+
const initialTaxon = (0, $gXNCa$react.useMemo)(()=>{
|
|
20985
|
+
if (!initial) return '';
|
|
20986
|
+
const hit = Object.values(grameneMaps || {}).find((m)=>m && m._id === initial.map);
|
|
20987
|
+
return hit ? String(hit.taxon_id) : '';
|
|
20988
|
+
}, [
|
|
20989
|
+
initial,
|
|
20990
|
+
grameneMaps
|
|
20991
|
+
]);
|
|
20992
|
+
const effectiveTaxon = taxonId || initialTaxon || reference[0] && String(reference[0].taxon_id) || '';
|
|
20898
20993
|
const genome = effectiveTaxon ? (grameneMaps || {})[effectiveTaxon] : null;
|
|
20899
20994
|
const chromosomes = (0, $gXNCa$react.useMemo)(()=>$909272efb41be16f$export$94955a075dcb14b2(genome), [
|
|
20900
20995
|
genome
|
|
@@ -20906,8 +21001,7 @@ const $909272efb41be16f$var$GenomicIntervalForm = ({ grameneMaps: grameneMaps, t
|
|
|
20906
21001
|
// Validated against the assembly's own region lengths, so the message can name
|
|
20907
21002
|
// the actual limit rather than just refusing.
|
|
20908
21003
|
const error = (()=>{
|
|
20909
|
-
if (!genome) return null;
|
|
20910
|
-
if (s === null || e === null) return null;
|
|
21004
|
+
if (!genome || s === null || e === null) return null;
|
|
20911
21005
|
if (!Number.isFinite(s) || !Number.isFinite(e)) return 'Positions must be numbers.';
|
|
20912
21006
|
if (s < 1 || e < 1) return 'Positions start at 1.';
|
|
20913
21007
|
if (s > e) return 'Start must not be greater than end.';
|
|
@@ -20917,112 +21011,134 @@ const $909272efb41be16f$var$GenomicIntervalForm = ({ grameneMaps: grameneMaps, t
|
|
|
20917
21011
|
const ready = !!genome && !!effectiveRegion && s !== null && e !== null && !error;
|
|
20918
21012
|
const submit = ()=>{
|
|
20919
21013
|
if (!ready) return;
|
|
20920
|
-
|
|
21014
|
+
onSubmit({
|
|
20921
21015
|
map: genome._id,
|
|
20922
21016
|
mapLabel: genome.display_name || genome._id,
|
|
20923
21017
|
region: effectiveRegion,
|
|
20924
21018
|
start: s,
|
|
20925
21019
|
end: e
|
|
20926
21020
|
});
|
|
20927
|
-
|
|
20928
|
-
|
|
21021
|
+
if (!initial) {
|
|
21022
|
+
setStart('');
|
|
21023
|
+
setEnd('');
|
|
21024
|
+
}
|
|
20929
21025
|
};
|
|
20930
21026
|
const genomeOption = (m)=>/*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("option", {
|
|
20931
21027
|
value: m.taxon_id,
|
|
20932
21028
|
children: m.display_name || m.system_name
|
|
20933
21029
|
}, m.taxon_id);
|
|
20934
21030
|
return /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsxs)("div", {
|
|
20935
|
-
className: "gramene-interval",
|
|
21031
|
+
className: "gramene-interval-form",
|
|
20936
21032
|
children: [
|
|
20937
|
-
/*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsxs)(
|
|
20938
|
-
|
|
20939
|
-
|
|
21033
|
+
/*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsxs)((0, $gXNCa$reactbootstrap.Form).Select, {
|
|
21034
|
+
size: "sm",
|
|
21035
|
+
className: "mb-1",
|
|
21036
|
+
value: effectiveTaxon,
|
|
21037
|
+
onChange: (ev)=>{
|
|
21038
|
+
setTaxonId(ev.target.value);
|
|
21039
|
+
setRegion('');
|
|
21040
|
+
},
|
|
20940
21041
|
children: [
|
|
20941
|
-
|
|
20942
|
-
|
|
21042
|
+
reference.map(genomeOption),
|
|
21043
|
+
anchors.length > 0 && /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("optgroup", {
|
|
21044
|
+
label: "Reference genomes",
|
|
21045
|
+
children: anchors.map(genomeOption)
|
|
21046
|
+
}),
|
|
21047
|
+
rest.length > 0 && /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("optgroup", {
|
|
21048
|
+
label: "Other genomes",
|
|
21049
|
+
children: rest.map(genomeOption)
|
|
21050
|
+
})
|
|
20943
21051
|
]
|
|
20944
21052
|
}),
|
|
20945
|
-
|
|
20946
|
-
|
|
20947
|
-
|
|
20948
|
-
|
|
20949
|
-
|
|
20950
|
-
|
|
20951
|
-
value:
|
|
20952
|
-
onChange: (ev)=>{
|
|
20953
|
-
setTaxonId(ev.target.value);
|
|
20954
|
-
setRegion('');
|
|
20955
|
-
},
|
|
21053
|
+
/*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)((0, $gXNCa$reactbootstrap.Form).Select, {
|
|
21054
|
+
size: "sm",
|
|
21055
|
+
className: "mb-1",
|
|
21056
|
+
value: effectiveRegion,
|
|
21057
|
+
onChange: (ev)=>setRegion(ev.target.value),
|
|
21058
|
+
children: chromosomes.map((c)=>/*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsxs)("option", {
|
|
21059
|
+
value: c.name,
|
|
20956
21060
|
children: [
|
|
20957
|
-
|
|
20958
|
-
|
|
20959
|
-
label: "Reference genomes",
|
|
20960
|
-
children: anchors.map(genomeOption)
|
|
20961
|
-
}),
|
|
20962
|
-
rest.length > 0 && /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("optgroup", {
|
|
20963
|
-
label: "Other genomes",
|
|
20964
|
-
children: rest.map(genomeOption)
|
|
20965
|
-
})
|
|
21061
|
+
c.name,
|
|
21062
|
+
c.length ? ` (${Math.round(c.length / 1e6)} Mb)` : ''
|
|
20966
21063
|
]
|
|
20967
|
-
})
|
|
20968
|
-
|
|
21064
|
+
}, c.name))
|
|
21065
|
+
}),
|
|
21066
|
+
/*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsxs)("div", {
|
|
21067
|
+
className: "gramene-interval-range",
|
|
21068
|
+
children: [
|
|
21069
|
+
/*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)((0, $gXNCa$reactbootstrap.Form).Control, {
|
|
20969
21070
|
size: "sm",
|
|
20970
|
-
|
|
20971
|
-
|
|
20972
|
-
|
|
20973
|
-
|
|
20974
|
-
|
|
20975
|
-
children: [
|
|
20976
|
-
c.name,
|
|
20977
|
-
c.length ? ` (${Math.round(c.length / 1e6)} Mb)` : ''
|
|
20978
|
-
]
|
|
20979
|
-
}, c.name))
|
|
20980
|
-
}),
|
|
20981
|
-
/*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsxs)("div", {
|
|
20982
|
-
className: "gramene-interval-range",
|
|
20983
|
-
children: [
|
|
20984
|
-
/*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)((0, $gXNCa$reactbootstrap.Form).Control, {
|
|
20985
|
-
size: "sm",
|
|
20986
|
-
type: "number",
|
|
20987
|
-
min: "1",
|
|
20988
|
-
placeholder: "start",
|
|
20989
|
-
value: start,
|
|
20990
|
-
onChange: (ev)=>setStart(ev.target.value)
|
|
20991
|
-
}),
|
|
20992
|
-
/*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("span", {
|
|
20993
|
-
className: "gramene-interval-dash",
|
|
20994
|
-
children: "\u2013"
|
|
20995
|
-
}),
|
|
20996
|
-
/*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)((0, $gXNCa$reactbootstrap.Form).Control, {
|
|
20997
|
-
size: "sm",
|
|
20998
|
-
type: "number",
|
|
20999
|
-
min: "1",
|
|
21000
|
-
placeholder: "end",
|
|
21001
|
-
value: end,
|
|
21002
|
-
onChange: (ev)=>setEnd(ev.target.value),
|
|
21003
|
-
onKeyDown: (ev)=>{
|
|
21004
|
-
if (ev.key === 'Enter') submit();
|
|
21005
|
-
}
|
|
21006
|
-
})
|
|
21007
|
-
]
|
|
21071
|
+
type: "number",
|
|
21072
|
+
min: "1",
|
|
21073
|
+
placeholder: "start",
|
|
21074
|
+
value: start,
|
|
21075
|
+
onChange: (ev)=>setStart(ev.target.value)
|
|
21008
21076
|
}),
|
|
21009
|
-
|
|
21010
|
-
className: "gramene-interval-
|
|
21011
|
-
children:
|
|
21077
|
+
/*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("span", {
|
|
21078
|
+
className: "gramene-interval-dash",
|
|
21079
|
+
children: "\u2013"
|
|
21012
21080
|
}),
|
|
21081
|
+
/*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)((0, $gXNCa$reactbootstrap.Form).Control, {
|
|
21082
|
+
size: "sm",
|
|
21083
|
+
type: "number",
|
|
21084
|
+
min: "1",
|
|
21085
|
+
placeholder: "end",
|
|
21086
|
+
value: end,
|
|
21087
|
+
onChange: (ev)=>setEnd(ev.target.value),
|
|
21088
|
+
onKeyDown: (ev)=>{
|
|
21089
|
+
if (ev.key === 'Enter') submit();
|
|
21090
|
+
}
|
|
21091
|
+
})
|
|
21092
|
+
]
|
|
21093
|
+
}),
|
|
21094
|
+
error && /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("div", {
|
|
21095
|
+
className: "gramene-interval-error",
|
|
21096
|
+
children: error
|
|
21097
|
+
}),
|
|
21098
|
+
/*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsxs)("div", {
|
|
21099
|
+
className: "gramene-interval-actions",
|
|
21100
|
+
children: [
|
|
21013
21101
|
/*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)((0, $gXNCa$reactbootstrap.Button), {
|
|
21014
21102
|
size: "sm",
|
|
21015
21103
|
variant: "primary",
|
|
21016
21104
|
className: "gramene-interval-submit",
|
|
21017
21105
|
disabled: !ready,
|
|
21018
21106
|
onClick: submit,
|
|
21019
|
-
children:
|
|
21107
|
+
children: submitLabel || 'Add interval'
|
|
21108
|
+
}),
|
|
21109
|
+
onCancel && /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)((0, $gXNCa$reactbootstrap.Button), {
|
|
21110
|
+
size: "sm",
|
|
21111
|
+
variant: "link",
|
|
21112
|
+
className: "gramene-interval-cancel",
|
|
21113
|
+
onClick: onCancel,
|
|
21114
|
+
children: "cancel"
|
|
21020
21115
|
})
|
|
21021
21116
|
]
|
|
21022
21117
|
})
|
|
21023
21118
|
]
|
|
21024
21119
|
});
|
|
21025
21120
|
};
|
|
21121
|
+
/** The collapsible "Add genomic interval" entry at the foot of the Filters panel. */ const $909272efb41be16f$var$GenomicIntervalForm = ({ grameneMaps: grameneMaps, targetTaxonId: targetTaxonId, onAdd: onAdd })=>{
|
|
21122
|
+
const [open, setOpen] = (0, $gXNCa$react.useState)(false);
|
|
21123
|
+
return /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsxs)("div", {
|
|
21124
|
+
className: "gramene-interval",
|
|
21125
|
+
children: [
|
|
21126
|
+
/*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsxs)("div", {
|
|
21127
|
+
className: "gramene-interval-toggle",
|
|
21128
|
+
onClick: ()=>setOpen(!open),
|
|
21129
|
+
children: [
|
|
21130
|
+
open ? /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)((0, $gXNCa$reacticonsbs.BsChevronDown), {}) : /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)((0, $gXNCa$reacticonsbs.BsChevronRight), {}),
|
|
21131
|
+
" Add genomic interval"
|
|
21132
|
+
]
|
|
21133
|
+
}),
|
|
21134
|
+
open && /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)($909272efb41be16f$export$4fa3dba3103266ea, {
|
|
21135
|
+
grameneMaps: grameneMaps,
|
|
21136
|
+
targetTaxonId: targetTaxonId,
|
|
21137
|
+
onSubmit: onAdd
|
|
21138
|
+
})
|
|
21139
|
+
]
|
|
21140
|
+
});
|
|
21141
|
+
};
|
|
21026
21142
|
var $909272efb41be16f$export$2e2bcd8739ae039 = $909272efb41be16f$var$GenomicIntervalForm;
|
|
21027
21143
|
|
|
21028
21144
|
|
|
@@ -21031,6 +21147,146 @@ var $909272efb41be16f$export$2e2bcd8739ae039 = $909272efb41be16f$var$GenomicInte
|
|
|
21031
21147
|
|
|
21032
21148
|
|
|
21033
21149
|
|
|
21150
|
+
/**
|
|
21151
|
+
* Edit one filter leaf in place, with a form shaped to what that leaf actually is:
|
|
21152
|
+
* a genomic interval gets the genome/chromosome/start/end fields, a `[lo TO hi]`
|
|
21153
|
+
* range gets two number boxes, anything else gets its raw value.
|
|
21154
|
+
*
|
|
21155
|
+
* Groups are not editable — their only parameter is the operator, which the menu
|
|
21156
|
+
* already exposes as "convert to".
|
|
21157
|
+
*
|
|
21158
|
+
* The plain-value case is honest but limited: many leaves carry an opaque id (a
|
|
21159
|
+
* pathway number, an ontology term, a saved-search hash) whose replacement a user
|
|
21160
|
+
* has no way to know. It is offered because a typo in a gene name or a term is
|
|
21161
|
+
* worth fixing without deleting and starting over.
|
|
21162
|
+
*/ const $91efc9c46e3775e3$var$FilterEditor = ({ node: node, grameneMaps: grameneMaps, targetTaxonId: targetTaxonId, onSave: onSave, onCancel: onCancel })=>{
|
|
21163
|
+
const kind = (0, $af4441dd29af05df$export$a7f4fa59930e5088)(node);
|
|
21164
|
+
const range = kind === 'range' ? (0, $af4441dd29af05df$export$9ee0ceaa589fc567)(node.fq_value) : null;
|
|
21165
|
+
const [lo, setLo] = (0, $gXNCa$react.useState)(range ? range.lo : '');
|
|
21166
|
+
const [hi, setHi] = (0, $gXNCa$react.useState)(range ? range.hi : '');
|
|
21167
|
+
const [value, setValue] = (0, $gXNCa$react.useState)(kind === 'value' ? String(node.fq_value ?? '') : '');
|
|
21168
|
+
if (!kind) return null;
|
|
21169
|
+
if (kind === 'interval') {
|
|
21170
|
+
const initial = (0, $af4441dd29af05df$export$67920d3e3cb3f136)(node.fq_value);
|
|
21171
|
+
return /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("div", {
|
|
21172
|
+
className: "gramene-filter-editor",
|
|
21173
|
+
children: /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)((0, $909272efb41be16f$export$4fa3dba3103266ea), {
|
|
21174
|
+
grameneMaps: grameneMaps,
|
|
21175
|
+
targetTaxonId: targetTaxonId,
|
|
21176
|
+
initial: initial,
|
|
21177
|
+
submitLabel: "Save",
|
|
21178
|
+
onCancel: onCancel,
|
|
21179
|
+
onSubmit: (iv)=>onSave((0, $af4441dd29af05df$export$634f7214da1b780a)(iv), (0, $af4441dd29af05df$export$535c09441f37845d)(iv))
|
|
21180
|
+
})
|
|
21181
|
+
});
|
|
21182
|
+
}
|
|
21183
|
+
if (kind === 'range') {
|
|
21184
|
+
const ok = lo !== '' && hi !== '';
|
|
21185
|
+
const save = ()=>{
|
|
21186
|
+
if (ok) onSave((0, $af4441dd29af05df$export$cd9b2ffd001c6d65)(lo, hi), `${lo}-${hi}`);
|
|
21187
|
+
};
|
|
21188
|
+
return /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsxs)("div", {
|
|
21189
|
+
className: "gramene-filter-editor",
|
|
21190
|
+
children: [
|
|
21191
|
+
/*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsxs)("div", {
|
|
21192
|
+
className: "gramene-interval-range",
|
|
21193
|
+
children: [
|
|
21194
|
+
/*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)((0, $gXNCa$reactbootstrap.Form).Control, {
|
|
21195
|
+
size: "sm",
|
|
21196
|
+
value: lo,
|
|
21197
|
+
onChange: (e)=>setLo(e.target.value),
|
|
21198
|
+
placeholder: "from"
|
|
21199
|
+
}),
|
|
21200
|
+
/*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("span", {
|
|
21201
|
+
className: "gramene-interval-dash",
|
|
21202
|
+
children: "\u2013"
|
|
21203
|
+
}),
|
|
21204
|
+
/*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)((0, $gXNCa$reactbootstrap.Form).Control, {
|
|
21205
|
+
size: "sm",
|
|
21206
|
+
value: hi,
|
|
21207
|
+
onChange: (e)=>setHi(e.target.value),
|
|
21208
|
+
placeholder: "to",
|
|
21209
|
+
onKeyDown: (e)=>{
|
|
21210
|
+
if (e.key === 'Enter') save();
|
|
21211
|
+
}
|
|
21212
|
+
})
|
|
21213
|
+
]
|
|
21214
|
+
}),
|
|
21215
|
+
/*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsxs)("div", {
|
|
21216
|
+
className: "gramene-interval-actions",
|
|
21217
|
+
children: [
|
|
21218
|
+
/*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)((0, $gXNCa$reactbootstrap.Button), {
|
|
21219
|
+
size: "sm",
|
|
21220
|
+
variant: "primary",
|
|
21221
|
+
className: "gramene-interval-submit",
|
|
21222
|
+
disabled: !ok,
|
|
21223
|
+
onClick: save,
|
|
21224
|
+
children: "Save"
|
|
21225
|
+
}),
|
|
21226
|
+
/*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)((0, $gXNCa$reactbootstrap.Button), {
|
|
21227
|
+
size: "sm",
|
|
21228
|
+
variant: "link",
|
|
21229
|
+
className: "gramene-interval-cancel",
|
|
21230
|
+
onClick: onCancel,
|
|
21231
|
+
children: "cancel"
|
|
21232
|
+
})
|
|
21233
|
+
]
|
|
21234
|
+
})
|
|
21235
|
+
]
|
|
21236
|
+
});
|
|
21237
|
+
}
|
|
21238
|
+
const ok = String(value).trim() !== '';
|
|
21239
|
+
// Keep the node's own label in step with its value, unless the label was
|
|
21240
|
+
// something other than the value to begin with (a suggestion's display name),
|
|
21241
|
+
// in which case leave it alone rather than overwriting it with a raw id.
|
|
21242
|
+
const save = ()=>{
|
|
21243
|
+
if (!ok) return;
|
|
21244
|
+
const v = String(value).trim();
|
|
21245
|
+
const nameFollowedValue = String(node.name ?? '') === String(node.fq_value ?? '');
|
|
21246
|
+
onSave(v, nameFollowedValue ? v : undefined);
|
|
21247
|
+
};
|
|
21248
|
+
return /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsxs)("div", {
|
|
21249
|
+
className: "gramene-filter-editor",
|
|
21250
|
+
children: [
|
|
21251
|
+
/*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)((0, $gXNCa$reactbootstrap.Form).Control, {
|
|
21252
|
+
size: "sm",
|
|
21253
|
+
value: value,
|
|
21254
|
+
onChange: (e)=>setValue(e.target.value),
|
|
21255
|
+
onKeyDown: (e)=>{
|
|
21256
|
+
if (e.key === 'Enter') save();
|
|
21257
|
+
}
|
|
21258
|
+
}),
|
|
21259
|
+
/*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsxs)("div", {
|
|
21260
|
+
className: "gramene-interval-actions",
|
|
21261
|
+
children: [
|
|
21262
|
+
/*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)((0, $gXNCa$reactbootstrap.Button), {
|
|
21263
|
+
size: "sm",
|
|
21264
|
+
variant: "primary",
|
|
21265
|
+
className: "gramene-interval-submit",
|
|
21266
|
+
disabled: !ok,
|
|
21267
|
+
onClick: save,
|
|
21268
|
+
children: "Save"
|
|
21269
|
+
}),
|
|
21270
|
+
/*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)((0, $gXNCa$reactbootstrap.Button), {
|
|
21271
|
+
size: "sm",
|
|
21272
|
+
variant: "link",
|
|
21273
|
+
className: "gramene-interval-cancel",
|
|
21274
|
+
onClick: onCancel,
|
|
21275
|
+
children: "cancel"
|
|
21276
|
+
})
|
|
21277
|
+
]
|
|
21278
|
+
})
|
|
21279
|
+
]
|
|
21280
|
+
});
|
|
21281
|
+
};
|
|
21282
|
+
var $91efc9c46e3775e3$export$2e2bcd8739ae039 = $91efc9c46e3775e3$var$FilterEditor;
|
|
21283
|
+
|
|
21284
|
+
|
|
21285
|
+
|
|
21286
|
+
|
|
21287
|
+
|
|
21288
|
+
|
|
21289
|
+
|
|
21034
21290
|
|
|
21035
21291
|
|
|
21036
21292
|
// "Save this view" UI — sits inside the Auth sidebar panel.
|
|
@@ -21475,6 +21731,7 @@ function $693dd8c7a5607c3a$var$logAction(action) {
|
|
|
21475
21731
|
});
|
|
21476
21732
|
}
|
|
21477
21733
|
const $693dd8c7a5607c3a$var$Filter = ({ node: node, moveCopyMode: moveCopyMode, showMarked: showMarked, actions: actions })=>{
|
|
21734
|
+
const [editing, setEditing] = (0, $gXNCa$react.useState)(false);
|
|
21478
21735
|
let classes = 'gramene-filter gramene-filter';
|
|
21479
21736
|
if (node.operation) classes = `${classes}-${(0, $af4441dd29af05df$export$c8b6102be216752a)(node.operation)}`;
|
|
21480
21737
|
// An expansion decorates whatever node it sits on, leaf or group — same as negate.
|
|
@@ -21534,6 +21791,14 @@ const $693dd8c7a5607c3a$var$Filter = ({ node: node, moveCopyMode: moveCopyMode,
|
|
|
21534
21791
|
]
|
|
21535
21792
|
}, key++));
|
|
21536
21793
|
});
|
|
21794
|
+
if ((0, $af4441dd29af05df$export$a7f4fa59930e5088)(node)) menuItems.push(/*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("li", {
|
|
21795
|
+
onClick: ()=>{
|
|
21796
|
+
$693dd8c7a5607c3a$var$logAction(`Edit filter`);
|
|
21797
|
+
actions.toggleMenu(node);
|
|
21798
|
+
setEditing(true);
|
|
21799
|
+
},
|
|
21800
|
+
children: "edit"
|
|
21801
|
+
}, key++));
|
|
21537
21802
|
if (node.leftIdx > 0) {
|
|
21538
21803
|
menuItems.push(/*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("li", {
|
|
21539
21804
|
onClick: ()=>{
|
|
@@ -21642,12 +21907,23 @@ const $693dd8c7a5607c3a$var$Filter = ({ node: node, moveCopyMode: moveCopyMode,
|
|
|
21642
21907
|
})
|
|
21643
21908
|
]
|
|
21644
21909
|
});
|
|
21910
|
+
const editor = editing ? /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)((0, $91efc9c46e3775e3$export$2e2bcd8739ae039), {
|
|
21911
|
+
node: node,
|
|
21912
|
+
grameneMaps: actions.grameneMaps,
|
|
21913
|
+
targetTaxonId: actions.targetTaxonId,
|
|
21914
|
+
onCancel: ()=>setEditing(false),
|
|
21915
|
+
onSave: (fq_value, name)=>{
|
|
21916
|
+
setEditing(false);
|
|
21917
|
+
actions.editNode(node, fq_value, name);
|
|
21918
|
+
}
|
|
21919
|
+
}) : null;
|
|
21645
21920
|
return /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsxs)("div", {
|
|
21646
21921
|
className: classes,
|
|
21647
21922
|
onClick: (e)=>$693dd8c7a5607c3a$var$handleClick(e, moveCopyMode, showMarked, node, actions),
|
|
21648
21923
|
children: [
|
|
21649
21924
|
content,
|
|
21650
21925
|
menu,
|
|
21926
|
+
editor,
|
|
21651
21927
|
children
|
|
21652
21928
|
]
|
|
21653
21929
|
}, node.leftIdx);
|
|
@@ -21662,7 +21938,12 @@ const $693dd8c7a5607c3a$var$FiltersCmp = (props)=>{
|
|
|
21662
21938
|
selectTarget: props.doMoveOrCopyGrameneFilter,
|
|
21663
21939
|
markTargets: props.doMarkGrameneFilterTargets,
|
|
21664
21940
|
unmarkTargets: props.doUnmarkGrameneFilterTargets,
|
|
21665
|
-
toggleMenu: props.doToggleGrameneFilterMenu
|
|
21941
|
+
toggleMenu: props.doToggleGrameneFilterMenu,
|
|
21942
|
+
editNode: props.doEditGrameneFilter,
|
|
21943
|
+
// Carried alongside the actions so every nested Filter can reach them without
|
|
21944
|
+
// threading two more props through the recursion.
|
|
21945
|
+
grameneMaps: props.grameneMaps,
|
|
21946
|
+
targetTaxonId: props.targetTaxonId
|
|
21666
21947
|
};
|
|
21667
21948
|
const intervalForm = /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)((0, $909272efb41be16f$export$2e2bcd8739ae039), {
|
|
21668
21949
|
grameneMaps: props.grameneMaps,
|
|
@@ -21710,7 +21991,7 @@ const $693dd8c7a5607c3a$var$FiltersCmp = (props)=>{
|
|
|
21710
21991
|
})
|
|
21711
21992
|
});
|
|
21712
21993
|
};
|
|
21713
|
-
const $693dd8c7a5607c3a$export$92a576f896a9bf72 = (0, $gXNCa$reduxbundlerreact.connect)('selectGrameneFilters', 'selectConfiguration', 'doNegateGrameneFilter', 'doDeleteGrameneFilter', 'doChangeGrameneFilterOperation', 'doExpandGrameneFilter', 'doRemoveGrameneExpansion', 'doMoveOrCopyGrameneFilter', 'doMarkGrameneFilterTargets', 'doUnmarkGrameneFilterTargets', 'doToggleGrameneFilterMenu', 'selectGrameneMaps', 'selectTargetTaxonId', 'doAddGrameneInterval', 'doClearGrameneFilters', $693dd8c7a5607c3a$var$FiltersCmp);
|
|
21994
|
+
const $693dd8c7a5607c3a$export$92a576f896a9bf72 = (0, $gXNCa$reduxbundlerreact.connect)('selectGrameneFilters', 'selectConfiguration', 'doNegateGrameneFilter', 'doDeleteGrameneFilter', 'doChangeGrameneFilterOperation', 'doExpandGrameneFilter', 'doRemoveGrameneExpansion', 'doMoveOrCopyGrameneFilter', 'doMarkGrameneFilterTargets', 'doUnmarkGrameneFilterTargets', 'doToggleGrameneFilterMenu', 'selectGrameneMaps', 'selectTargetTaxonId', 'doAddGrameneInterval', 'doEditGrameneFilter', 'doClearGrameneFilters', $693dd8c7a5607c3a$var$FiltersCmp);
|
|
21714
21995
|
const $693dd8c7a5607c3a$var$ResultsCmp = (props)=>{
|
|
21715
21996
|
let activeViews = props.grameneViews.options;
|
|
21716
21997
|
return props.grameneFilters.rightIdx > 0 ? /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("div", {
|