Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 14 additions & 9 deletions assets/live/finding.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,12 @@
root.setAttribute('data-pgp-status', 'ready');
return;
}
// known, not family: the click that opens this finding draws again with family as it came, UNKNOWN kept.
var unknown = family === UNKNOWN;
if (unknown) { family = null; }
var me = family && (family.state.members || []).filter(function (m) { return m.sample === r.sample; })[0];
var known = unknown ? null : family;
var me = known && (known.state.members || []).filter(function (m) { return m.sample === r.sample; })[0];
// A family that does not list this person cannot say they are not a child: closed as well.
var child = unknown || (!!family && !me) || !!(me && (me.father || me.mother));
var child = unknown || (!!known && !me) || !!(me && (me.father || me.mother));
// Closed: no title, gene or variant anywhere on the page (its title, crumb, cover, rail) until opened.
var closed = child && f.level === 'act' && !draw.open;
var title = closed ? 'A result to act on' : f.title;
Expand All @@ -97,7 +98,7 @@
add(rail, el('div', { 'class': 'group' }, 'This finding'));
var parts = [['what', 'What it is'], ['plan-sec', 'What to do'], ['evidence', 'Evidence']];
if (f.viewer) { parts.push(['reads', 'The reads']); }
if (family) { parts.push(['family', 'In the family']); }
if (known) { parts.push(['family', 'In the family']); }
parts.push(['related', 'Related results'], ['sources', 'Caveat and sources']);
var tol = el('ol', {});
parts.forEach(function (p, i) {
Expand Down Expand Up @@ -158,7 +159,7 @@
add(box, ol);
add(m1, box);
var a1 = el('aside', {});
if (f.level === 'carrier' && family) { add(a1, note('Family', add(el('span', {}), 'A carrier is not affected. ', el('a', { href: abs(familyUrl) }, 'The couple screen on the family page →')))); }
if (f.level === 'carrier' && known) { add(a1, note('Family', add(el('span', {}), 'A carrier is not affected. ', el('a', { href: abs(familyUrl) }, 'The couple screen on the family page →')))); }
add(row1, m1, a1);
add(col, row1);
// The evidence.
Expand Down Expand Up @@ -189,14 +190,14 @@
// Related findings and the family.
var rel = (f.related || []).map(function (id) { return (r.findings || []).filter(function (x) { return x.id === id; })[0]; })
.filter(function (x) { return x && !(child && x.level === 'act'); });
if (family) {
if (known) {
var sf = el('section', { 'class': 'sec', id: 'family' });
add(sf, add(el('div', { 'class': 'sechead' }), el('span', { 'class': 'secnum' }, ROMAN[parts.length - 3]), el('h2', { 'class': 'h2' }, 'In the family')));
var fam = el('p', { 'class': 'soft' });
add(fam, 'Who else in the family has a genome here: ');
(family.state.members || []).filter(function (m) { return m.sample !== r.sample; }).forEach(function (m, i) {
(known.state.members || []).filter(function (m) { return m.sample !== r.sample; }).forEach(function (m, i) {
if (i) { add(fam, ', '); }
var u = family.runs && family.runs[m.sample] && family.runs[m.sample].url;
var u = known.runs && known.runs[m.sample] && known.runs[m.sample].url;
add(fam, u ? el('a', { href: abs(u) }, m.sample) : el('span', {}, m.sample + ' (no genome)'));
});
add(fam, '. ', el('a', { href: abs(familyUrl) }, 'The family report →'));
Expand Down Expand Up @@ -230,7 +231,11 @@
var familyUrl = null;
var UNKNOWN = { unknown: true };
function familyOf(st) {
var fam = st && st.plugins && st.plugins.family;
// No state (state.json or frames.json refused, missing or not JSON), a state with no plugins, or a family
// plugin that found a family report it could not read: the roles are unknown, never a standalone adult.
if (!st || !st.plugins) { return Promise.resolve(UNKNOWN); }
var fam = st.plugins.family;
if (fam && fam.unknown) { return Promise.resolve(UNKNOWN); }
var f = fam && fam.kind === 'member' && (fam.families || [])[0];
if (!f) { return Promise.resolve(null); }
familyUrl = f.url;
Expand Down
23 changes: 20 additions & 3 deletions assets/live/person.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,18 @@
var f = fam && fam.kind === 'member' && (fam.families || [])[0];
return f ? f : null;
}
// The family plugin cannot say: a state with no plugins (unavailable or cut short), or a family plugin
// that found a family report it could not read (plugins.family.unknown). Not a standalone adult then.
function familyUnknown() {
var fam = state && state.plugins ? state.plugins.family : undefined;
return !state || !state.plugins || !!(fam && fam.unknown);
}
function loadFamily() {
var f = familyUrl();
var key = f ? f.url : null;
var key = f ? f.url : (familyUnknown() ? '?' : null);
if (key === familyFor) { return; }
familyFor = key;
if (!f) { family = null; familyStatus = 'none'; return; }
if (!f) { family = null; familyStatus = key ? 'failed' : 'none'; return; }
familyStatus = 'pending';
U.getJSON(f.url + 'family.json').then(function (d) {
if (familyFor !== key) { return; }
Expand Down Expand Up @@ -316,6 +322,17 @@
// The findings of a card that a child's page keeps closed: while one is closed the card's own rows,
// numbers and drawing stay closed too, or its table would name the gene and variant under the veil.
function veiledOf(c) { return (c.findings || []).map(findingById).filter(function (f) { return f && veiled(f); }); }
// The search box (plugins/search.js) asks the same question for each hit, by the summary key and the anchor
// of the section it comes from: a hit from a card this page keeps closed is left out. A closed page with
// no results.json yet cannot tell which cards those are, so it leaves every hit out until it can.
// Asked with no key, it answers whether this page keeps anything closed at all.
window.PGP.searchHidden = function (key, anchor) {
if (!closedPage()) { return false; }
if (!results || key === null) { return true; }
return cards().some(function (c) {
return (c.id === anchor || (c.keys || []).indexOf(key) >= 0) && veiledOf(c).length > 0;
});
};

function card(c) {
var g = gate(c);
Expand Down Expand Up @@ -1051,7 +1068,7 @@
function keepFolds() { foldKeys().forEach(function (x) { foldState[x[0]] = x[1].open; }); }
function restoreFolds() { foldKeys().forEach(function (x) { if (foldState[x[0]]) { x[1].open = true; } }); }
function redraw(force) {
var k = JSON.stringify([doneSet(), state && state.run && state.run.state, !!results, !!family, Object.keys(shown),
var k = JSON.stringify([doneSet(), state && state.run && state.run.state, !!results, !!family, familyStatus, Object.keys(shown),
state && state.plugins && state.plugins.recheck && state.plugins.recheck.mtime,
// Every step's state: one can move from waiting to not finished with the done set unchanged.
((state && state.steps) || []).map(function (s) { return s.step + ':' + s.state; })]);
Expand Down
4 changes: 4 additions & 0 deletions assets/live/plugins/family.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@

function member(f) {
box.appendChild(el('h2', {}, 'Family'));
if (f.unknown) {
box.appendChild(para('A family report could not be read, so this page cannot tell whether this person is a child '
+ 'of it: results to act on stay closed until opened.', 'muted'));
}
f.families.forEach(function (x) {
var p = el('p', {}, 'In the family ');
p.appendChild(link(x.url, x.name));
Expand Down
14 changes: 14 additions & 0 deletions assets/live/plugins/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,24 @@
return li;
}

// A hit from a section the page keeps closed (a result to act on about a child, person.js's
// PGP.searchHidden) is left out, and so is a suggested term that only such sections name: the search
// must not name what the page veils. The page says so whether or not anything was left out.
function hidden(it) { return !!(root.PGP.searchHidden && root.PGP.searchHidden(it.section, it.anchor)); }
function closedNote() {
return root.PGP.searchHidden && root.PGP.searchHidden(null, null)
? el('p', { 'class': 'muted search-closed' }, 'Results this page keeps closed are left out of the search until they are opened.')
: null;
}

function show() {
if (!out) { return; }
out.textContent = '';
var q = input.value;
if (!index || !q.trim()) { document.documentElement.removeAttribute('data-pgp-search'); return; }
var r = match(index, q);
r.items = r.items.filter(function (it) { return !hidden(it); });
r.suggestions = r.suggestions.filter(function (t) { return (index.terms[t] || []).some(function (it) { return !hidden(it); }); });
document.documentElement.setAttribute('data-pgp-search', String(r.items.length));
if (r.kind === 'site') {
out.appendChild(el('p', {}, 'The search finds gene symbols and rsIDs. A position is a question about the genotype: '
Expand Down Expand Up @@ -119,6 +131,8 @@
});
out.appendChild(p);
}
var note = closedNote();
if (note) { out.appendChild(note); }
}

function onState(state) {
Expand Down
Loading
Loading